У меня есть следующее определение класса:
public abstract class BaseExample<T> where T : BaseExample<T>
{
public abstract T Clone(T original);
}
и его наследства
public class Example01 : BaseExample<Example01>
{
public override Example01 Clone(Example01 original)
{
return this; // not the actual implementation
}
}
public class Example02 : BaseExample<Example02>
{
public override Example02 Clone(Example02 original)
{
return this; // not the actual implementation
}
}
Как объявить переменную с типом или базовым классом? Поскольку следующее выражение не компилируется:
private BaseExample<T> declarationA;
private BaseExample<T> declarationA;
private BaseExample declarationB;
Он не будет работать так же, как все, что вы назначаете родовому типу T
никогда не может быть BaseExample<T>
.
BaseExample<int> declarationA;
в случае, если выше int
не может быть BaseExample<int>
(int
! = BaseExample<int>
)
Мне нужно иметь экземпляр
BaseExample
который мог бы получить значенияExample01
илиExample02
. например:BaseExample a = new Example01()
Вы не можете - BaseExample<Example01>
и BaseExample<Example02>
- разные типы. Там нет базового типа (кроме object
), который может содержать любой тип.
Предположим, вы могли:
BaseExample a = new Example01();
a.Clone()
будет возвращаемый тип a.Clone()
?
Если ваш код находится в методе общего класса ot, вы можете:
public T MyMethod<T>(T value) where T : BaseExample<T>
{
BaseExample<T> a = value;
return value.Close();
}
Но тогда вы должны указать тип при вызове метода, например
Example01 a1 = new Example01();
Example01 a2 = MyMethod(a1); // MyMethod<Example01> is inferred by the compiler
Как уже упоминалось, поскольку Generic<T1>
и Generic<T2>
являются разными классами, вы не можете назначить их одной и той же переменной.
Один из способов, которым я обойду это, - использовать не общий базовый класс, такой, что
public abstract class BaseExample { ... }
public abstract class BaseExmmple<T> : BaseExample
where T : BaseExample<T>
{ ... }
Это можно сделать более безопасным путем внедрения internal abstract
элемента, так что внешние классы не могут реализовать BaseExample
.
Если вы хотите позвонить .Clone()
из объекта, .Clone()
в переменной не-общего типа, вы должны реализовать форму object
-returning, которая обертывается родовым классом для вызова общей формы.
BaseExample<T>
не будет работать, если компилятор не знает, что такоеT
(имеется в виду, что он находится в универсальном классе или методе), аBaseExample
не является типом.