Можете ли вы создать подкласс обобщенного класса с определенным типизированным классом?

У меня есть универсальный класс с подклассом, который обеспечивает определенные типы.

public abstract class GenericBase<T>
    where T:Interface1
{
}

Я делю на подклассы дженерики с конкретными реализациями:

public class Customer:
    GenericBase<Type1>

(Type1 инвентарь Interface1).

У меня есть другой абстрактный базовый класс, который имеет ссылку на это:

protected GenericBase<Interface1> genericInstance;

Наконец, когда я пытаюсь присвоить genericInstance экземпляру базового класса, он выдает ошибку компилятора, говоря, что он "не может неявно преобразовать Customer в GenericBase".

base.genericInstance = new Customer(); //Compiler error

Я не понимаю, почему я получил бы эту ошибку, если Customer это подтип GenericBase<Type1>, а также Type1 инвентарь Interface1, не Customer эффективно тип GenericBase<Interface1>, если это подкласс GenericBase<Type1>?

Я предполагаю, что я неправильно понимаю кое-что о дженериках здесь; Есть ли способ разрешить такое поведение?

2 ответа

Решение

В C# ковариация (назначение производного типа базовому типу) не может применяться к универсальным классам. В результате вам потребуется применить интерфейс, специально помеченный как ковариантный, с использованием модификатора параметра out на новом IGenericBase интерфейс.

protected IGenericBase<Interface1> genericInstance = new Customer();

public interface IGenericBase<out T> {}

public abstract class GenericBase<T> : IGenericBase<T>
    where T:Interface1 {}

public interface Interface1 {}

public class Type1 : Interface1 {}

public class Customer: GenericBase<Type1> {}

В C# нет ковариации обобщенных классов, что означает, что вы не можете присвоить значение с аргументом более производного типа переменной с аргументом менее производного типа.

Это будет работать с интерфейсами, однако, при условии выполнения некоторых условий, а именно, если тип параметра используется только в ковариантных позициях, то есть как возвращаемый тип методов и свойств.

Обратитесь к этой и другим частям документации для получения дополнительной информации.

Другие вопросы по тегам