67.泛型类的父子关系写法
67.1 题目
有以下两个泛型类的定义,它们之间存在父子关系:
public class Father<T>
{
// 父类定义
}
public class Son<T> : Father<T>
{
// 子类定义
}
public Father<Father<int>> Test()
{
return new Son<Son<int>>();
}
请判断这个写法是否正确。
67.2 深入解析
这个写法是不正确的,会报错。
因为 Son<Son<int>>
并不是 Father<Father<int>>
的子类。在C#中,泛型类的类型参数 T
是类型的一部分,而 T
并不存在里式替换的关系。
如果要修正这个问题,可以将返回类型修改为 Son<Father<int>>
的子类,例如:
public Father<Father<int>> Test()
{
return new Son<Father<int>>();
}
这样便符合了类型的关系,避免了报错。
关键点:泛型类的类型参数 T
是类型的一部分,而在继承关系中并不存在里式替换的关系。
67.3 答题示例
“这个写法是错误的。在C#中,泛型类的继承关系不会传递给类型参数,即
Son<T>
继承自Father<T>
,但Son<Son<int>>
和Father<Father<int>>
之间不存在继承关系。编译器会严格检查泛型参数的精确匹配,因此Son<Son<int>>
无法隐式转换为Father<Father<int>>
。正确的做法是确保泛型参数类型一致,例如将返回值改为new Son<Father<int>>()
,此时Son<Father<int>>
是Father<Father<int>>
的子类,满足里氏替换原则。”
67.4 关键词联想
- 泛型协变/逆变(Covariance/Contravariance)
- 类型参数约束(Type Parameter Constraints)
- 里氏替换原则(Liskov Substitution Principle)
- 泛型继承规则(Generic Inheritance Rules)
- 编译时类型检查(Compile-Time Type Checking)
- 引用转换(Reference Conversion)
- 泛型接口实现(Generic Interface Implementation)
- 协变接口示例(
IEnumerable<out T>
) - 泛型委托兼容性(Generic Delegate Compatibility)
- 类型参数不变性(Type Parameter Invariance)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com