Подтвердить что ты не робот

В С# 4.0 можно ли получить класс из параметра общего типа?

Я пытался это, но я не могу понять это. Я хочу сделать это...

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 есть много другой логики, не связанной с вопросом, поэтому он был опущен, чтобы сосредоточиться на данном вопросе.

4b9b3361

Ответ 1

Нет, это невозможно. Например, возьмите тип, объявленный sealed. Вы не можете наследовать от этого класса, и нет ограничений для ограничения непечатаемых типов, ergo, пытающихся наследовать его с помощью общего параметра, невозможно.

Ответ 2

Общие типы в С# не являются шаблонами С++; помните, что общий тип должен работать для всех возможных аргументов типа. Шаблон должен работать только для конструкций, которые вы на самом деле делаете.

Этот вопрос является дубликатом; см. мой ответ на

Почему генераторы С# не могут быть получены из одного из параметров типового типа, как они могут, в шаблонах С++?

за больше мыслей об этом. В основном, короткий ответ заключается в том, что значительные затраты не перевешивают небольшие преимущества этой функции. Если вам не нравится этот ответ, см. Мой второй ответ:

Почему генераторы С# не могут быть получены из одного из параметров типового типа, как они могут, в шаблонах С++?

И если вам не нравится этот ответ, обратитесь к следующему вопросу:

Каковы веские причины пожелать, чтобы генерики .NET могли наследовать один из типичных типов параметров?

Ответ 3

Каждый тип имеет ровно один действительный дискретный родительский класс, даже если задействованы дженерики. Даже при работе с открытым общим типом (например, typeof(List<>)) вы все равно можете найти родительский класс.

Если вам было разрешено, это было бы неверно, typeof(SingletonType<,> не имел бы родительский тип, и это не разрешено.

Ответ 4

Нет, это невозможно, потому что, допустим, у вас есть этот класс:

class bar {
  int example = 0;
}

Теперь вот наш класс параметров типа:

class foo<T> : T {
  int example = 5;
}

Если бы мы создали переменную типа foo<bar> example мог бы быть перепутан.