扩展空检查的最佳方法是什么?

Age*_*ire 16 c# null extension-methods isnull

你们都这样做了:

public void Proc(object parameter)
{
    if (parameter == null)
        throw new ArgumentNullException("parameter");

    // Main code.
}
Run Code Online (Sandbox Code Playgroud)

Jon Skeet曾经提到他有时会使用扩展来进行检查,所以你可以这样做:

parameter.ThrowIfNull("parameter");
Run Code Online (Sandbox Code Playgroud)

所以我得到了这个扩展的两个实现,我不知道哪个是最好的.

第一:

internal static void ThrowIfNull<T>(this T o, string paramName) where T : class
{
    if (o == null)
        throw new ArgumentNullException(paramName);
}
Run Code Online (Sandbox Code Playgroud)

第二:

internal static void ThrowIfNull(this object o, string paramName)
{
    if (o == null)
        throw new ArgumentNullException(paramName);
}
Run Code Online (Sandbox Code Playgroud)

你怎么看?

Ada*_*rth 13

我倾向于坚持无处不在的Guard课程:

static class Guard
{
    public static void AgainstNulls(object parameter, string name = null)
    {
        if (parameter == null) 
            throw new ArgumentNullException(name ?? "guarded argument was null");

        Contract.EndContractBlock(); // If you use Code Contracts.
    }
}

Guard.AgainstNulls(parameter, "parameter");
Run Code Online (Sandbox Code Playgroud)

并且避免扩展object,加上肉眼观察null对象的方法似乎是荒谬的(尽管我知道对扩展方法进行空方法调用是完全有效的).

至于哪个最好,我也不使用.它们都有无限的递归.我也不打扰保护message参数,使其可选为null.您的第一个解决方案也不支持Nullable<T>类型,因为class约束会阻止它.

当我们决定启用代码合约时,我们的Guard课程也会Contract.EndContractBlock()接到调用,因为它符合所需的"if-then-throw"结构.

这也是PostSharp方面的完美候选者.


yv9*_*89c 6

ThrowIfNull从 .NET 6 开始,现在类中的静态方法具有System.ArgumentNullException以下签名:

ThrowIfNull(object? argument, string? paramName = null);
Run Code Online (Sandbox Code Playgroud)

因此,不要写:

if (value == null)
{
    throw new System.ArgumentNullException(nameof(value));
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以简单地写:

System.ArgumentNullException.ThrowIfNull(value);
Run Code Online (Sandbox Code Playgroud)

文档:https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull? view=net-6.0


这个新方法的实现利用该System.Runtime.CompilerServices.CallerArgumentExpressionAttribute属性来进一步简化这一过程,不需要开发人员显式提供受保护的参数的名称。

最终引入这个新 API 的讨论可以在这里找到: https ://github.com/dotnet/runtime/issues/48573

可以在此处找到在 .NET 6 代码库中引入它的 PR: https: //github.com/dotnet/runtime/pull/55594


Vas*_*are 5

我用了internal static void ThrowIfNull<T>(this T o, string paramName) where T : class.我不会用,internal static void ThrowIfNull(this object o, string paramName)因为它可能会做拳击.

  • 拳击的影响也可以忽略不计,人们忘记它实际上已经从.NET预仿制日那里得到了很好的优化.虽然它可以增加GC压力.我倾向于发现"拳击"这些天并不是一个有效的全部借口,拳击在某些情况下完全可以接受,而在其他情况下则不然. (2认同)

归档时间:

查看次数:

4702 次

最近记录:

8 年,9 月 前