[英]System.MissingMethodException: Cannot create an instance of an interface
[英]System.MissingMethodException: Cannot create an abstract class
扩展命令管理器.cs
var assembly = AppDomain.CurrentDomain.GetAssemblies();
var types = assembly.SelectMany(s => s.GetTypes()).Where(p => typeof(ICommand).IsAssignableFrom(p));
foreach (var type in types)
{
source.Commands.Add((ICommand) Activator.CreateInstance(type));
}
return source;
类型继承ICcommand 但是为什么会出现错误呢?
错误
Unhandled exception. System.MissingMethodException: Cannot create an abstract class.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor)
at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
at System.Activator.CreateInstance(Type type)
at BASE.CommandControllers.ExtendedCommandManager.Load[T](T source) in D:\CLang\DicordProject\Discord\BASE\CommandControllers\ExtendedCommandManager.cs:line 16
但是为什么会出现错误呢?
因为您正在尝试创建抽象类的实例(而不是从该抽象类派生的具体类)。 你不能用反射来做到这一点,就像你不能用常规代码那样。 如果您尝试编写var command = new FooCommand();
(其中FooComand
是它失败的类型)该代码将无法编译。
检查要实例化哪些类型的代码应包含!p.IsAbstract
以过滤掉实现ICommand
抽象类。
错误告诉您究竟出了什么问题。 您不能创建抽象类的实例。
您需要过滤您的类型,以便它们不包含抽象类型。 像这样:
var types = assembly.SelectMany(s => s.GetTypes()).Where(p => !p.IsAbstract && typeof(ICommand).IsAssignableFrom(p));
您不能同时创建抽象类和接口的实例。 因为它不包含完整的实现。 所以,首先要实现它。
与大多数语言中的大多数抽象类实现一样,您无法专门创建该对象。 它用作构建块,通常用于在其他类之间共享的公共代码。
执行是正确的。 当您使用接口作为标识符通过反射加载类/对象时,实现该接口的类之一是抽象的,无法使用Activator.CreateInstance
实例化,但您的代码直到运行时才知道这一点,因为它可以对运行时动态创建的内容进行类型检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.