c# - 检查泛型集合中更多派生类型的正确方法是什么?

标签 c# generics types casting

我正在为我的 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/

相关文章:

c - 如何在C语言中打印一个double类型的数字,最多保留一位小数?

c# - Authorize 和 AllowAnonymous 元数据在应用于 Controller 时会给出不同的行为

c# - 使用 C# 泛型从方法创建泛型对象(不是 "new")

typescript - TypeScript 中的 Record 中只有多个可能键中的一个键

java - 如何在实例化之前参数化泛型类?

c# - DataContractSerializer 和 Dictionary<string,object> 读取时失败

haskell - 输入没有意义的签名

c# - 将 QueryString 值分配为隐藏字段值

c# - WAS回收应用程序池后,使用Unity解析实例会失败

c# - 什么时候需要在 C# 中使用 stackalloc 关键字?