Search code examples
c#noreturn

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


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.


Solution

  • 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.
        }
    }