Класс предмета
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и что у него есть ограничение общего типа.
Надеюсь, теперь это имеет гораздо больше смысла.