System.MissingMethodException:无法创建抽象类



ExtendedCommandManager.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:CLangDicordProjectDiscordBASECommandControllersExtendedCommandManager.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文档以供参考

就像大多数语言中的大多数抽象类实现一样,您不能专门创建这样的对象。它被用作构建块,通常用于其他类之间共享的公共代码。

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

最新更新