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