仅在变量类型为派生类时才有效?

时间:2012-02-16 05:46:37

标签: c# inheritance operator-overloading

我有以下代码:

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

}

看起来运算符重载仅在你正在处理的变量的类型是定义运算符重载的类时起作用。我可以看出为什么会出现这种情况,因为我正在寻找一种安全的方法检查对象是否等于null。

我的问题是:

如果变量的类型是定义运算符的类,重载运算符是否有效(我的代码告诉我是,但我可能会犯错)?

以下代码是检查对象是否等于null的安全方法吗?

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

2 个答案:

答案 0 :(得分:5)

  

以下代码是检查对象是否等于null的安全方法吗?

if ((object)obj == null)

是。但是,我个人更喜欢:

if (object.ReferenceEquals(obj, null))

因为现在它对代码的读者来说非常清楚正是在这里发生了什么。

您可能有兴趣阅读有关使Equalsoperator==这些奇怪的鸭子的设计因素的文章:

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

答案 1 :(得分:2)

在C#重写重载操作符实际上创建了一个名为op_xxx的静态方法(例如op_Add,op_Equality)。在您的问题中,test == null行为如Test.op_Equality(test, null)显然会返回trueobjTest == null调用Object.op_Equality(test, null)时返回false。另一方面,您覆盖虚拟方法Equals,因此test.EqualsobjTest.Equals具有相同的结果。