使用带有约束的泛型时无法隐式转换类型[重复]
Posted
技术标签:
【中文标题】使用带有约束的泛型时无法隐式转换类型[重复]【英文标题】:Cannot implicitly convert type when using generics with constraints [duplicate] 【发布时间】:2021-11-11 17:56:48 【问题描述】:我正在尝试为 AutoMapper 创建一个自定义类型转换器,但我的问题是“无法隐式转换类型”
这是我的转换器代码:
public class StatusConverter<TValue> : ITypeConverter<string, Wrapper<TValue>> where TValue : Status
public Wrapper<TValue> Convert(string source, Wrapper<TValue> destination, ResolutionContext context)
return Status.Create(source);
错误发生在return Status.Create(source);
行,它说无法从Wrapper<Status>
转换为Wrapper<TValue>
。
我已在此处上传了与此相关的所有其他课程: https://dotnetfiddle.net/iSr94S
但我的问题是:
为什么我会收到此错误?我在方法where TValue : Status
中设置了一个约束,所以TValue
的类型是Status
,为什么会抱怨类型呢?
谢谢
【问题讨论】:
简而言之,因为Wrapper<Status>
不是Wrapper<SomeStatusInheritor>
。 Covariance and Contravariance in C# 可以作为调查的有用开始。
@GuruStron 你能解释一下我要查看的内容吗?我也尝试过以下操作:public class StatusConverter<TValue, TType> : ITypeConverter<string, Wrapper<TValue>> where TValue : Enumeration<TType> where TType : struct, IComparable public Wrapper<TValue> Convert(string source, Wrapper<TValue> destination, ResolutionContext context) return Status.Create(source);
但我得到了相同的结果。
你有继承自 Status
的类吗? Wrapper
究竟做了什么?
@GuruStron 不,我没有。这个想法是我的Enumeration
类是基类。从它继承的所有类都是sealed
。在这种情况下,Status
将被密封,但出于演示目的,我没有在这里进行。 Wrapper
将包含创建是否失败、成功、失败原因以及Value
等信息。我在演示中仅使用Value
对其进行了简化。
如果你不这样做,那么where TValue : Status
没有任何意义。将您的代码更改为StatusConverter: ITypeConverter<string, Wrapper<Status>>
【参考方案1】:
正如我在 cmets 中所说,这种行为的原因是 C# 中的类不支持方差,即Wrapper<SomeStatusChild>
不是Wrapper<Status>
(例如explained here)。如果您没有 Status
继承者,您可以这样做:
public class StatusConverter : ITypeConverter<string, Wrapper<Status>>
public Wrapper<Status> Convert(string source, Wrapper<Status> destination, ResolutionContext context)
return Status.Create(source);
【讨论】:
以上是关于使用带有约束的泛型时无法隐式转换类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章