【问题标题】:Convert EqualityComparer<Child<T>> into EqualityComparer<Parent>将 EqualityComparer<Child<T>> 转换为 EqualityComparer<Parent>
【发布时间】:2019-05-13 10:11:19
【问题描述】:

我有这样的层次结构:

public interface INode
{
    //...
}

public interface INode<T> : INode
{
    //...
}

public class Node : INode
{
    //...
}

public class Node<T> : Node, INode<T>
{
    //...     
}

现在我想这样投射:

EqualityComparer<INode<int>> intcomparer = EqualityComparer<INode<int>>.Default;
EqualityComparer<INode> comparer = intcomparer;

为什么这个转换无效?以及如何解决?

【问题讨论】:

    标签: c# generics inheritance casting iequalitycomparer


    【解决方案1】:

    为什么演员表应该是有效的?

    是什么让您相信EqualityComparer&lt;T&gt; 源自EqualityComparer&lt;Random base class/interface of T&gt;EqualityComparer&lt;every possible base class/interface of T&gt;

    你不能和这个比较:

    Node<string> stringNode;
    Node node = stringNode;
    

    这是有效的,因为 Node&lt;T&gt; 的类定义明确派生自 Node 的非泛型版本

    public class Node<T> : Node, INode<T>
    

    当您查看类定义时 EqualityComparer&lt;T&gt;

    public abstract class EqualityComparer<T> : 
        System.Collections.Generic.IEqualityComparer<T>,
        System.Collections.IEqualityComparer
    

    您可以看到没有非通用版本,但您可以将代码更改为他的:

    EqualityComparer<INode<int>> intcomparer = EqualityComparer<INode<int>>.Default;
    IEqualityComparer comparer = intcomparer;
    

    但是,IEqualityComparer 将没有关于您的INode 的信息,并且只定义了一个Equals(object, object) 方法。

    这对每个泛型类都有效,例如。看到这个相关的,甚至可能是重复的问题:

    Cast Generic<Derived> to Generic<Base>

    更新:

    之后,注意到IEqualityComparer&lt;T&gt; 被定义为IEqualityComparer&lt;in T&gt; - 所以逆变是可能的,你可以看看这个:

    Variance in generic Interfaces

    您目前的其他方式是可能的,接口IEqualityComparer&lt;T&gt; 在课堂上不起作用。

    IEqualityComparer<INode> comparer = EqualityComparer<INode>.Default;
    IEqualityComparer<INode<int>> intcomparer = comparer;
    

    【讨论】:

      猜你喜欢
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多