AutoMapper泛型转换器中Wrapper<Status>无法转Wrapper<Enum<byte>>问题问询
问题根因
该报错是C#默认的泛型不变性规则导致的:
- 泛型类的类型参数默认没有变体支持,即便
Status是Enum<byte>的子类,Wrapper<Status>和Wrapper<Enum<byte>>仍然是相互独立的类型,不存在继承关系,无法直接隐式转换。
解决方案
可根据实际业务场景选择以下任意一种方案:
方案1:声明协变接口(最推荐)
C#的协变仅支持接口和委托类型,你可以额外定义带协变标记的IWrapper<out T>接口,让Wrapper<T>实现该接口:
// out 关键字标记T为协变参数 public interface IWrapper<out T> { T Value { get; } } public class Wrapper<T> : IWrapper<T> { public T Value { get; set; } }
注意:协变参数
out T只能用作方法返回值、只读属性的类型,不能用作方法入参、可写属性的类型,完全符合普通包装类的使用场景。
后续自定义转换器时,将目标类型改为IWrapper<Enum<byte>>即可,Wrapper<Status>可以直接隐式转换为IWrapper<Enum<byte>>。
方案2:手动构造目标类型实例
如果不想修改Wrapper<T>的原有定义,可以在转换器中直接构造Wrapper<Enum<byte>>类型的返回值,而非返回Wrapper<Status>实例:
// 替换原有返回Wrapper<Status>的逻辑 var status = /* 你转换得到的Status实例 */; return new Wrapper<Enum<byte>> { Value = status };
方案3:注册开放泛型转换器适配所有子类场景
如果你需要统一处理所有继承自Enum<byte>的子类的Wrapper转换,可以直接注册开放泛型转换器,无需针对Wrapper<Enum<byte>>做统一适配:
// AutoMapper配置中注册开放泛型映射 cfg.CreateMap(typeof(string), typeof(Wrapper<>)) .ConvertUsing(typeof(StringToWrapperEnumConverter<>)); // 泛型转换器实现 public class StringToWrapperEnumConverter<T> : ITypeConverter<string, Wrapper<T>> where T : Enum<byte> { public Wrapper<T> Convert(string source, Wrapper<T> destination, ResolutionContext context) { // 你的字符串转T类型的转换逻辑 T enumValue = /* 转换得到的T实例 */; return Wrapper<T>.Wrap(enumValue); } }
内容的提问来源于stack exchange,提问作者Axajkamkat
相关产品推荐
相关产品推荐

