实现operator ==

时间:2016-10-06 21:21:24

标签: c#

我试图在我的一个班级中实施operator==。根据书 Microsoft Visual C#Step by Step ,我应该这样写:

using System;
using System.Diagnostics;

namespace EqualTest2
{
    public class EqualTestClass
    {
        public double _x1;

        public EqualTestClass(double x1)
        {
            _x1 = x1;
        }

        public override bool Equals(object other)
        {
            if (other is EqualTestClass)
            {
                return (Math.Abs(_x1 - ((EqualTestClass)other)._x1) < 1e-6);
            }
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs)
        {
            return lhs.Equals(rhs);
        }

        public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs)
        {
            return !lhs.Equals(rhs);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            EqualTestClass test1 = new EqualTestClass(1.0);
            EqualTestClass test2 = new EqualTestClass(1.0);
            EqualTestClass test3 = new EqualTestClass(2.0);
            EqualTestClass test4 = null;

            Debug.WriteLine("1: {0}", test1 == test2);
            Debug.WriteLine("2: {0}", test1 == test3);
            Debug.WriteLine("3: {0}", test1 == test4);
            Debug.WriteLine("4: {0}", test4 == test1);
        }
    }
}

此程序在第四个调试行上抛出NullReferenceException,因为行lhs上的lhs.Equals(rhs)为空。我无法将if (lhs != null)放入operator==,因为这会导致无限递归(正如本书警告的那样)。因此,为了避免在比较我的类的null实例时出现异常,我将实现更改为:

    public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs)
    {
        try
        {
            return lhs.Equals(rhs);
        }
        catch (NullReferenceException)
        {
            return false;
        }
    }

    public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs)
    {
        try
        {
            return !lhs.Equals(rhs);
        }
        catch (NullReferenceException)
        {
            return false;
        }
    }

(我是来自Objective C背景的C#的新手,如果[lhs method:argument]为零,lhs愉快地返回nil,那么这样的异常将永远不会发生。)

这种基于异常的实现是否正确地纠正了C#?

4 个答案:

答案 0 :(得分:3)

在检查相等性之前,考虑使用ReferenceEquals(lhs, null)检查每个args的null引用

答案 1 :(得分:3)

我会避免在你的情况下使用try-catch块。您只需要将操作符更改为:

public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs)
{
    return object.Equals(lhs, rhs);
}
public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs)
{
    return !object.Equals(lhs, rhs);
}

这将在您仍然调用被覆盖的Equals()方法时对您进行空值检查。根据{{​​1}}的源代码:

System.Object.Equals()

看起来这样可以解决您的问题。

答案 2 :(得分:0)

您需要通过引用比较参数:

if (!ReferenceEquals(lhs, null)) ...

答案 3 :(得分:0)

首先执行空测试

if(lhs == null || rhs == null){

按照你想要的方式处理。 (返回false,如果两者都为null,则返回true)

.equals()需要一个对象,如果你试图在空对象上调用它,它将抛出NullPointer。但==工作正常。