Reputation: 182
Okay, I need to be able to pass in an anonymous method and an exception type to check against. Here's a stripped out version of what I'm trying now
public T MyMethod<T,E>(Func<T> action, E ExceptionType, int param2, int param3 = 3) where E : Exception
{
try
{
//Some code here
}
catch(Exception ex)
{
if(ex.GetType() == typeof(ExceptionType))
{
//Do something
}
else
{
//Do something else
}
}
}
I'm trying to call the method like this
Retry(()=>OtherMethod("input"),typeof(Exception),33,9);
And I keep getting the same error. "The type arguments for method X cannot be inferred from the usage. Try specifying the type arguments explicitly"
The idea is to check to see if an exception thrown inside MyMethod matches the type of exception that was passed in as the second argument, and take an action based on whether it does or not. I can't just hard code the type because this is to be used in a library and the type of exception to check for will not always be the same.
What can I change to accomplish what I am trying?
EDIT: I've also tried to call the method like so..
Retry(()=OtherMethod(),new Exception(),10,10)
But I get the same issue.
Upvotes: 0
Views: 290
Reputation: 660513
Servy's answer is correct. Some thoughts on how to fix your problem:
First option: take a type:
public T MyMethod<T>(Func<T> action, Type exceptionType)
{
...
catch(Exception ex)
{
if(ex.GetType() == exceptionType)
Second option: take a type parameter:
public T MyMethod<T, E>(Func<T> action)
where E : Exception
{
...
catch(Exception ex)
{
if(ex.GetType() == typeof(E))
This solution has a problem: there is no basis upon which to infer the type parameter E, so the caller cannot use type inference.
A third option:
public T MyMethod<T>(Func<T> action, Exception example)
{
...
catch(Exception ex)
{
if(ex.GetType() == example.GetType())
Yuck. Passing in an object just so that you can extract its type is weird.
All solutions have a problem with the comparison:
if(ex.GetType() == exceptionType)
if(ex.GetType() == typeof(E))
if(ex.GetType() == example.GetType())
This is problematic; suppose the exception type is AnimalException and ex is of type GiraffeException, which derives from AnimalException. These tests will fail, since the types are not equal, and that's an equality check. If you go with this approach, consider whether an exact match of types is what you really want.
I was hoping to be able to pass in a Type but have it restricted to only types that inherit from Exception
Oh, well, why didn't you say so?
public T MyMethod<T>(Func<T> action, Type exceptionType)
{
if (!typeof(Exception).IsAssignableFrom(exceptionType))
throw new ArgumentException("exceptionType must represent a type derived from or equal to Exception");
Easy peasy. Don't try to capture everything in the type system. Your callers who violate this rule will discover it quickly and fix the problem.
Upvotes: 1
Reputation: 203840
The expression typeof(Exception)
evaluates to Type
. Type
doesn't meet the criteria for the type that it needs to extend Exception
.
The method is expecting you to pass an instance of some kind of exception, not a Type
object that is an exception.
If you want to pass the type itself, don't try to infer the generic arguments - explicitly specify the exception as the generic type argument. If you want to pass a Type
, write the method to accept one.
Upvotes: 2