繁体   English   中英

System.MissingMethodException:无法创建抽象类

[英]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));

您不能同时创建抽象类和接口的实例。 因为它不包含完整的实现。 所以,首先要实现它。

请参阅此Microsoft Doc 以供参考

与大多数语言中的大多数抽象类实现一样,您无法专门创建该对象。 它用作构建块,通常用于在其他类之间共享的公共代码。

执行是正确的。 当您使用接口作为标识符通过反射加载类/对象时,实现该接口的类之一是抽象的,无法使用Activator.CreateInstance实例化,但您的代码直到运行时才知道这一点,因为它可以对运行时动态创建的内容进行类型检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM