使用带有约束的泛型时无法隐式转换类型[重复]

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&lt;Status&gt; 转换为Wrapper&lt;TValue&gt;

我已在此处上传了与此相关的所有其他课程: https://dotnetfiddle.net/iSr94S

但我的问题是: 为什么我会收到此错误?我在方法where TValue : Status中设置了一个约束,所以TValue的类型是Status,为什么会抱怨类型呢?

谢谢

【问题讨论】:

简而言之,因为Wrapper&lt;Status&gt; 不是Wrapper&lt;SomeStatusInheritor&gt;。 Covariance and Contravariance in C# 可以作为调查的有用开始。 @GuruStron 你能解释一下我要查看的内容吗?我也尝试过以下操作:public class StatusConverter&lt;TValue, TType&gt; : ITypeConverter&lt;string, Wrapper&lt;TValue&gt;&gt; where TValue : Enumeration&lt;TType&gt; where TType : struct, IComparable public Wrapper&lt;TValue&gt; Convert(string source, Wrapper&lt;TValue&gt; destination, ResolutionContext context) return Status.Create(source); 但我得到了相同的结果。 你有继承自 Status 的类吗? Wrapper 究竟做了什么? @GuruStron 不,我没有。这个想法是我的Enumeration 类是基类。从它继承的所有类都是sealed。在这种情况下,Status 将被密封,但出于演示目的,我没有在这里进行。 Wrapper 将包含创建是否失败、成功、失败原因以及Value 等信息。我在演示中仅使用Value 对其进行了简化。 如果你不这样做,那么where TValue : Status 没有任何意义。将您的代码更改为StatusConverter: ITypeConverter&lt;string, Wrapper&lt;Status&gt;&gt; 【参考方案1】:

正如我在 cmets 中所说,这种行为的原因是 C# 中的类不支持方差,即Wrapper&lt;SomeStatusChild&gt; 不是Wrapper&lt;Status&gt;(例如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);
    

【讨论】:

以上是关于使用带有约束的泛型时无法隐式转换类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Scala 宏介绍

带有泛型的 Typescript JSX - 参数隐式具有“任何”类型

Scala:从泛型类型到第二泛型类型的隐式转换

使用支持对象/结构的泛型时如何返回空值/默认值? [复制]

学习笔记——泛型

C#错误(无法将类型'string'隐式转换为'int')[重复]