【问题标题】:Only works when type of variable is derived class?仅当变量类型是派生类时才有效?
【发布时间】:2012-02-16 05:46:37
【问题描述】:

我有以下代码:

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)
{
    // ...
}

【问题讨论】:

标签: c# inheritance operator-overloading


【解决方案1】:

以下代码是检查对象是否等于 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

【讨论】:

    【解决方案2】:

    在 C# overriding 中,重载运算符本质上会创建一个静态方法,其名称类似于 op_xxx(例如 op_Add、op_Equality)。在您的问题中,test == null 之类的 Test.op_Equality(test, null) 行为显然会返回 true。而objTest == null 调用Object.op_Equality(test, null) 返回false。另一方面,你重写了虚方法Equals,所以test.EqualsobjTest.Equals的结果是一样的。

    【讨论】:

    • 谢谢,现在我将运算符视为静态方法,这对我来说更有意义。
    • @haiyyu:这就是为什么我们要求您将运算符声明为作为静态方法
    • 其实object.op_Equality()这个方法是不存在的。但行为与它类似。
    • 非常微妙的术语区别在于运算符被重载,而不是被覆盖。
    • @phoog:同意。我编辑了答案。感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多