2017-06-02 41 views
0
try {...} 
catch (InvalidDataException ex){...} 

可以捕获在try块中引发的InvalidDataException类的任何实例。如何捕获特定异常实例而不是特定异常类的任何实例?

try块有可能包含几个可以引发InvalidDataException类实例的地方时,是否可以捕获特定实例?

谢谢。

+0

有几种方法可以做到这一点 - 多个尝试块,抛出不同的异常类型,过滤消息 - 但这对我来说似乎是一个XY问题。你能否提供一个更完整的例子来说明你想要做的事情? –

+0

通用异常与自定义异常类?如果它的泛型没有办法区分哪个实例,唯一的方法是创建自定义的Exception类,该类从具有特定标志或枚举的'InvalidDataException'继承,当发生异常时,将该InvalidDataException与所述枚举。 – t0mm13b

+0

@BJ:我期待一些方法来抛出一个异常,在一个测试方法的单元测试方法。所以我在'try'块中调用了其他方法,并且需要捕获该方法可能引发的任何异常。但是我不能排除是否可以从'try'块中的其他代码行抛出同一类的另一个异常,所以我需要区分抛出哪个异常实例,并且只捕获正在测试的方法抛出的异常。 – Tim

回答

1

基本上你可以做类似

try {...} 
catch (InvalidDataException ex) 
{ 
    if (ex == myInstance) { 
     // do something 
    } else { 
     throw; 
    } 
} 

但我会强烈建议反对。您不应该使用异常来控制程序流。

+0

这不需要'myInstance'是一个在'try'块之外声明的异常,甚至在它被提升之前吗?这似乎很奇怪。 –

+0

@BJMyers是的,这就是为什么整个想法很糟糕。 – Adrian

0

您可以通过使用堆栈跟踪识别它:

var stackTrace = new StackTrace(exception, true); 

然后,你可以调用帧(或帧的阵列),并使用其属性:

var methodThatCalled = stackTrace.GetFrames()[0].GetMethod().Name; 
1

如果我理解正确的话 - 你有一个try块。在try区块内有几个类似的操作可能会导致InvalidDataException。你想抓住一些但不抓住别人。

正如所暗示的,这可能是一个XY问题,但这里是如何从字面上做你在C#7中所说的话。我不推荐这个,只是从字面上回答这个问题。

bool catching = false; 
try 
{ 
    catching = true; 
    // now exceptions are caught in the catch block. 

    catching = false 
    // now exceptions aren't caught - they are thrown to the calling method. 

} 
catch (InvalidDataException ex) when (catching) 
{ 

} 
1

这是一个简单的例子

[Serializable] 
    public class MyException : Exception 
    { 
     public MyException() { } 
     public MyException(string message) : base(message) { } 
     public MyException(string message, Exception inner) : base(message, inner) { } 

     protected MyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } 
    } 

    class Program { 
     static void Main(string[] args) { 
      try{ 
       throw new MyException("Whoops#1"); 
       //throw new MyException("Fubar#2"); 
      }catch(MyException myEx){ 
       string aExMsg = myEx.Message; 
       if (aExMsg.Contains("#1")){ 
        Console.WriteLine("Whoops was caught"); 
       } 
       if (aExMsg.Contains("#2")){ 
        Console.WriteLine("Fubar was caught"); 
       } 
      }catch (Exception ex){ 
       throw; 
      } 
      Console.Write("Press <ENTER> to continue..."); 
      Console.ReadLine(); 
     } 
    } 

取消对线//throw new MyException("Fubar#2");并运行它,该catchMyException意愿捕获错误,检查Message类的内容,寻找一个特定线索,从而可以得到一个实例。

但是,必须指出的是,这并不是处理异常,或者通过这样做来控制代码流的好方法。确定它是什么样的时候,不关心甚至走下坡路 - 为什么?在那里花费的时间太多了!只要看看Message部分的线索就可以了。

例外情况,是出于某种原因,当出现错误情况时,两个结果 - 抓住它们或者悄悄丢弃(坏!)。

查看上面的示例代码,如果这是某种形状或形式的处理数据的一部分,它会影响即将执行的依赖类或方法吗?

为了即将执行的依赖类或方法的好处,以这种方式设置了一对行程开关标志,以使得当进一步的代码被执行时;它会看到之前设置的行程开关标志,跳过一堆代码,知道之前发生了错误,会使事情变得更糟。

最后,优雅地记录下来,通知运营商只需在运营商看到的某个弹出窗口或组件中使用ERROR这个词,它就会给他们一个不需要的恐慌和压力。