Is there something like [[noreturn]] in C# to indicate the compiler that the method will never return a value?

1.7k Views Asked by At

For some of my code I use a method which looks like this:

public static void Throw<TException>(string message) where TException : Exception
{
    throw (TException) Activator.CreateInstance(typeof(TException), message);
}

and I want to use it like this (simple example):

public int MyMethod()
{
    if(...)
    {
        return 42;
    }

    ThrowHelper.Throw<Exception>("Test");
    // I would have to put "return -1;" or anything like that here for the code to compile.
}

now, obviously, I know that there is no way MyMethod could never return anything, because it will always (indirectly) throw an exception. But of course I get the compiler value "not all paths return a value".

That's why I am asking if there is anything like the C++ [[noreturn]] attribute that I could use to indicate to the compiler that the code is actually valid?


EDIT: The reason for why I want to use a throwing helper class instead of throwing directly or using an exception builder, is this statement:

Members that throw exceptions are not getting inlined. Moving the throw statement inside the builder might allow the member to be inlined.

I actually measured the code and I would benefit (a little) from inlining, so I would be happy to find ways to achieve this.

3

There are 3 best solutions below

4
On BEST ANSWER

The normal way of doing this is to throw an exception with no branching. Something like this:

public int MyMethod()
{
    //Other code here.

    throw new InvalidOperationException();
}

I actually thought of a way to do what you want:

public class Thrower
{
    public static TRet Throw<TException, TRet>(string message) where TException : Exception
    {
        throw (TException)Activator.CreateInstance(typeof(TException), message);
    }

    public int MyMethod()
    {
        if (new Random().Next() == 2)
        {
            return 42;
        }

        return Throw<Exception, int>("Test");
        // I would have to put "return -1;" or anything like that here for the code to compile.
    }
}
0
On

No, there is no way to get the compiler to understand that the method will always throw an exception and thus marks the end of code execution.

You are forced to

  1. Call the method as the very last statement of your method (if your method is void)
  2. Or add the necessary flow control statements after the method call to end the execution, even though the code will never actually be executed.

As you've pointed out, in a method with a return type, you will be forced to write the appropriate return X; statement where X is an appropriate value for the return type of your method.

There is no way around this.

2
On

Bit late, but seems relevant:

Since Net Core 3.0 there is the DoesNotReturn attribute in System.Diagnostics.CodeAnalysis

Reference: learn.microsoft.com