67.泛型类的父子关系写法

  1. 67.泛型类的父子关系写法
    1. 67.1 题目
    2. 67.2 深入解析
    3. 67.3 答题示例
    4. 67.4 关键词联想

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

×

喜欢就点赞,疼爱就打赏