Throw an exception if an object is null
Asked Answered
G

6

17

I've recently discovered that this:

if (Foo() != null)
    { mymethod(); }

can be rewritten as:

Foo?.mymethod()

Can the following be rewritten in a similar fashion?

if (Foo == null)
    { throw new Exception() }
Gehenna answered 17/2, 2016 at 23:44 Comment(3)
The way you have it is correct. The Null-conditional Operator only returns NULL.Centrepiece
There's no shortcut to throw an exception but one of the things you can do is shorten checks like if (Foo == null || Foo.Bar == null || Foo.Bar.Oof == null) throw ... to if (Foo?.Bar?.Oof == null) throw ...Angarsk
If my memory serves me correctly, any call to throw new Exception() actually guarantees that the method will not be inlined. Therefore, in the official Microsoft manuals they recommended ArgumentNullException.ThrowIfNull. This approach is extended in dotnet8 with new checks for utofrange exceptions. See issue github.com/dotnet/runtime/issues/69590Ellga
D
2

I don't know why you would..

public Exception GetException(object instance)
{
    return (instance == null) ? new ArgumentNullException() : new ArgumentException();
}

public void Main()
{
    object something = null;
    throw GetException(something);
}
Denishadenison answered 18/2, 2016 at 0:6 Comment(1)
Do not use throw. Microsoft creates special helpers that do not reduce performance.Ellga
M
29

Yes, as of C# 7 you can use Throw Expressions

var firstName = name ?? throw new ArgumentNullException("Mandatory parameter", nameof(name));

Source

Mccollough answered 13/6, 2018 at 8:55 Comment(3)
Nice, but your arguments are backwards in ArgumentException :)Blandishment
That said, they'd be the right way round for ArgumentNullException.Blandishment
Can't find something for condition, for example if(blub > 0) { throw exception}Pamulapan
E
29

As of .NET 6, you can use the ArgumentNullException.ThrowIfNull() static method:

void HelloWorld(string argumentOne)
{
    ArgumentNullException.ThrowIfNull(argumentOne);
    Console.WriteLine($"Hello {argumentOne}");
}
Explain answered 4/11, 2021 at 7:57 Comment(1)
This method introduced with .NET 6 Framework, not C# Lang 10. learn.microsoft.com/en-us/dotnet/api/… For example, if your project netcoreapp3.1 framework and using C# 10.0 you can not use this static method.Multifaceted
D
8

There is no similar fashion syntax in C# 6.

However, if you want you can simplify null check by using an extension methods...

 public static void ThrowIfNull(this object obj)
    {
       if (obj == null)
            throw new Exception();
    }

usage

foo.ThrowIfNull();

Or improvement it to display null object name.

 public static void ThrowIfNull(this object obj, string objName)
 {
    if (obj == null)
         throw new Exception(string.Format("{0} is null.", objName));
 }

foo.ThrowIfNull("foo");
Deel answered 18/2, 2016 at 0:9 Comment(1)
The method call can be changed to: foo.ThrowIfNull(nameof(foo)); Makes it safe if the variable name is changed :)Irizarry
D
2

I don't know why you would..

public Exception GetException(object instance)
{
    return (instance == null) ? new ArgumentNullException() : new ArgumentException();
}

public void Main()
{
    object something = null;
    throw GetException(something);
}
Denishadenison answered 18/2, 2016 at 0:6 Comment(1)
Do not use throw. Microsoft creates special helpers that do not reduce performance.Ellga
A
1

If null then null; if not then dot

Code using the null conditional can be easily understood by saying that statement to yourself when reading it. So for instance in your example, if foo is null, then it would return null. If it were not null, then it would "dot" and then throw an exception which I don't believe is what you want.

If you're looking for a shorthand way to handle null checks, I would recommend Jon Skeet's answer here and his related blog post on the topic.

Deborah Kurata referenced this saying in this Pluralsight course which I recommend also.

Anthemion answered 18/2, 2016 at 0:29 Comment(1)
Do not link to pages that are protected. What is the code you are referring to?Illyrian
W
1

Using C#10 with Nullable directive enabled I often need to transform the values of type T? into T. For instance I have a property string? ServerUrl in class representing configuration section (it is nullable since it potentially can not be set by user) and I need to pass it as parameter to method taking non-nullable string. It is tedious in many of such cases to handle missing value of nullable type. One possible solution is to use !(null-forgiving) but in case of actual null value it will produce just NullReferenceException. As alternative, in case when you want to have more informative exception, you can define extension methods for verified conversion, one for value types and one for reference types, like the following:

public static class NullableExtensions
{
    public static T ThrowIfNull<T>(
        this T? input, [CallerArgumentExpression("input")] string? description = null)
        where T : struct =>
        input ?? ThrowMustNotBeNull<T>(description);

    public static T ThrowIfNull<T>(
        this T? input, [CallerArgumentExpression("input")] string? description = null)
        where T : class =>
        input ?? ThrowMustNotBeNull<T>(description);

    private static T ThrowMustNotBeNull<T>(string? description) =>
        throw new InvalidOperationException($"{description} must not be null");
}

These methods take optional argument description allowing to capture expressions passed as arguments, using CallerArgumentExpression attribute.

Examples of usage:

string? a = null;
a.ThrowIfNull(); // throws exception with message "a must not be null"

int? b = null;
int? c = 5;
(b + c).ThrowIfNull(); // throws exception with message "b + c must not be null"

.NET Fiddle example

I do not suggest to abuse this approach instead of proper handling of nullable values in strictly-typed manner. You can consider it as way of assertion (or suppressing warnings) that value is set or otherwise developer's error has happened. At the same time you also want to have additional information and you are not considered with runtime performance impact (operator ! in contrast does not have any runtime impact).

Wendelina answered 6/4, 2023 at 6:46 Comment(1)
Really nice IMHO. Maybe add [NotNull] in front of this T? input, and [DoesNotReturn] to method ThrowMustNotBeNull.Craftsman

© 2022 - 2024 — McMap. All rights reserved.