-1

有人问过类似的问题,但我不确定我是否正确理解了答案。我指的是相等运算符在一个或两个类中被覆盖的情况。请解释我是否正确。如果我写if(a == b) { ... },则使用“a”类的相等运算符,如果使用 ,if(b == a) { ... }则使用“b”类中定义的相等运算符。如果我写的话,使用哪个类的相等运算符if(null == a) { ... }

4

2 回答 2

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;
    }
}

输出: 。

我们没有得到任何输出,因为被调用的运算符不是此处定义的运算符……而是使用默认运算符( for 的运算符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

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

于 2017-11-30T07:03:18.413 回答
0

只需尝试一下

public class Program
{
    public static void Main()
    {
        var foo = new Foo();

        if(foo == null)
        {
        }

        if(null == foo)
        {
        }
    }
}

public class Foo
{
    public static bool operator ==(Foo a, Foo b)
    {
        Console.WriteLine("Foo operator == called");
        return ReferenceEquals(a, b);
    }

    public static bool operator !=(Foo a, Foo b)
    {
        Console.WriteLine("Foo operator != called");
        return !(a == b);
    }

    public override bool Equals(object obj)
    {
        Console.WriteLine("Foo Equals() called");
        return ReferenceEquals(this, obj);
    }

    public override int GetHashCode()
    {
        Console.WriteLine("Foo GetHashCode() called");
        return base.GetHashCode();
    }
}

输出:

Foo operator == called
Foo operator == called

Foo所以在这两种情况下都会调用类的相等运算符。

于 2017-11-30T07:00:20.480 回答