Рассмотрим этот пример из вашего вопроса ...
public class SomeClass<T>
{
public T DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (T)obj;
}
}
... и тот случай, когда у вас есть
public abstract class AbstractStuff : SomeClass<AbstractStuff> { }
public class DoStuff : AbstractStuff { }
Если вы замените параметр типа аргументом, вы получите это для DoSomething()
:
public AbstractStuff DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (AbstractStuff)obj;
}
Теперь давайте немного изменим рефакторинг для простоты «отладки» и добавим номера строк:
1 public AbstractStuff DoSomething()
2 {
3 var type = this.GetType();
4 var obj = Activator.CreateInstance(type);
5 // Do Things
6 return (AbstractStuff)obj;
7 }
Если вы вызовете этот метод для экземпляра DoStuff
и прервитесь на строке 4, вы увидите, что type
- это DoStuff
; если вы прервете строку 6, вы увидите, что тип времени выполнения obj
также равен DoStuff
. Конечно, приведение этого объекта к AbstractStuff
будет успешным (и приведение даже не требуется), потому что всегда есть неявное преобразование ссылки из любого ссылочного типа в его базовый тип.
Теперь давайте рассмотрим сообщение об ошибке, о котором вы сообщаете: «невозможно создать экземпляр абстрактного класса». Что это говорит нам? Он говорит, что по какой-то причине, когда вы вызываете Activator.CreateInstance, вы передаете ссылку на тип AbstractStuff
.
Похоже, пример кода, который вы нам дали, не точный. GetType()
никогда не сможет вернуть абстрактный тип, , потому что тип времени выполнения объекта никогда не может быть абстрактным типом. Другими словами, невозможно иметь экземпляр абстрактного типа.
На самом деле, описанное вами поведение будет ожидаемым, если у вас будет строка ...
var obj = Activator.CreateInstance(typeof(T));
... а не ...
var obj = Activator.CreateInstance(this.GetType());
Вы уверены, что это не так?