Работает только тогда, когда тип переменной является производным классом? - PullRequest
2 голосов
/ 16 февраля 2012

У меня есть следующий код:

class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        object objTest = test;

        Console.WriteLine(test.GetType());    // Output: "OperatorOverload.Test"
        Console.WriteLine(objTest.GetType()); // Output: "OperatorOverload.Test"

        Console.WriteLine(test == null);    // Output: "True"
        Console.WriteLine(objTest == null); // Output: "False"

        test.Equals(null);    // Output: "Hi!"
        objTest.Equals(null); // Output: "Hi!"

        Console.ReadLine();
    }
}

Тест выглядит так:

class Test
{

    public static bool operator ==(Test obj1, Test obj2)
    {
        return true;
    }

    public static bool operator !=(Test obj1, Test obj2)
    {
        return !(obj1 == obj2);
    }

    public override bool Equals(object obj)
    {
        Console.WriteLine("Hi!");
        return true;
    }

}

Представляется, что перегрузка оператора работает только тогда, когда тип переменной, с которой вы имеете дело, является классом, в котором определена перегрузка оператора. Я понимаю, почему это так, поскольку я ищу безопасный проверки, равен ли объект нулю.

Мои вопросы:

Перегруженные операторы работают только в том случае, если тип переменной - это класс, в котором определен оператор (мой код говорит мне «да», но я мог ошибиться)?

Является ли следующий код безопасным способом проверки, равен ли объект нулю?

SomeClass obj = new SomeClass(); // may have overloaded operators
if ((object)obj == null)
{
    // ...
}

Ответы [ 2 ]

5 голосов
/ 16 февраля 2012

Является ли следующий код безопасным способом проверки, равен ли объект нулю?

if ((object)obj == null)

Да.Тем не менее, я лично предпочитаю:

if (object.ReferenceEquals(obj, null))

, потому что теперь для читателя кода кристально ясно , что именно здесь происходит.чтобы прочитать мою статью о факторах дизайна, которые делают Equals и operator== такими странными утками:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx

2 голосов
/ 16 февраля 2012

В C # переопределение перегрузка оператора по существу создает статический метод с его именем, например op_xxx (например, op_Add, op_Equality). В вашем вопросе test == null поведение, подобное Test.op_Equality(test, null), которое, очевидно, возвращает true. В то время как objTest == null вызывает Object.op_Equality(test, null), возвращается false. С другой стороны, вы переопределяете виртуальный метод Equals, поэтому test.Equals и objTest.Equals имеют одинаковый результат.

...