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

时间:2014-05-06 00:07:14

标签: 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派生的类型列表,然后将该列表与集合中的每个元素进行比较,但这看起来有点过分。还有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

你不应该这样做,违反界面(通过转发)应该只是非常谨慎和充分理由。

您提到了两个用户想要执行此操作,查看和编辑的用例。

要查看,解决方案很简单。要么覆盖.ToString()以获取所需信息,要么需要“漂亮”输出,创建一个接口函数DrawInfo来为您执行此显示(根据需要传递参数,如屏幕区域)吸引到。)

要进行编辑,您需要DrawDialog功能。与DrawInfo函数一样,这可以采用“area”参数。假设这个对话框可以管理自己的UI控件(按钮等),那么你就完成了。顺便说一句,这类似于让一个类在WPF / Winforms中返回UserControl来做同样的事情。

在接口中使用这些确保每个派生类都有它(通过反射调用方法不安全或有趣!)并且您不需要担心运行时的类型,多态性会为您处理所有事情。

答案 1 :(得分:1)

您可以在任何.NET对象上调用GetType()方法。这将返回对象的实际类型(EntityHasItem,QuestHasFlag等)。

http://msdn.microsoft.com/en-us/library/system.object.gettype.aspx

例如:

foreach(var condition in type.Conditions)
{
   Debug.WriteLine(condition.GetType().FullName);
}