Search code examples
c#.netnullablenull-coalescing-operator

Is it possible to use operator ?? and throw new Exception()?


I have a number of methods doing next:

var result = command.ExecuteScalar() as Int32?;
if(result.HasValue)
{
   return result.Value;
}
else
{
   throw new Exception(); // just an example, in my code I throw my own exception
}

I wish I could use operator ?? like this:

return command.ExecuteScalar() as Int32? ?? throw new Exception();

but it generates a compilation error.

Is it possible to rewrite my code or there is only one way to do that?


Solution

  • For C# 7

    In C# 7, throw becomes an expression, so it's fine to use exactly the code described in the question.

    For C# 6 and earlier

    You can't do that directly in C# 6 and earlier - the second operand of ?? needs to be an expression, not a throw statement.

    There are a few alternatives if you're really just trying to find an option which is concise:

    You could write:

    public static T ThrowException<T>()
    {
        throw new Exception(); // Could pass this in
    }
    

    And then:

    return command.ExecuteScalar() as int? ?? ThrowException<int?>();
    

    I really don't recommend that you do that though... it's pretty horrible and unidiomatic.

    How about an extension method:

    public static T ThrowIfNull(this T value)
    {
        if (value == null)
        {
            throw new Exception(); // Use a better exception of course
        }
        return value;
    }
    

    Then:

    return (command.ExecuteScalar() as int?).ThrowIfNull();
    

    Yet another alternative (again an extension method):

    public static T? CastOrThrow<T>(this object x) 
        where T : struct
    {
        T? ret = x as T?;
        if (ret == null)
        {
            throw new Exception(); // Again, get a better exception
        }
        return ret;
    }
    

    Call with:

    return command.ExecuteScalar().CastOrThrow<int>();
    

    It's somewhat ugly because you can't specify int? as the type argument...