Ответ 1
Нет, это невозможно. Например, возьмите тип, объявленный sealed
. Вы не можете наследовать от этого класса, и нет ограничений для ограничения непечатаемых типов, ergo, пытающихся наследовать его с помощью общего параметра, невозможно.
Я пытался это, но я не могу понять это. Я хочу сделать это...
public abstract class SingletonType<TSingleton, TBaseClass> : TBaseClass
where TSingleton : TBaseClass, new()
where TBaseClass : class
{
static TSingleton _singleton;
public static TSingleton Singleton
=> _singleton ?? (_singleton = new TSingleton());
}
План состоял в том, чтобы использовать его так, чтобы он как бы "оборачивал" шаблон синглтона вокруг базового класса...
public class SingletonFoo : SingletonType<SingletonFoo, Foo> {
}
Тем не менее, я продолжаю получать это
Не может быть получен из TBaseClass, потому что это параметр типа
Хм... Я думал, что типы были именно то, что вы делаете из!
Так чего мне не хватает?
Примечание: это, конечно, тривиальный пример, поскольку он не добавляет ничего полезного, но предположим, что в SingletonType
есть много другой логики, не связанной с вопросом, поэтому он был опущен, чтобы сосредоточиться на данном вопросе.
Нет, это невозможно. Например, возьмите тип, объявленный sealed
. Вы не можете наследовать от этого класса, и нет ограничений для ограничения непечатаемых типов, ergo, пытающихся наследовать его с помощью общего параметра, невозможно.
Общие типы в С# не являются шаблонами С++; помните, что общий тип должен работать для всех возможных аргументов типа. Шаблон должен работать только для конструкций, которые вы на самом деле делаете.
Этот вопрос является дубликатом; см. мой ответ на
за больше мыслей об этом. В основном, короткий ответ заключается в том, что значительные затраты не перевешивают небольшие преимущества этой функции. Если вам не нравится этот ответ, см. Мой второй ответ:
И если вам не нравится этот ответ, обратитесь к следующему вопросу:
Каждый тип имеет ровно один действительный дискретный родительский класс, даже если задействованы дженерики. Даже при работе с открытым общим типом (например, typeof(List<>)
) вы все равно можете найти родительский класс.
Если вам было разрешено, это было бы неверно, typeof(SingletonType<,>
не имел бы родительский тип, и это не разрешено.
Нет, это невозможно, потому что, допустим, у вас есть этот класс:
class bar {
int example = 0;
}
Теперь вот наш класс параметров типа:
class foo<T> : T {
int example = 5;
}
Если бы мы создали переменную типа foo<bar>
example
мог бы быть перепутан.