Does C# have some kind of value_or_execute or value_or_throw?

I’m learning C# and trying to handle the influx of "a could be null" warnings.

I was wondering, since it’s such a common case to error out when something is null, either by returning from the function or throwing an exception, does C# have some kind of syntactical sugar for that case ?

Example of what I have in mind: int a = obtainA() ??? { Console.WriteLine("Fatal error;") return }; (this is not real code)

I know about the ?? and ??= operators, but they don’t seem to help much here and I haven’t found better.

If not, what would be the closest we have to emulating this ? Is there no better way than to write the following ?

int? nullableA = obtainA();
int a;
if (nullableA is null) {
    a = nullableA.Value;
}
else {
    Console.WriteLine("Fatal error");
    return;
}
/* use a, or skip defining a and trust the static analyzer to notice nullableA is not null */

>Solution :

"or_throw" can be achieved with ?? operator since C# 7 due to throw expressions introduction:

int? i = null;
int j = i ?? throw new Exception();

Another throw approach can be achieved with ArgumentNullException.ThrowIfNull:

#nullable enable
int? i = null;
ArgumentNullException.ThrowIfNull(i);
int j = i.Value; // no warning, compiler determine that i can't be null here

Also you can write your own method supporting nullable flow analysis (like ArgumentNullException.ThrowIfNull does) with attributes for null-state static analysis interpreted by the C# compiler:

#nullable enable
int? i = null;
if (IsNullAndReport(i)) return;
int j = i.Value; // no warning, compiler determine that i can't be null here

bool IsNullAndReport([NotNullWhen(false)]int? v, [CallerArgumentExpression(nameof(i))] string name = "")
{
    if (v is null)
    {
        Console.WriteLine($"{name} is null;");
        return true;
    }

    return false;
}

And pattern matching approach:

int? i = null;
if (i is { } j) // checks if i is not null and assigns value to scoped variable 
{
    // use j which is int
}
else
{
    Console.WriteLine("Fatal error");
    return;
}

Leave a Reply