C# 如何在C语言中捕获泛型异常的所有变体#
我想捕获一个泛型异常类的所有变体,我想知道是否有一种不用多个catch块就可以实现的方法。例如,假设我有一个异常类:C# 如何在C语言中捕获泛型异常的所有变体#,c#,generics,exception,C#,Generics,Exception,我想捕获一个泛型异常类的所有变体,我想知道是否有一种不用多个catch块就可以实现的方法。例如,假设我有一个异常类: public class MyException<T> : Exception { public string MyProperty { get; } public MyException(T prop) : base(prop.ToString()) { MyProperty = prop?.ToString();
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
但它不是很干净,这意味着我无法访问MyProperty
我对该问题的一般解决方案感兴趣,但在我的情况下,通用异常是在第三方库中定义的,如下所述,该库为该问题添加了一些附加约束。使MyException
实现一个接口,并按接口类型检查异常
接口:
public interface IMyException
{
string MyProperty { get; }
}
实现接口的泛型类:
public class MyException<T> : Exception, IMyException
{
public string MyProperty { get; }
public MyException(T prop)
{
MyProperty = prop?.ToString();
}
}
同样可以通过创建一个继承自
Exception
的基类,而不是从该基类派生MyException
来实现
catch(MyException ex)
类,因为它需要一个类型
最好是创建基类或接口,捕获它并从中获取类型
关于如何获取类型并执行此操作,已经有一个答案。如果T:Value是Valuetype,则此实现将装箱并取消装箱。。。但是关于利用率,您可以通过尝试装箱/取消装箱的次数来控制性能影响
public class MyException<T> : MyException
{
public T Prop => (T)base.Prop;
public MyException(T prop) : base(prop)
{
}
}
public class MyException : Exception
{
protected object Prop { get; }
public MyException(object prop)
{
Prop = prop;
}
}
此实现将异常类型的处理委托从T/C的上下文中抽象出来。。。这可能有点太冒险了,但最酷的是,您可以根据重用范围和使用上下文注入不同的处理程序
public interface IExceptionHandler
{
object Handle(Exception ex);
void RegisterExceptionTypeHandler<T>(Func<T,object> handlerDelegate) where T : Exception;
}
如果您的
类型
来自泛型,则测试为:
Type = typeof(something);
t.GetGenericTypeDefinition()==typeof(MyException<>);
因此,这适用于任何现有的泛型,但您需要知道此测试的继承级别,或者遍历所有基类型
所以你可以这样做:
catch(Exception ex) when (ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>))
catch(异常ex)when(ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException))
我不确定它在这里是否值得一个接口-只要在Exception
和MyException
之间有一个非泛型基类就可以了。此外,OP仍然无法访问泛型属性(不使用反射)我想这才是真正的问题。这是一个很好的答案,我投了更高的票——不幸的是,这并不能解决我的具体问题,因为通用异常在第三方库中,所以我无法编辑它。
public class MyException<T> : MyException
{
public T Prop => (T)base.Prop;
public MyException(T prop) : base(prop)
{
}
}
public class MyException : Exception
{
protected object Prop { get; }
public MyException(object prop)
{
Prop = prop;
}
}
try {
...
} catch(MyException e) {
...
}
public interface IExceptionHandler
{
object Handle(Exception ex);
void RegisterExceptionTypeHandler<T>(Func<T,object> handlerDelegate) where T : Exception;
}
handler.RegisterExceptionTypeHandler<MyException<int>>(ex => ...);
handler.RegisterExceptionTypeHandler<MyException<string>>(ex => ...);
try {
...
}catch(Exception ex)
{
...any validation
return exceptionHandler.Handle(ex)
}
Type = typeof(something);
t.GetGenericTypeDefinition()==typeof(MyException<>);
ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>);
catch(Exception ex) when (ex.GetType.BaseType.GetGenericTypeDefinition()==typeof(MyException<>))