我正在为我的 XNA 游戏编写一个对话模块作为学习项目。我一直在使用已接受的答案here作为指导。
每个ILink
包含 ICollection<ICondition>
,用于确定是否满足所有条件以使特定对话框链接显示为选项:
public interface INode
{
int ID { get; set; }
ICollection<ILink> Links { get; set; }
}
public interface ILink
{
INode Target { get; set; }
IScript Script { get; set; }
ICollection<string> Text { get; set; }
ICollection<ICondition> Conditions { get; set; }
}
public interface IScript { void Execute(); }
public interface ICondition { bool Evaluate(); }
基于此,显然我想要进行的每种类型的比较都必须是它自己的类:
public class EntityHasItem : ICondition
{
public IEntity Entity { get; set; }
public IItem Item { get; set; }
public bool Evaluate() { return Entity.Inventory.Contains(Item); }
}
或者
public class QuestHasFlag : ICondition
{
public IQuest Quest { get; set; }
public IFlag Flag { get; set; }
public bool Evaluate() { return Quest.Flags.Contains(Flag); }
}
如何检查 INode.Conditions
的每个元素的类型是?例如,我可能会担任编辑,或提供反馈。由于泛型集合,它将始终以 ICondition(这是最常见的派生类型)返回,但它只公开 Evaluate(),这在这里没有太大帮助。
我的第一个想法是使用反射来获取派生自 ICondition
的类型列表。 ,然后将该列表与集合中的每个元素进行比较,但这似乎有点矫枉过正。有更好的办法吗?
最佳答案
您不需要这样做,只有非常小心并有充分理由才能违反接口(interface)(通过向下转型)。
您提到了想要执行此操作的两个用例:查看和编辑。
对于查看,解决方案很简单。重写 .ToString()
来获取您需要的信息,或者如果您需要“漂亮”的输出,请创建一个接口(interface)函数 DrawInfo
来为您执行此显示(传递参数根据需要,例如要绘制的屏幕区域)。
为了进行编辑,您需要一个 DrawDialog
函数。与 DrawInfo
函数一样,它可以采用“区域”参数。假设此对话框可以管理其自己的 UI 控件(按钮等),那么您就完成了。顺便说一句,这类似于让一个类在 WPF/Winforms 中返回一个 UserControl
来执行相同的操作。
在接口(interface)中拥有这些可以确保每个派生类都拥有它(通过反射调用方法既不安全也不有趣!)并且您无需担心运行时的类型,多态性会为您处理一切。
关于c# - 检查泛型集合中更多派生类型的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23483898/