Best way to check for null parameters (Guard Clauses)

后端 未结 10 1802
北荒
北荒 2021-01-31 16:45

For example, you usually don\'t want parameters in a constructor to be null, so it\'s very normal to see some thing like

if (someArg == null)
{
    throw new Arg         


        
相关标签:
10条回答
  • 2021-01-31 17:14

    If you want to save typing the argument name twice, like Guard.AgainstNull(arg, nameof(arg));

    check out YAGuard, where you can write Guard.AgainstNull(arg);

    No need to specify the name of the argument in the guard clause, but in the argument thrown, the name is correctly resolved.

    It also supports guard-and-set in the form MyProperty = Assign.IfNotNull(arg);

    Nuget: YAGuard

    Disclaimer: I'm the author of YAGuard.

    0 讨论(0)
  • 2021-01-31 17:17

    Null references are one sort of troubles you have to guard against. But, they are not the only one. The problem is wider than that, and it boils down to this: Method accepts instances of a certain type, but it cannot handle all instances.

    In other words, domain of the method is larger than the set of values it handles. Guard clauses are then used to assert that actual parameter does not fall into that "gray zone" of the method's domain which cannot be handled.

    Now, we have null references, as a value which is typically outside the acceptable set of values. On the other hand, it often happens that some non-null elements of the set are also unacceptable (e.g. empty string).

    In that case, it may turn out that the method signature is too broad, which then indicates a design problem. That may lead to a redesign, e.g. defining a subtype, typically a derived interface, which restricts domain of the method and makes some of the guard clauses disappear. You can find an example in this article: Why do We Need Guard Clauses?

    0 讨论(0)
  • 2021-01-31 17:18

    Ardalis has an excellent GuardClauses library.

    It's nice to use Guard.Against.Null(message, nameof(message));

    0 讨论(0)
  • 2021-01-31 17:19

    In C# 8.0 and later, new helps are available. C# 8.0 introduces non-nullable reference types (a feature somewhat confusingly called "nullable reference types" in the docs). Prior to C# 8.0, all reference types could be set to null. But now with C# 8.0 and the 'nullable' project setting, we can say that reference types are by default non-nullable, and then make our variables and parameters nullable on a case-by-case basis.

    So whereas at the moment, we recognize code like this:

    public void MyFunction(int thisCannotBeNull, int? thisCouldBeNull)
    {
        // no need for checking my thisCannotBeNull parameter for null here
    }
    

    If you set <Nullable>enable</Nullable> for your C# v8.0+ project, you can do things like this too:

    public void MyFunction(MyClass thisCannotBeNull, MyClass? thisCouldBeNull)
    {
        // static code analysis at compile time checks to see if thisCannotBeNull could be null
    }
    

    The null-checking is done at compile-time, using static code analysis. So if you've coded it in a way that means a null could turn up there, you'll get a compiler warning (which you can upgrade to an error if you want). So lots (but not all) of the situations where you need a run-time check for null parameters can be handled as a compile-time check based on your code.

    0 讨论(0)
  • 2021-01-31 17:19

    There is a nuget package called SwissKnife. Install SwissKnife from nuget gallery. It provides you with many options starting with null checking for arguments Argument.IsNotNullOrEmpty(args,"args") under SwissKnife.Diagnostics.Contracts namespace alongwith with option idoim and many more. You can set Option<Class_Name> _someVar and then check if _someVar.IsSome or _someVar.IsNone. This helps against nullable classes as well. Hope this helps.

    0 讨论(0)
  • 2021-01-31 17:26

    With newer version of C# language you can write this without additional library or additional method call:

    _ = someArg ?? throw new ArgumentNullException(nameof(someArg));
    _ = otherArg ?? throw new ArgumentNullException(nameof(otherArg));
    
    0 讨论(0)
提交回复
热议问题