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

创建List<IValueMapper<MyRecord>>遇CS1503错误,如何实现目标集合?

问题:如何创建包含MyMapper的List<IValueMapper>?

问题场景

现有以下接口与类定义:

public interface IValueMapper<TData>{ }
public class MyMapper : IValueMapper<IMyType> { }
public class MyRecord : BaseType, IMyType

尝试创建目标列表时触发编译器错误CS1503:

var mappers = new List<IValueMapper<MyRecord>>{new MyMapper() };

原因分析

C#中泛型接口默认是不变量,即IValueMapper<IMyType>和IValueMapper<MyRecord>被视为完全独立的类型,即便MyRecord实现了IMyType,也无法直接进行类型转换。

可行解决方案

方案一:将接口改为协变接口

在泛型参数前添加out关键字,把IValueMapper<TData>声明为协变接口:

public interface IValueMapper<out TData> { }

协变规则允许将泛型接口的宽泛类型(IMyType)实例转换为更具体的类型(MyRecord),此时原列表创建代码可直接正常编译。

方案二:创建适配包装类(无法修改接口时使用)

如果不能修改原接口定义,可以编写一个包装类,将MyMapper适配为IValueMapper<MyRecord>:

public class MyRecordMapperWrapper : IValueMapper<MyRecord>
{
    private readonly MyMapper _innerMapper;

    public MyRecordMapperWrapper(MyMapper innerMapper)
    {
        _innerMapper = innerMapper;
    }

    // 若IValueMapper有成员方法,需在此委托给_innerMapper实现
}

之后通过包装类创建列表:

var mappers = new List<IValueMapper<MyRecord>>{ new MyRecordMapperWrapper(new MyMapper()) };

方案三:强制类型转换(不推荐)

如果IValueMapper<TData>没有任何成员方法,可通过两次强制转换绕过编译器检查,但这种方式不安全,后续接口添加成员后可能引发运行时错误:

var mappers = new List<IValueMapper<MyRecord>>{ (IValueMapper<MyRecord>)(object)new MyMapper() };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:45:39