Asking a Generic Method to Throw Specific Exception Type on FAIL

前端 未结 5 978
深忆病人
深忆病人 2021-02-08 06:32

Right, I know I am totally going to look an idiot with this one, but my brain is just not kicking in to gear this morning.

I want to have a method where I can sa

相关标签:
5条回答
  • 2021-02-08 06:57

    You can almost do it like this:

    static void TestException<E>(string message) where E : Exception, new()
    {
        var e = new E();
        e.Message = message;
        throw e;
    }
    

    However, that doesn't compile because Exception.Message is read only. It can only be assigned by passing it to the constructor, and there's no way to constrain a generic type with something other than a default constructor.

    I think you'd have to use reflection (Activator.CreateInstance) to "new up" the custom exception type with the message parameter, like this:

    static void TestException<E>(string message) where E : Exception
    {
        throw Activator.CreateInstance(typeof(E), message) as E;
    }
    

    Edit Oops just realised you're wanting to return the exception, not throw it. The same principle applies, so I'll leave my answer as-is with the throw statements.

    0 讨论(0)
  • 2021-02-08 07:02

    I think seeing as all exceptions should have a parameterless constructor, and have the Message property, so the following should work:

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        ExType ex = new ExType();
        ex.Message = message;
        return ex;
    }
    

    Edit: OK, Message is read only, so you'll have to hope the class implements the Exception(string) constructor instead.

    static ExType TestException<ExType>(string message) where ExType:Exception
    {
        return new ExType(message);
    }
    
    0 讨论(0)
  • 2021-02-08 07:09

    The only issue with the solution is that it is possible to create a subclass of Exception which does not implement a constructor with a single string parameter, so the MethodMissingException might be thrown.

    static void TestException<E>(string message) where E : Exception, new()
    {
        try 
        {
          return Activator.CreateInstance(typeof(E), message) as E;
        } 
        catch(MissingMethodException ex) 
        {
          return new E();
        }
    }
    
    0 讨论(0)
  • 2021-02-08 07:11

    Have you tried, instead:

    static T TestException<Exception>(string message)
    {}
    

    because I have a feeling that putting in the generic constraint is not necessary as all throwable exceptions must inherit from System.Exception anyway.

    Remember that generics do accept inherited types.

    0 讨论(0)
  • 2021-02-08 07:21

    I have been instantiating inline the type of exception I want to throw, like this:

    if (ItemNameIsValid(ItemName, out errorMessage))
        throw new KeyNotFoundException("Invalid name '" + ItemName + "': " + errorMessage);
    if (null == MyArgument)
        throw new ArgumentNullException("MyArgument is null");
    
    0 讨论(0)
提交回复
热议问题