[英]Passing List of Exception Types as type parameter to generic method
我正在尝试编写一个通用的辅助方法,该方法将调用方法并处理异常(如果有)。
该方法应该能够接受可接受的Exception
类型的List
,并以特定方式处理它们。 对于其他类型的异常,它将以不同的方式处理。
这是该方法的非常简化的版本
public static TResult InvokeMethod<TResult, TAllowedException>
(Func<TResult> func) where TAllowedException : Exception
{
try
{
return func();
}
catch (Exception ex)
{
if (ex is TAllowedException) //do something
return default(TResult);
else //do something else
throw;
}
}
在这里,我将允许的Exception Type指定为TAllowedException
。 这很好。 但是,这仅接受一个Exception_Type
。 我该如何传递List<Exception_Type>
?
您不能将类型列表作为类型参数传递给泛型方法。
为什么不简单地将类型的集合作为常规参数传递呢?
public static TResult InvokeMethod<TResult>
(Func<TResult> func, ICollection<Type> ignoredExceptions)
{
try
{
return func();
}
catch (Exception ex)
when (ignoredExceptions != null &&
ignoredExceptions.Any(t => t.IsAssignableFrom(ex.GetType())))
{
return default(TResult);
}
}
如果有人传递的Type
也不例外,则不会发生任何不良情况。 我认为没有必要对其进行验证。 该方法仍将正常工作-集合中的异常将被忽略。
调用InvokeMethod(func, new Type[] { typeof(Int32) })
的预期行为是什么? func
将被执行,并且如果它引发一个Int32
异常,则将返回默认结果。 func
绝不会抛出Int32
异常,因此它已经可以像这样工作,而无需验证ignoredExceptions
。
BTW不需要将arg
作为参数传递。 您可以使用lambda捕获闭包中的arg
- () => func(arg)
。 这将适用于任何数量的参数。
编辑
如果您真的想在编译时限制类型,则必须创建自己的集合,并使用一些奇怪的通用Add
方法:
public class ExceptionCollection : IEnumerable<Type>
{
private readonly List<Type> _exceptions = new List<Type>();
public void Add<T>() where T : Exception => _exceptions.Add(typeof(T));
public IEnumerator<Type> GetEnumerator() => _exceptions.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_exceptions).GetEnumerator();
}
此类的最大缺点是,它不适用于集合初始值设定项。
也有一种方法使其也可以与集合初始化程序一起使用。 初始化程序需要一个带有一个参数的Add
方法,但是它们将很高兴地与泛型Add<T>(T item)
方法一起工作。
public void Add<T>(T item) where T : Exception => _exceptions.Add(typeof(T));
使用它也有些棘手。 我们当然可以传递异常的实例,但是仅创建实例来获取其类型毫无意义。 我们可以使用强制类型转换或default(T)
来传递强类型的null
:
new ExceptionCollection { default(ArgumentNullException), default(ArgumentException) };
我仍然认为在这种特殊情况下,不必验证类型的集合。 在其他情况下,如果有必要限制类型的集合,那么上述解决方案就可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.