首页 > 解决方案 > 将继承接口的类与接口引用进行比较

问题描述

在我的课堂ClassA : ISomeInterface上,我有:

public class ClassA : ISomeInterface {
    Entity entity;
    public void Test(){
       if(entity.Target == this){}
    }    
}

定义Targetentity

public class Entity {     

   public ISomeInterface Target {get; private set;}    

}

然后我的编辑给了我一个警告:

Possible unintended reference comparison; to get a value comparison cast the LHS to type `Object`

在此处输入图像描述

虽然它可以编译,但这是我第一次收到此警告。我不应该像这样比较接口引用吗?

标签: c#

解决方案


正如您已经说过的,这是警告而不是错误。警告告诉你编译器真正做了什么,也许你故意猜测应该发生的事情是错误的。

话虽如此,让我们进一步挖掘问题可能是什么。这是一些示例代码(请给出完整的示例):

using System;

public interface ISomeInterface
{
}

public class ClassA : ISomeInterface
{
    public ClassA(int id)
    {
        Id = id;
    }

    public int Id { get; }

    public ISomeInterface Entity { get; set; }
    
    public static bool operator== (ClassA x, ClassA y)
    {
        return true;
    }
    
    public static bool operator!= (ClassA x, ClassA y)
    {
        return false;
    }

    public override bool Equals(object obj)
    {
        return true;
    }
    
    public override int GetHashCode()
    {
        return 72;
    }

    public void Test()
    {
        if (Entity == this)
        {
            Console.WriteLine("same");
        }
        else
        {
            Console.WriteLine("different");
        }
    }
}

public class Program
{
    public static void Main()
    {
        var first = new ClassA(1);
        var second = new ClassA(1);
        first.Entity = second;
        first.Test(); // writes "different"
    }
}

如您所见,代码实现了相等比较器和Equals(). 所有这些方法都说所有实例都是相同的,但调用if(Entity == this)仍然表明它们是不同的。

这就是警告的含义,根本原因是,接口的相等性检查总是回退到 type 中的实现object。而那个实现是ReferenceEquals(x, y).

因此,为避免此警告并明确您的意图,您应该显式编写if(ReferenceEquals(Entity, this))或实现一个独立的类,该类实现IEqualityComparer<ISomeInterface>并使用它的实例if(new MyComparer().Equals(Enity, this))(不要在真实代码中的 if 语句中实例化比较器)来做出比较的意图明显的。


推荐阅读