Как наследовать от общего параметра?
Я в основном хочу это сделать:
class UILockable<T> : T
where T : UIWidget
{
}
Однако это не работает. Я видел, как люди рекомендуют вам это делать:
class UILockable<T>
where T : UIWidget
{
private T _base;
}
Это потребовало бы, чтобы я переопределял каждую функцию, которую UILockable нуждался бы и перенаправлял бы ее T. Это невозможно, так как T может происходить из UIWidget и иметь уникальные абстрактные/виртуальные методы.
Нет способа просто наследовать от T?
Ответы
Ответ 1
Вы не можете наследовать параметр родового типа. С# generics сильно отличаются от шаблонов С++. Наследование от параметра type требует, чтобы класс имел совершенно иное представление, основанное на параметре type, что не так, как в случае с генериками .NET. Они идентичны на уровне IL и на уровне (для всех аргументов ссылочного типа).
Ответ 2
Нет, нет. Однако я не понимаю ваш аргумент против того, чтобы UILockable<T>
наследовать от UIWidget
и переадресовывать все вызовы на ваш T
:
class UILockable<T> : UIWidget
where T : UIWidget
{
private readonly T t;
public void SomeMethod()
{
this.t.SomeMethod();
}
}
Вам не нужна спецификация T
реализации UIWidget
- только то, что это реализация UIWidget
.
Ответ 3
Подумайте об этом так:
Когда тип B наследуется от типа A, вы заявляете, что B похож на A (где сходство означает, что вы можете использовать B везде, где вы ожидаете использовать A). Теперь, поскольку такое сходство не симметрично, вы имеете то, что B аналогично A, но A не похож на B. Кроме того, B и C могут быть похожими на A (то есть они оба спускаются из A), не будучи похожими друг на друга.
Так что вы хотите объявить, что Unlockable похож на все, что похоже на UIWidget, но это невозможно, потому что тип сходства не является транзитивным (т.е. если B аналогичен A и C аналогичен A, вы не можете сказать B аналогичен C).
Ответ 4
Вы не можете наследовать от аргумента Generic type. С# - строго типизированный язык. Все типы и иерархия наследования должны быть известны во время компиляции..Net generics отличаются от шаблонов С++.
И когда вы так уверены, что аргумент типа T будет иметь тип UIWidget, тогда почему бы не наследовать от UIWidget. Если это когда-нибудь будет разрешено [предполагая, просто предполагая, что я знаю, что это никогда не будет возможно], что бы вы достигли, наследуя свой класс от T, который уже имеет тип UIWidget. Во время разработки вы будете только кодировать UIWidget, поэтому почему бы не напрямую наследовать от UIWidget.