Класс предмета
public class Item
{
public bool Check(int value) { ... }
}
Базовый абстрактный класс с общим типом ограничений
public abstract class ClassBase<TItem>
where TItem : Item
{
protected IList<TItem> items;
public ClassBase(IEnumerable<TItem> items)
{
this.items = items.ToList();
}
public abstract bool CheckAll(int value);
}
Унаследованный класс без ограничений
public class MyClass<TItem> : ClassBase<TItem>
{
public override bool CheckAll(int value)
{
bool result = true;
foreach(TItem item in this.items)
{
if (!item.Check(value)) // this doesn't work
{
result = false;
break;
}
}
return result;
}
}
Я хотел бы знать, почему наследования не являются типичными ограничениями типа? Поскольку, если мой унаследованный класс наследуется от базового класса и передает его общий тип, который имеет ограничение на базовый класс, он автоматически означает, что общий тип в унаследованном классе должен иметь такое же ограничение без явного определения его. Не так ли?
Я делаю что-то неправильно, понимая это неправильно или действительно ли это ограничение общего типа не наследуется? Если последнее верно, , почему в мире это?
Немного дополнительного объяснения
Почему я думаю, что ограничения типа generic, определенные в классе, должны быть унаследованы или принудительно введены в дочерние классы? Позвольте мне дать вам дополнительный код, чтобы сделать его менее очевидным.
Предположим, что мы имеем все три класса, как указано выше. Тогда мы также имеем этот класс:
public class DanteItem
{
public string ConvertHellLevel(int value) { ... }
}
Как мы видим, этот класс не наследует от Item
, поэтому он не может использоваться как конкретный класс как ClassBase<DanteItem>
(забудьте о том, что ClassBase
является абстрактным на данный момент. обычный класс). Поскольку MyClass
не определяет каких-либо ограничений для своего типового типа, кажется совершенно справедливым, что MyClass<DanteItem>
...
Но. Вот почему я считаю, что ограничения общего типа должны быть унаследованы/применены в унаследованных классах так же, как и для ограничений типа generic типа, потому что если мы посмотрим на определение MyClass
, то он говорит:
MyClass<T> : ClassBase<T>
Когда T
есть DanteItem
, мы можем видеть, что он автоматически не может использоваться с MyClass
, потому что он унаследован от ClassBase<T>
и DanteItem
не выполняет свое ограничение общего типа. Я мог бы сказать, что ** общий тип на MyClass
зависит от ограничений типа ClassBase
общего типа, поскольку в противном случае MyClass
может быть создан с любым типом. Но мы знаем, что этого не может быть.
Было бы, конечно, иначе, если бы я имел MyClass
, определяемый как:
public class MyClass<T> : ClassBase<Item>
в этом случае T не имеет ничего общего с базовым классом, поэтому он не зависит от него.
Это все немного объяснение/рассуждение. Я мог бы просто подвести итог:
Если мы не предоставляем ограничение общего типа на
MyClass
, это подразумевает, что мы можем создать экземплярMyClass
с любым конкретным типом. Но мы знаем, что это невозможно, так какMyClass
наследуется отClassBase
и что у него есть ограничение общего типа.
Надеюсь, теперь это имеет гораздо больше смысла.