C# 如何在C语言中捕获泛型异常的所有变体#

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();

我想捕获一个泛型异常类的所有变体,我想知道是否有一种不用多个catch块就可以实现的方法。例如,假设我有一个异常类:

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<>))