Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

c# - Possibility of external functions as nullable guards?

C# 8 introduced nullable reference types, which is a very cool feature. Now if you expect to get nullable values you have to write so-called guards:

object? value = null;
if (value is null)
{
  throw new ArgumentNullException();
}
…

These can be a bit repetitive. What I am wondering is if it is possible to avoid writing this type of code for every variable, but instead have a guard-type static void function that throws exception if value is null or just returns if value is not null. Or is this too hard for compiler to infer? Especially if it's external library/package?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a few things you can do.

You can use [DoesNotReturnIf(...)] in your guard method, to indicate that it throws if a particular condition is true or false, for example:

public static class Ensure
{
    public static void True([DoesNotReturnIf(false)] bool condition)
    {
        if (!condition)
        {
             throw new Exception("!!!");   
        }
    }
}

Then:

public void TestMethod(object? o)
{
    Ensure.True(o != null);
    Console.WriteLine(o.ToString()); // No warning
}

This works because:

[DoesNotReturnIf(bool)]: Placed on a bool parameter. Code after the call is unreachable if the parameter has the specified bool value


Alternatively, you can declare a guard method like this:

public static class Ensure
{
    public static void NotNull([NotNull] object? o)
    {
        if (o is null)   
        {
            throw new Exception("!!!");
        }
    }
}

And use it like this:

public void TestMethod(object? o)
{
    Ensure.NotNull(o);
    Console.WriteLine(o.ToString()); // No warning
}

This works because:

[NotNull]:?For outputs (ref/out parameters, return values), the output will not be null, even if the type allows it. For inputs (by-value/in parameters) the value passed is known not to be null when we return.

SharpLab with examples


Of course, the real question is why you want to do this. If you don't expect value to be null, then declare it as object?, rather than object -- that's the point of having NRTs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...