可以完全重新创建异常吗?

时间:2014-02-28 14:49:42

标签: c# exception reflection system.reflection

this question中的相同想法一致。我需要能够在一个函数中重新创建一个异常,它不会提前知道将传递什么类型的异常。

到目前为止我的代码:

//Code where original exception in created
ArgumentException ex = new ArgumentException(SixteenthsFractional, "Not a recognized architectural string");
RecievingCode(ex, ex.GetType());
throw ex;


public static void RecievingCode(Exception passedException, Type passedExceptionType)
{
    var exception = Activator.CreateInstance(passedExceptionType);
    //Can I cast the passedException to this type?
}

如何重新创建特定异常,就像人在this question的答案中对Child1对象所做的那样?

(这不是系统架构问题。我有理由说明为什么我需要这样做)

3 个答案:

答案 0 :(得分:3)

一个对象有一个类型,该对象总是具有该类型,无论你将它投射到什么类型。即使你的参数是

Exception passedException

它仍然是ArgumentException。该方法只接受“任何异常类型”。您可以安全地将Exception转换回对象的实际类型,但为此,您首先需要知道它的类型:

ArgumentException argEx = passedException as ArgumentException;
if (argEx != null)
{
    ...
}

if (passedException is ArgumentException)
{
    ArgumentException argEx = (ArgumentException)passedException;        
}

但是你不能在类型上switch,所以如果每个异常类型都有一堆不同的功能,这将导致一大堆if / else语句。

答案 1 :(得分:1)

如果使用泛型类型推断,则可以执行以下操作:

public static void RecievingCode<TException>(TException passedException) where TException : Exception
{
    // stuff
}

你会这样称呼:

RecievingCode(ex);

答案 2 :(得分:0)

虽然只能抛出或捕获从Exception派生的类型,但关于这些类型可以执行或包含的内容的规则很少,并且此类规则不足以保证通过任何通用方法的存在可以重新创建任何和所有此类类型的实例 。当然,类型可以被设计为“困难”,虽然大多数类型没有理由这样做,但是不能保证某种类型的创建者不会发现某种设计的某些好处,而这种设计恰好与任何简单的复制不兼容方法

例如,请考虑以下异常衍生的草图:

void SillyException : Exception
{
    SillyException shouldBeThis;
    public SillyException()
    {
      shouldBeThis = this;
    }
    public override String ToString()
    {
      if (shouldBeThis != this) doSometingBad();
      return base.ToString();
    }
}

知道字段shouldBeThis的代码可能能够使用Reflection来设置它,但是没有办法让没有理由怀疑存在变量的代码将其正确地设置为{{1 }}。虽然这个特定的例子当然是高度设计的,但是为什么复制异常可能基本上是不可能的,有各种类似的原因。例如,一个类可能保留一个this变量,该变量保存异常 - 如果有的话 - 由该线程上的类的最后一次尝试操作抛出,并且如果清理失败,它可以构建一个复合异常,将原始异常与清理异常相结合。如果多个异常包含对彼此的引用,则尝试复制不了解不同异常及其关系的异常可能很容易导致对象图破坏,这可能导致尝试检查并报告崩溃发生的事件堆栈溢出。

如果您对将要知道此类设计不是问题的例外情况了解得足够多,那么使用泛型和反射的方法可能是可用的,但这些设计的适用性将取决于您所知道的确切内容你想做什么。