如果我理解正确:C#Equality运算符(==)和操作数的顺序

时间:2017-11-30 06:04:56

标签: c# equality-operator

已经提出了类似的问题,但我不确定我是否正确理解答案。我指的是在一个或两个类中重写相等运算符的情况。请解释我是否正确。如果我写if(a == b) { ... },那么" a"类的等于运算符。在if(b == a) { ... }被使用的情况下使用,然后在" b"的类中定义相等运算符。如果我写if(null == a) { ... },则使用哪个类的等于运算符。

1 个答案:

答案 0 :(得分:1)

  

在一个或两个类中重写相等运算符的情况

我们可以做到这一点并测试......如下所示?

class A
{
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator == (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

class B
{
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator == (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

然后你编写如下代码:

A a = new A();
B b = new B();
if (a == b)
{
    // ...
}

然后你得到:

  

CS0034运算符'=='在'A'和'B'类型的操作数上不明确

这会回答你的问题吗?看一下代码,在定义运算符==时指定参数的类型,编译器使用它来选择要调用的运算符。在这种情况下,它找到两个运算符按顺序具有操作数AB并且导致模糊调用(编译器不知道 - 没有办法决定 - 使用哪一个) )。

  

如果我写if(a == b) { ... },则使用“a”类的等式运算符,如果使用if(b == a) { ... },则在“b”类中定义等式运算符

这取决于操作数的类型。如果你总是将当前类的操作符作为第一个,那就是这样。例如:

void Main()
{
    A a = new A();
    B b = new B();
    if (a == b)
    {
        // ...
    }
}

class A
{
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

class B
{   
    public static bool operator == (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

输出:A

但是,如果使用相反顺序的操作数定义运算符...

void Main()
{
    A a = new A();
    B b = new B();
    if (a == b)
    {
        // ...
    }
}

class A
{
    public static bool operator == (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

class B
{   
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

输出:B

  

如果我写if(null == a) { ... }

,则使用哪个类的等于运算符

首先,让我们说清楚。 B或任何其他类别与此无关。它们不会影响此比较的结果,因为您在此处未使用它们。如果他们这样做会非常不方便。

让我们试试:

void Main()
{
    A a = new A();
    if (null == a)
    {
        // ...
    }
}

class A
{
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("A");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

class B
{   
    public static bool operator == (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("B");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

输出:。

我们没有输出,因为被调用的运算符不是这里定义的运算符...因为它使用的是默认运算符(object的运算符)。

等待!如果我改变操作数的顺序怎么办?

void Main()
{
    A a = new A();
    if (null == a)
    {
        // ...
    }
}

    class A
{
    public static bool operator == (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public static bool operator != (B b, A a)
    {
        Console.WriteLine("A");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

class B
{   
    public static bool operator == (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public static bool operator != (A a, B b)
    {
        Console.WriteLine("B");
        return false;
    }

    public override bool Equals(object o)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

输出:A

现在我们在A上使用运算符,因为它比默认运算符更好地匹配操作数类型。