比较2个接口

发布于 2024-10-18 05:32:28 字数 1603 浏览 1 评论 0原文

interface I //: IEquatable<I>
{ }

class A : I
{
    static public bool operator !=(A a, I i)
    {
        return !(a == i);
    }

    static public bool operator ==(A a, I i)
    {
        return true;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

class B : I
{
    static public bool operator !=(B b, I i)
    {
        return !(b == i);
    }

    static public bool operator ==(B b, I i)
    {
        return false;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        List<I> iss = new List<I>();
        A a = new A();
        B b = new B();
        iss.Add(a);
        iss.Add(b);

        if (iss[0] == iss[1])
            Console.WriteLine("a == b");
        else
            Console.WriteLine("a != b");

        if (iss[1] == iss[0])
            Console.WriteLine("b == a");
        else
            Console.WriteLine("b != a");
    }
}

输出是

a != b
b != a

我预期的

a == b
b != a

有人可以解释一下吗?

interface I //: IEquatable<I>
{ }

class A : I
{
    static public bool operator !=(A a, I i)
    {
        return !(a == i);
    }

    static public bool operator ==(A a, I i)
    {
        return true;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

class B : I
{
    static public bool operator !=(B b, I i)
    {
        return !(b == i);
    }

    static public bool operator ==(B b, I i)
    {
        return false;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        List<I> iss = new List<I>();
        A a = new A();
        B b = new B();
        iss.Add(a);
        iss.Add(b);

        if (iss[0] == iss[1])
            Console.WriteLine("a == b");
        else
            Console.WriteLine("a != b");

        if (iss[1] == iss[0])
            Console.WriteLine("b == a");
        else
            Console.WriteLine("b != a");
    }
}

The output is

a != b
b != a

I expected

a == b
b != a

Could somebody can explain it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你怎么这么可爱啊 2024-10-25 05:32:28

我会在每个类的 Equals() 方法和 == 运算符中设置一个断点,并查看调用什么来计算每个表达式。这显然不是你所期望的。我的猜测是,因为 I 不会也不可能要求实现者公开 == 运算符,因此当您比较两个 I 时这样做时,运行时不会费心寻找重载的运算符,而是求助于 System.Object ==,它执行引用检查。

I'd set a breakpoint in each class's Equals() method and == operator, and see what gets called to evaluate each expression. It's obviously not what you expect. My guess is that because I does not and cannot require implementors to expose a == operator, when two Is are compared as you're doing, the runtime doesn't bother looking for overloaded operators and instead resorts to the System.Object ==, which performs a referential check.

寂寞笑我太脆弱 2024-10-25 05:32:28

简单的答案:

您有一个 List,并且您将两个 I 相互比较。因为接口 I 没有(也不能)实现比较运算符,所以对象是通过引用进行比较的。

相反,您可以使用抽象基类:

public interface I
{
}

public abstract class AbstractI : I
{
    public static bool operator ==(AbstractI left, I right)
    {
        return left.equals(right); //TODO can be null
    }
    public static bool operator !=(AbstractI left, I right)
    {
        return !left.equals(right);
    }

    protected abstract bool equals(I other);
}

public class A : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}

public class B : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}


List<AbstractI> l = new List<AbstractI>(){
    new A(),
    new B()
};

var x = l[0] == l[1];

Simple answer:

You have a List<I> and you compare two I with each other. Because interface I does not (and cannot) implement a compare operator the objects are compared by reference.

Instead you could use an abstract base class:

public interface I
{
}

public abstract class AbstractI : I
{
    public static bool operator ==(AbstractI left, I right)
    {
        return left.equals(right); //TODO can be null
    }
    public static bool operator !=(AbstractI left, I right)
    {
        return !left.equals(right);
    }

    protected abstract bool equals(I other);
}

public class A : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}

public class B : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}


List<AbstractI> l = new List<AbstractI>(){
    new A(),
    new B()
};

var x = l[0] == l[1];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文