c# - 实现 operator== 时如何避免 NullReferenceException

标签 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,因为 lhslhs.Equals(rhs) 行中为 null。我不能将 if (lhs != null) 放在 operator== 中,因为这会导致无限递归(正如书中警告的那样)。因此,为了避免在比较我的类的空实例时出现异常,我将实现更改为:

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

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

这种基于异常的实现在 C# 中是否符合惯用语?

最佳答案

我会避免为您的情况使用 try-catch block 。您只需将您的运营商更改为:

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() 方法。根据 System.Object.Equals() 的源代码:

public static bool Equals(Object objA, Object objB) 
{
    if (objA==objB) {
        return true;
    }
    if (objA==null || objB==null) {
        return false;
    }
    return objA.Equals(objB);
}

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

关于c# - 实现 operator== 时如何避免 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39905809/

相关文章:

c# - 如何在继续当前方法之前等待触发另一个方法,同时仍显示 UI

c# - 将分钟转换为毫秒

c# - 多线程单元测试

c# - 使用 Linq 映射模型

c# - switch 语句可以有多个变量吗?

c# - 替换页面的查询字符串

c# - 我可以在通用列表中使用 string.join

C# 调用 C++ 第 3 方 DLL(无源代码)引发异常 - 不兼容 PInvoke

c# - 如何在使用 MinimalApi 时配置 json 名称大小写策略

c# - 如何在同一行中找到重复的名称/值?可以算吗?