你能捕到一个例外<T>哪里有T是什么类型的?

Des*_*tar 34 c# generics exception-handling

我希望能够捕捉WebFaultException<string>到最具体的一个WebFaultException<T>(T是任何其他类型)作为更一般的情况来处理.这可能吗?

try
{
    // throw exception
}
catch (WebFaultException<string> e)
{
    // handle more specific type
}
catch (WebFaultException<T> e)
{
    // handle more general type
}
catch (Exception e)
{
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*ade 14

正如其他答案所述; 你不能直接指定捕获每一个WebFaultException<T>而不知道指定的类型参数,或者捕获它的基类型.

但是,如果您想要捕获所有 WebFaultException事件并根据泛型类型以不同方式处理响应,那么您可以简单地捕获基类型并使用反射来确定使用泛型参数的类型Type.GetGenericArguments().这是一个简单的catch条款,展示你如何去做:

// ...

catch (FaultException ex)
{
    Type exceptionType = ex.GetType();

    if (exceptionType.IsGenericType)
    {
        // Find the type of the generic parameter
        Type genericType = ex.GetType().GetGenericArguments().FirstOrDefault();

        if (genericType != null)
        {
            // TODO: Handle the generic type.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想要一个更深入的例子,我已经上传了一个测试程序来向PasteBin演示.随意看看!


Eri*_*ich 5

我从来没有想过这样的事情,所以我很好奇并做了一个小便笺实现。首先,以下工作:

public class WebFaultException : Exception
{
    public WebFaultException() { }
    public WebFaultException(string message) : base(message) { }
    public WebFaultException(string message, Exception innerException) : base(message, innerException) { }
    protected WebFaultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}

public class WebFaultException<T> : WebFaultException
{
    public WebFaultException() { }
    public WebFaultException(string message) : base(message) { }
    public WebFaultException(string message, Exception innerException) : base(message, innerException) {  }
    protected WebFaultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) {}
}
Run Code Online (Sandbox Code Playgroud)

作为您的异常定义,然后这些测试都通过了:

    [TestMethod]
    public void SpecificGeneric()
    {
        bool hitException = false;
        try
        {
            throw new WebFaultException<string>();
        }
        catch(WebFaultException<string> e)
        {
            hitException = true;
        }

        Assert.IsTrue(hitException);
    }

    [TestMethod]
    public void AnyGeneric()
    {
        bool hitException = false;
        try
        {
            throw new WebFaultException<int>();
        }
        catch (WebFaultException<string> e)
        {
            hitException = false;
        }
        catch (WebFaultException e)
        {
            hitException = true;
        }

        Assert.IsTrue(hitException);
    }
Run Code Online (Sandbox Code Playgroud)

在做你想做的事情方面,有一个问题。在您提供的代码中,WebDefaultException<T>是没有意义的,因为您没有提供 T。但是,您可以像这样(另一个通过的单元测试)解决这个问题(有点笨拙):

    [TestMethod]
    public void CallingGenericMethod()
    {
        Assert.IsTrue(GenericExceptionMethod<int>());
    }

    private bool GenericExceptionMethod<T>()
    {
        bool hitException = false;
        try
        {
            throw new WebFaultException<int>();
        }
        catch (WebFaultException<string> e)
        {
            hitException = false;
        }
        catch (WebFaultException<T> e)
        {
            hitException = true;
        }
        return hitException;
    }
Run Code Online (Sandbox Code Playgroud)

也就是说,如果您处理异常的方法(或类)有一个泛型参数,您实际上可以捕获WebFaultException<T>. 但是,我要提醒一句,这是一件非常奇怪的事情——作为您方法的客户,我被迫传入一种类型,该类型将用于我不关心的任何内容并且是内部的您想要捕获的某些异常的实现细节。

所以,我会说是的,可能。但充其量也很尴尬,也许是不明智的。