【问题标题】:Extension method to Exception requiring dynamic generic type需要动态泛型类型的异常的扩展方法
【发布时间】:2010-12-03 18:53:10
【问题描述】:

以前曾以不同的方式提出过这个问题,但答案对我没有帮助,因为(1)我无法控制内置的 Exception 类,以及(2)Activator.CreateInstance() 返回一个对象/实例,我需要一个真正的动态类型。

我正在尝试创建一个扩展方法,允许我根据我捕获的异常从我的 WCF 服务中抛出一个FaultException。例如:

try {
    ...
}
catch (ArgumentNullException exc) {
    throw new FaultException<ArgumentNullException>(exc);
}

直截了当。但如果我想以一般方式扩展它,我会使用扩展类,例如:

try {
    ...
}
catch (Exception exc) {
    exc.ThrowFaultException();
}

我比较纠结的地方,当然是扩展方法的实现:

public static void ThrowFaultException(this Exception exc) {

    //  Gives me the correct type...
    Type exceptionType = exc.GetType();

    //  But how the heck do I use it?
    throw new FaultException<???>(exc);
}

herehere 的答案无济于事。有什么想法吗?

【问题讨论】:

  • 为什么你不能把Activator.CreateInstance()的返回值转换成Exception?它仍然会作为它的实际类型被抛出,不是吗?
  • 从自定义代码中抛出异常而不是从一些通用方法中抛出异常是个好主意。这将有助于 VS.Net 和其他代码分析器(包括您的同行)检测无法访问的代码和相关问题。
  • BR/DP> 我在测试该解决方案时发现调用者在通用 catch (Exception exc){} 处理程序下捕获了异常,而不是 FaultException
  • DK> 你能详细说明一下吗?
  • James B> 这只是一般考虑,与问题没有直接关系......想象一下,后来初级开发人员在每个异常处理结束时添加了日志记录。在您的第一个带有“throw”的代码 sn-p 中,编译器会立即警告他 Log.LogError() 调用不能放在 throw 语句之后,因为它将无法访问;事实上,开发人员甚至不太可能尝试这样做。在使用 2nd sn-p 的情况下,它对开发人员来说更加晦涩难懂,并且编译器没有帮助。 HTH。

标签: c# wcf generics exception exception-handling


【解决方案1】:

试试这个:

public static void ThrowFaultException<TException>(this TException ex) where TException : System.Exception
{
    throw new FaultException<TException>(ex);
}

【讨论】:

  • 完美运行!!正是我想要的:)
  • 我总是忘记泛型的美丽!
【解决方案2】:
   public static void ThrowFaultException(this Exception exc)
    {
        //  Gives me the correct type...
        Type exceptionType = exc.GetType();
        var  genericType = typeof(FaultException<>).MakeGenericType(exceptionType);
        //  But how the heck do I use it?
        throw (Exception)Activator.CreateInstance(genericType, exc);
    }

【讨论】:

    【解决方案3】:

    您不需要将 Activator.CreateInstance 返回的对象强制转换为 FaultException> 来抛出它。将其转换为 Exception 就足够了:

    var type = typeof(FaultException<>).MakeGenericType(exc.GetType());
    
    throw (Exception)Activator.CreateInstance(type, exc);
    

    我不会在 ThrowFaultException 中抛出异常:

    try
    {
        ...
    }
    catch (Exception e)
    {
        throw e.WrapInFaultException();
    }
    
    public static Exception WrapInFaultException(this Exception e)
    {
        var type = typeof(FaultException<>).MakeGenericType(e.GetType());
    
        return (Exception)Activator.CreateInstance(type, e);
    }
    

    【讨论】:

    • 我只是想发布这个,但他如何将 exc 作为参数传递给 FaultException 的构造函数? CreateInstance 是否允许这样做?
    • @Pandincus:我还没有测试过,但我相信上面显示的对Activator.CreateInstance(Type, Object[]) 的调用应该可以正常工作。
    • 没关系,我看到您为此编辑了答案。巧妙的把戏!
    • 如果我这样做,客户端会捕获一般异常,而不是 FaultException : (
    猜你喜欢
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多