C#中能否用基类泛型变量引用派生类泛型对象?
解决方案:统一匹配泛型渲染组件的对象
你原来的写法失效是因为C#泛型类默认是不变的——BaseRenderComp<Line>和BaseRenderComp<BaseLine>属于完全独立的类型,不存在继承关系,所以无法通过is BaseRenderComp<BaseLine>来匹配子类泛型实例。以下是三种可行的实现方式:
方案1:使用协变泛型接口(推荐,扩展性好)
通过out关键字声明泛型参数为协变,让子类泛型接口实例可以隐式转换为父类泛型接口类型:
- 定义协变接口:
// out关键字标记T为协变类型,只能用于返回值,不能作为方法参数 public interface IBaseRenderComp<out T> where T : BaseLine { T GetLine(); // 其他通用只读/返回型成员... }
- 让原泛型基类实现该接口:
public abstract class BaseRenderComp<T> : IBaseRenderComp<T> where T : BaseLine { public abstract T GetLine(); // 原有逻辑实现... }
- 统一判断逻辑:
if (renderComp is IBaseRenderComp<BaseLine> baseRenderComp) { // do something.... BaseLine targetLine = baseRenderComp.GetLine(); }
方案2:定义非泛型基类/接口(简单直接)
如果不需要依赖具体泛型参数类型,可以定义一个非泛型的通用基类/接口:
- 定义非泛型接口:
public interface IBaseRenderComp { void Render(); BaseLine GetBaseLine(); }
- 修改泛型基类实现该接口:
public abstract class BaseRenderComp<T> : IBaseRenderComp where T : BaseLine { public abstract T GetLine(); // 实现非泛型接口方法 public BaseLine GetBaseLine() => GetLine(); public abstract void Render(); }
- 统一判断逻辑:
if (renderComp is IBaseRenderComp baseRenderComp) { // do something.... baseRenderComp.Render(); BaseLine targetLine = baseRenderComp.GetBaseLine(); }
方案3:模式匹配直接匹配多类型(快速临时解决)
如果不想修改现有类结构,可使用C# 9.0+支持的模式匹配或运算符,直接匹配多个目标类型:
if (renderComp is LineRenderComp or PolyLineRenderComp baseRenderComp) { // do something.... // 此处baseRenderComp的类型为两个类的共同基类,可按需转换 }
注:该方案扩展性差,新增渲染组件时需同步修改判断条件。
内容的提问来源于stack exchange,提问作者personax
相关产品推荐
相关产品推荐

