在 C# 中,是否应该检查传递给 null 的方法的引用

本文关键字:null 方法 引用 检查 是否 | 更新日期: 2023-09-27 17:55:29

嗯,几个月前我问了一个关于C和C++的类似问题,但由于整个"Windows Phone"的事情,我最近更加关注C#。

那么,在 C# 中,是否应该费心在方法边界处检查 NULL?我认为这与 C 和 C++ 中的不同,因为在 C# 中通常可以确定给定的引用是否有效——编译器将阻止在任何地方传递未初始化的引用,因此唯一可能的错误是它是空的。此外,在.NET Framework中为这些东西定义了一个特定的异常,即ArgumentNullException,它似乎编纂了程序员认为在传递无效null时应该得到什么。

我个人的观点再次是,这样做的呼叫者被破坏了,并且该呼叫者应该向他们扔NRE,直到几天结束。但是,我对此的确定程度远低于本机代码领域 - 在这方面,与C或C++相比,C#在某些地方具有完全不同的编程风格。

那么......你应该检查 C# 方法中的空参数吗?

在 C# 中,是否应该检查传递给 null 的方法的引用

是的,检查它们。最好使用代码协定告诉调用方您需要非空参数

void Foo(Bar bar) {
    Contract.Requires(bar != null);
}

这是特别有利的,因为客户可以准确地看到参数的要求。

如果不能使用代码协定,请使用保护子句

void Foo(Bar bar) {
    Guard.Against<ArgumentNullException>(bar == null);
}

快速失败。

我认为如果你

的方法不希望特定参数为null,最好抛出一个ArgumentNullException(或像Jason建议的那样使用合约)。通过向客户端发送合约,在调用方法时首先不传递 null 是一个更好的指标。

然后,空检查是客户的责任,这使得双方的代码更易于维护(通常是双赢的局面)......至少我是这么觉得的。

至少在

公共方法中验证所有参数是一种很好的做法。这有助于更快地定位错误,并且在读取代码时也有助于,因为它描述了方法的协定。

我们实现了一个静态类AssertUtilities,它有一堆用于参数和状态验证的方法。我相信有些人称这样的课程为Guard.

例如:

    public static void ArgumentNotNull(object argument, string argumentName)
    {
        if (argument == null)
            throw new ArgumentNullException(argumentName);
    }
    public static void ArgumentInRange(decimal argument, decimal minValue, decimal maxValue, string argumentName)
    {
        if (argument < minValue || argument > maxValue)
        {
            throw new ArgumentOutOfRangeException(
                argumentName,
                FormatUtilities.Format("Argument out of range: {0}. Must be between {1} and {2}.", argument, minValue, maxValue));
        }
    }
    public static void ArgumentState(bool expression, string argumentName, string formatText, params object[] args)
    {
        if (!expression)
            throw new ArgumentException(FormatUtilities.Format(formatText, args), argumentName);
    }
    public static void ArgumentHasText(string argument, string argumentName)
    {
        ArgumentNotNull(argument, argumentName);
        ArgumentState(argument.Length > 0, argumentName, "Argument cannot be an empty string.");
    }

那么......你应该检查 C# 方法中的空参数吗?

是的,当然,除非允许null

更好的视角:应始终检查有效的参数值。有时允许引用为空,有时必须>= 0 int,或者字符串可能不是 NullOrWhiteSpace。

因此,最好使用参数验证块启动每个方法。

从那里开始,有几种选择。内部/私有方法的验证通常被认为不太重要,并且出于性能原因,它可以成为有条件的(甚至被排除在外)。

边界处的验证通常在发布版本中保留。几乎没有理由关闭它。

大多数项目将使用一些帮助程序类进行验证,以最大程度地减少方法中的重复编码。一个非常好但还不是很流行的工具包是内置的System.Diagnostics.Contracts类。代码协定工具具有许多有关参数验证的设置。