You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中转换泛型包装类中的派生类实例

解决Wrapper到Wrapper的转换问题

问题原因

C#中默认的泛型类是不变的——即使Y继承自X,Wrapper<Y>和Wrapper<X>也会被视为完全独立的类型,因此无法直接隐式转换,这就是报错CS0029的原因。

解决方案:使用协变泛型接口

C#允许泛型接口/委托通过out关键字实现协变,只要泛型参数仅作为输出类型(如方法返回值)使用,就能安全地实现子类泛型实例到父类泛型实例的转换。

修改代码如下:

using System;

class X {}
class Y: X {}

// 定义协变接口,用out标记泛型参数T
interface IWrapper<out T> where T : X {}

// 让原Wrapper类实现该协变接口
class Wrapper<T> : IWrapper<T> where T : X {}

public class HelloWorld
{
    public static void Main(string[] args)
    {
        Wrapper<Y> y = new();
        // 现在可以隐式转换为IWrapper<X>
        IWrapper<X> x = y; 
    }
}

注意事项

  • 协变的out关键字要求泛型参数T只能出现在输出位置(比如方法返回值、只读属性),不能作为方法的输入参数(如void SetItem(T item)这类方法会导致协变无法生效)。
  • 如果必须保留Wrapper<X>的类类型而非接口,也可以在Wrapper<T>中实现显式转换方法,但协变接口是更符合C#类型系统设计的优雅方案。

内容的提问来源于stack exchange,提问作者kennarddh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 21:05:02