У меня есть класс в C# с шаблоном и статическим методом, подобным
class BClass<T>
{
public static BClass<T> Create()
{
return new BClass<T>();
}
}
От этого я получаю класс и указываю шаблонный параметр к базовому классу
class DClass : BClass<int> { }
Проблема происходит, когда я пытаюсь использовать статический метод создать экземпляр D
class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create();
}
}
Дает ошибку компилятора, "Не может неявно преобразовать тип 'Тест. BClass <интервал>' для 'Тестирования. DClass'".
Добавление ниже броска приводит к исключению кастинга времени выполнения.
DClass d = (DClass)DClass.Create();
Там какой-либо succint путь состоит в том, чтобы позволить статическому методу создать экземпляры производного класса? Идеально я хотел бы эквивалент определения типа C++, и я не хочу ниже синтаксиса (который действительно работает).
BClass<int> d = DClass.Create();
Да, это возможно, имея ссылку типа на сам тип. Обратите внимание, что в мире .NET мы говорим о дженериках, а не о шаблонах, которые имеют важные различия в работе.
class BClass<T, TSelf> where TSelf: BClass<T, TSelf>, new() {
public static TSelf Create() {
return new TSelf();
}
}
class DClass: BClass<int, DClass> {}
class Program {
static void Main(string[] args) {
DClass d = DClass.Create();
}
}
Кажется, что то, что вы хотите, чтобы DClass
был псевдонимом для BClass
. Но это не то, что у вас здесь. У вас есть то, что DClass
происходит от BClass
. Таким образом, вызов DClass.Create ();
создает BClass
, который не DClass
(это наоборот ).
Это могло бы прояснить ситуацию. Предположим, у вас есть такая иерархия:
class Rectangle {
static Rectangle Create() {
return new Rectangle();
}
}
class Square : Rectangle { }
// code elsewhere
var shape = Square.Create(); // you might want this to return a square,
// but it's just going to return a rectangle
Один из вариантов получить что-то похожее на функциональность, которая вам нужна, может заключаться в определении вашего метода Create
следующим образом:
static TClass Create<TClass>() where TClass : BClass<T>, new() {
return new TClass();
}
// code elsewhere
var shape = DClass.Create<DClass>();
Это немного беспорядочно (а также требует, чтобы вы напишите конструктор без параметров для DClass
). Если вы твердо настроены использовать метод Create
для создания экземпляров ваших объектов, подумайте о написании для него фабричного класса.
class BClass<T>
{
public static T1 Create<T1, T2>() where T1 : BClass<T2>, new()
{
return new T1();
}
}
class DClass : BClass<int> { }
class Program
{
static void Main(string[] args)
{
DClass d = DClass.Create<DClass, int>();
}
}