Добавить, где ограничение на класс B
class B<D> : A<C> where D : C
Чтобы ответить вам вопросы:
а) с исправлением в этом ответе, ваш подход является довольно чистым до сих пор, если чуть-чуть более абстрактно (из-за наименований в основном).
b) Вы должны добавлять только D-тип типа D к вашему дочернему классу B, если сам дочерний класс либо добавляет значение в общий способ, относящийся к подклассам C, которые являются экземплярами D; или если дочерний класс сам является неполным, ожидается, что он будет расширен и потребует подклассы знаний C как D. В этом случае вы должны отметить его абстрактным.
UPDATE:
Я хотел бы добавить еще одну вещь об этом. В вышеприведенной сигнатуре параметр T
A<T>
будет C в тех элементах A, которые используют тип T
. Это может быть проблемой, как показано в следующем примере:
public class C {}
public class F : C {}
public class E : C {}
public class A<T> where T : C
{
protected T cSubclass;
public void SetCSubclass(T cSubclass) { this.cSubclass = cSubclass; }
}
public class B<D> : A<C> where D : C
{
public D GetCSubclass()
{
return this.cSubclass;
}
}
Код в этом примере не будет компилироваться.Вы получите следующее сообщение об ошибке компиляции:
error CS0266: Cannot implicitly convert type 'C' to 'D'. An explicit conversion exists (are you missing a cast?)
Однако, устранена ошибка компиляции, если мы изменим класс B к следующему:
public class B<D> : A<D> where D : C
{
public D GetCSubclass()
{
return this.cSubclass;
}
}
Причина заключается в том, что D должен быть конкретный подкласс C , однако в прежней версии мы ограничили A только любой формой C, включающей сам себя и любой из его подклассов. Поэтому мы могли бы назвать new B<F>.SetCSubclass(new E());
, который был бы другого типа, чем ожидал бы возврат GetCSubclass. В последней версии мы указали D как аргумент типа для использования в форсировании A B<F>.SetCSubclass
, чтобы принимать только экземпляры F
.
Это обеспечивает дополнительную степень безопасности типа, которую может ожидать разработчик, использующий этот тип шаблонов.
Не видите сценарий, который вы использовали бы, но «A где T1: T2, где T2: C' и' B : A 'должен делать трюк. –
MarcinJuraszek