【发布时间】:2019-06-25 06:27:58
【问题描述】:
编辑:此代码统一作为自定义检查器代码运行,但我不确定它是否相关,如果是,我将发布整个课程。
我想获取所有实现特定接口的类,并显示一个选项列表,以便用户选择如何实现该接口。
这是一个描述角色行为的简单界面。
我曾尝试将接口替换为抽象类,但无济于事...
在调试中我可以看到,返回的值为空。
我在网上找到的所有内容都说该类型可能不存在,但在我的情况下这是不可能的,因为我使用反射获得了我的类型。
ICombatBehaviour combat;
private string[] FindAllCombatOptions(out List<Type> existingTypes)
{
List<string> options = new List<string>();
existingTypes = new List<Type>();
var combatBehaviours = Assembly.GetAssembly(typeof(ICombatBehaviour)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && typeof(ICombatBehaviour).IsAssignableFrom(myType));
foreach (var behaviour in combatBehaviours)
{
existingTypes.Add(behaviour);
options.Add(behaviour.Name);
}
return options.ToArray();
}
private void UpdateType(List<Type> types)
{
combat = Activator.CreateInstance(types[index]) as ICombatBehaviour;
}
UpdateType() 方法,获取FindAllCombatOptions() 方法找到的所有类型,并获取所选索引中的类型。类型正确,但combat 变量仍然为空...
ICombatBehavior:
public interface ICombatBehaviour
{
}
实现类:
public class FightBehaviour : ICombatBehaviour
{
}
public class EscapeBehaviour : ICombatBehaviour
{
}
这是调用函数:
public override void SelectType()
{
List<Type> types;
string[] options = FindAllCombatOptions(out types);
index = AskUserForAType(options); // Currently returns only zero
UpdateType(types);
}
【问题讨论】:
-
您发布的代码似乎运行良好,如 here 所示。鉴于此,如果您共享更多代码可能会有所帮助,例如定义这些成员的整个类、它们的使用方式以及实现
ICombatBehaviour的类型示例 -
您确定该索引上的类型实现了 ICombatBehaviour?
-
@OndřejKubíček 我敢肯定,因为如您所见,FindAllCombatOptions() 方法只找到实现该接口的类
-
您应该将
Activator.CreateInstance(…) as ICombatBehaviour更改为(ICombatBehaviour)Activator.CreateInstance(…),因为您希望此时所有类型都派生自ICombatBehaviour。如果有一个不是从它派生的类型,它会抛出一个异常并告诉你出了什么问题,而不是默默地以 null 失败,你不知道为什么会像现在这样。 -
不客气。您可以添加答案并接受它,这样有相同问题的新手可以轻松找到解决方案,而无需阅读所有 cmets。 :-D
标签: c# reflection interface null createinstance