好的,我需要能够传入匿名方法和异常类型来进行检查。这是我现在正在尝试的一个剥离版本
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
}
}
}
我正试图像这样调用这个方法
Retry(()=>OtherMethod("input"),typeof(Exception),33,9);
我一直得到同样的错误。 “无法从用法中推断出方法X的类型参数。请尝试明确指定类型参数”
我们的想法是检查MyMethod中抛出的异常是否与作为第二个参数传入的异常类型匹配,并根据它是否执行操作来执行操作。我不能只对代码进行硬编码,因为这将在库中使用,并且要检查的异常类型并不总是相同。
我可以改变什么来完成我正在尝试的东西?
编辑: 我也试过这样调用这个方法..
Retry(()=OtherMethod(),new Exception(),10,10)
但我得到同样的问题。
答案 0 :(得分:2)
表达式typeof(Exception)
的计算结果为Type
。 Type
不符合扩展Exception
所需类型的条件。
该方法期望您传递某种异常的实例,而不是作为异常的Type
对象。
如果要传递类型本身,请不要尝试推断泛型参数 - 将异常显式指定为泛型类型参数。如果要传递Type
,请编写接受方法。
答案 1 :(得分:1)
Servy的回答是正确的。关于如何解决问题的一些想法:
第一个选项:采取类型:
public T MyMethod<T>(Func<T> action, Type exceptionType)
{
...
catch(Exception ex)
{
if(ex.GetType() == exceptionType)
第二个选项:采用类型参数:
public T MyMethod<T, E>(Func<T> action)
where E : Exception
{
...
catch(Exception ex)
{
if(ex.GetType() == typeof(E))
此解决方案存在一个问题:没有依据可以推断出类型参数E,因此调用者不能使用类型推断。
第三种选择:
public T MyMethod<T>(Func<T> action, Exception example)
{
...
catch(Exception ex)
{
if(ex.GetType() == example.GetType())
呸。传入一个对象只是为了让你可以提取它的类型很奇怪。
所有解决方案都存在比较问题:
if(ex.GetType() == exceptionType)
if(ex.GetType() == typeof(E))
if(ex.GetType() == example.GetType())
这是有问题的;假设异常类型是AnimalException,而ex是GiraffeException类型,它派生自AnimalException。这些测试将失败,因为类型不是相等,并且这是相等检查。如果您采用这种方法,请考虑类型的完全匹配是否是您真正想要的。
我希望能够传入一个Type,但只限于从Exception继承的类型
哦,好吧,你为什么不这么说?
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");
容易腻。不要试图捕获类型系统中的所有内容。违反此规则的呼叫者将快速发现并解决问题。