System.MissingMethodException: невозможно создать абстрактный класс - PullRequest
0 голосов
/ 11 марта 2020

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:\CLang\DicordProject\Discord\BASE\CommandControllers\ExtendedCommandManager.cs:line 16

Ответы [ 4 ]

6 голосов
/ 11 марта 2020

Но почему возникает ошибка?

Поскольку вы пытаетесь создать экземпляр абстрактного класса (а не конкретный класс, производный от этого абстрактного класса). Вы не можете сделать это с помощью отражения, как вы не можете сделать это с помощью обычного кода. Если бы вы попытались написать код var command = new FooCommand(); (где FooComand - это тип, на котором происходит сбой), этот код не скомпилировался бы.

Ваш код для проверки того, какие типы создавать, должен включать !p.IsAbstract отфильтровать абстрактные классы, которые реализуют ICommand.

1 голос
/ 11 марта 2020

Ошибка говорит вам, что именно не так. Вы не можете создать экземпляр абстрактного класса.

Вам необходимо отфильтровать ваши типы, чтобы они не включали абстрактные типы. как это:

var types = assembly.SelectMany(s => s.GetTypes()).Where(p => !p.IsAbstract && typeof(ICommand).IsAssignableFrom(p));
0 голосов
/ 11 марта 2020

См. Это Microsoft Do c Для справки

Как и в большинстве реализаций абстрактного класса в большинстве языков, вы не можете создать объект этого конкретного. Он используется в качестве строительного блока, как правило, для общего кода, совместно используемого другими классами.

Исключительно правильное исполнение. Когда вы загрузили ваши классы / объекты с помощью отражения, используя интерфейс в качестве его идентификатора, один из классов, который реализовал этот интерфейс, является абстрактным и не может быть создан с помощью Activator.CreateInstance, но ваш код не знает этого до времени выполнения, так как он может выполнять проверку типов для материалов, динамически создаваемых во время выполнения.

0 голосов
/ 11 марта 2020

Вы не можете создать экземпляр как абстрактного класса, так и интерфейса. Потому что он не содержит полной реализации. Итак, сначала реализуем это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...