简体   繁体   English

System.MissingMethodException:无法创建抽象类

[英]System.MissingMethodException: Cannot create an abstract class

ExtendedCommandManager.cs扩展命令管理器.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; 

type inherited ICcommand But why is there an error?类型继承ICcommand 但是为什么会出现错误呢?

Error错误

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

But why is there an error?但是为什么会出现错误呢?

Because you're trying to create an instance of an abstract class (rather than a concrete class derived from that abstract class).因为您正在尝试创建抽象类的实例(而不是从该抽象类派生的具体类)。 You can't do that with reflection, just like you can't do it with regular code.你不能用反射来做到这一点,就像你不能用常规代码那样。 If you were to try writing code of var command = new FooCommand();如果您尝试编写var command = new FooCommand(); (where FooComand is the type that it's failing on) that code would fail to compile. (其中FooComand是它失败的类型)该代码将无法编译。

Your code for checking which types to instantiate should include !p.IsAbstract to filter out abstract classes that implement ICommand .检查要实例化哪些类型的代码应包含!p.IsAbstract以过滤掉实现ICommand抽象类。

The error tells you exactly what is wrong.错误告诉您究竟出了什么问题。 You can't create an instance of an abstract class.您不能创建抽象类的实例。

You need to filter your types so that they don't include abstract types.您需要过滤您的类型,以便它们不包含抽象类型。 like this:像这样:

var types = assembly.SelectMany(s => s.GetTypes()).Where(p => !p.IsAbstract && typeof(ICommand).IsAssignableFrom(p));

You cannot create a instance of both abstract class and interface.您不能同时创建抽象类和接口的实例。 Because it does not contain complete implementation.因为它不包含完整的实现。 So, first implement it.所以,首先要实现它。

See this Microsoft Doc For Reference请参阅此Microsoft Doc 以供参考

Like most abstract class implementation in most languages, you can't create an object of that specifically.与大多数语言中的大多数抽象类实现一样,您无法专门创建该对象。 It's used as a building block, typically for common code shared amongst other classes.它用作构建块,通常用于在其他类之间共享的公共代码。

The Execption is correct.执行是正确的。 When you loaded your classes / objects by reflection using the interface as it's identifier, one of the classes that implemented that interface is abstract and can't be instanciated with Activator.CreateInstance , but your code doesn't know that until runtime as it can do type checking on stuff created dynamically at runtime.当您使用接口作为标识符通过反射加载类/对象时,实现该接口的类之一是抽象的,无法使用Activator.CreateInstance实例化,但您的代码直到运行时才知道这一点,因为它可以对运行时动态创建的内容进行类型检查。

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

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