Reputation: 340
I am trying to wrap my exception throwing logic into another class so that it is easier to throw custom exceptions. Every class would use either a direct reference to this Thrower class, or an interface, whatever is most appropriate.
I have written a simple class that handles it and it works for the most part, but I have encountered a situation in methods with return types where, even though an exception will always be thrown, the compiler fails to detect it and complains that not all paths return a value.
The following code shows an simplified form of the structure of the Thrower class and any class which would use said Thrower.
public class Thrower
{
public void ThrowException()
{
throw new Exception("Im an exception");
}
}
public class Foo
{
// Does not work, compiler complains about not all paths returning values.
public int ExceptionNotDetected(bool shouldThrow)
{
if (!shouldThrow)
{
return 1;
}
var thrower = new Thrower();
thrower.ThrowException();
}
// Works fine.
public int ExceptionDetected(bool shouldThrow)
{
if (!shouldThrow)
{
return 1;
}
throw new Exception("Im an exception");
}
}
As far as I can see the method that uses the Thrower must either return a value or throw an exception. From that it seems that the method ExceptionNotDetected and ExceptionDetected are functionally equivalent.
Why then does the compiler complain about ExceptionNotDetected?
Edit:
In regards to the design, this was purely for illustration purposes as all I really wanted to do is understand what was happening. I apologize if I didn't clarify this properly in the post description. That being said I appreciate the advice in regards to structure.
Upvotes: 2
Views: 478
Reputation: 2623
Simply because the compiler does not analyse the code inside a function to detect that the function always throw an exception.
C# does not seems to have a "never return" attribute. See: Is there a standard "never returns" attribute for C# functions?
But also, there are no reason to write code that way:
throw new MyExceptionType(my_parameters);
.throw new MyExceptionType::CreateFromThatData(…);
Exception
.static class
with some (static) methods to create desired exception would works.thrower
object and then call a method on it to throw the exception. You know need 2 lines of code to throw an exception instead of one.throw
call inside a function make the code harder to understand and validate. Does thrower.ThrowException
really throw an exception and which one.You are over-complicating your design and your code and as such creating more problems than you solve.
Upvotes: 1
Reputation: 15076
Since c# does not have checked exceptions like Java, rhere is no way the compiler can know that the thrower actually throws.
But you can invert the logic
if (shouldThrow)
{
var thrower = new Thrower();
thrower.ThrowException();
}
return 1;
That way the compiler will assume 1 is returned and that the ThrowException medthod is a regular void which like any other void method might throw and exception.
Upvotes: 3
Reputation: 420
The compiler can only see the return type of the current method, the "ThrowExeption()" method returns nothing (void).
It won't check inside the called method to see if that is going to return an exception or not.
Upvotes: 4