2016-10-15 2 views

Antwort

3

Gehe zu.

Sie können try-catch nicht mit der alten Fehlerbehandlung in einer Methode kombinieren. Wenn Sie On Error Resume Next verwenden, erhält jede einzelne Codezeile in der Methode eine Bezeichnung sowie eine eindeutige Kennung. # -Code in pseudo-C:

int currentId = 0; 

Label1: 
currentId = 1; 
Line1(); 

Label2: 
currentId = 2; 
Line2(); 

Label3: 
currentId = 3; 
Line3(); 

Exit: 

Das gesamte Verfahren wird in einem Try-Catch gewickelt. Wenn die Ausnahmebedingung trifft, prüft der Catch-Handler currentId und führt eine einfache goto zum nächsten Label in Zeile (und ProjectError ist gesetzt). In unserem Fall wäre es etwa so aussehen:

try 
{ 
    ... 
} 
catch (Exception ex) 
{ 
    ProjectData.SetProjectError(ex); 

    if (currentId == 1) goto Label2; 
    if (currentId == 2) goto Label3; 
    if (currentId == 3) goto Exit; 
} 

Wohlgemerkt, dies ist nur eine Implementierung Detail I von decompiling einer VB.NET Anwendung bekam. Das einzige vertragliche Verhalten ist dasjenige, das in On Error Resume Next definiert ist, was im Grunde darauf hinausläuft, "Projektfehler zu setzen und zur nächsten Anweisung fortzufahren".

0

Hier gehen Sie:

Public Sub A() 
End Sub 
Public Sub B() 
End Sub 
Public Sub C() 
End Sub 
Public Sub D() 
End Sub 
Public Sub E() 
End Sub 

Public Sub Test() 
    A() 
    On Error GoTo ErrorHandler 
    B() 
    Exit Sub 
    C() 
    ErrorHandler: 
    D() 
    Resume Next 
    E() 
End Sub 

Compiliert zu (ohne die zusätzlichen Methoden):

.method public static void Test() cil managed 
{ 
    // Code size  201 (0xc9) 
    .maxstack 3 
    .locals init (int32 V_0, 
      int32 V_1, 
      int32 V_2) 
    IL_0000: ldc.i4.1 
    IL_0001: stloc.2 
    IL_0002: call  void VBTest.Program::A() 
    IL_0007: call  void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() 
    IL_000c: ldc.i4.2 
    IL_000d: stloc.0 
    IL_000e: ldc.i4.3 
    IL_000f: stloc.2 
    IL_0010: call  void VBTest.Program::B() 
    IL_0015: leave  IL_00c0 
    IL_001a: ldc.i4.5 
    IL_001b: stloc.2 
    IL_001c: call  void VBTest.Program::C() 
    IL_0021: ldc.i4.6 
    IL_0022: stloc.2 
    IL_0023: call  void VBTest.Program::D() 
    IL_0028: ldc.i4.7 
    IL_0029: stloc.2 
    IL_002a: call  void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() 
    IL_002f: ldloc.1 
    IL_0030: brtrue.s IL_0047 
    IL_0032: ldc.i4  0x800a0014 
    IL_0037: call  class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32) 
    IL_003c: throw 
    IL_003d: ldc.i4.s 9 
    IL_003f: stloc.2 
    IL_0040: call  void VBTest.Program::E() 
    IL_0045: leave.s IL_00c0 
    IL_0047: ldloc.1 
    IL_0048: ldc.i4.1 
    IL_0049: add 
    IL_004a: ldc.i4.0 
    IL_004b: stloc.1 
    IL_004c: switch  ( 
         IL_007d, 
         IL_0000, 
         IL_0007, 
         IL_000e, 
         IL_0015, 
         IL_001a, 
         IL_0021, 
         IL_0028, 
         IL_003d, 
         IL_003d, 
         IL_0045) 
    IL_007d: leave.s IL_00b5 
    IL_007f: ldloc.2 
    IL_0080: stloc.1 
    IL_0081: ldloc.0 
    IL_0082: switch  ( 
         IL_0093, 
         IL_0047, 
         IL_0021) 
    IL_0093: leave.s IL_00b5 
    IL_0095: isinst  [mscorlib]System.Exception 
    IL_009a: ldnull 
    IL_009b: cgt.un 
    IL_009d: ldloc.0 
    IL_009e: ldc.i4.0 
    IL_009f: cgt.un 
    IL_00a1: and 
    IL_00a2: ldloc.1 
    IL_00a3: ldc.i4.0 
    IL_00a4: ceq 
    IL_00a6: and 
    IL_00a7: endfilter 
    IL_00a9: castclass [mscorlib]System.Exception 
    IL_00ae: call  void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception) 
    IL_00b3: leave.s IL_007f 
    IL_00b5: ldc.i4  0x800a0033 
    .try IL_0000 to IL_0095 filter IL_0095 handler IL_00a9 to IL_00b5 
    IL_00ba: call  class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32) 
    IL_00bf: throw 
    IL_00c0: ldloc.1 
    IL_00c1: brfalse.s IL_00c8 
    IL_00c3: call  void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() 
    IL_00c8: ret 
} // end of method Program::Test 

Diese abberation mit Reflektor auf diese dekompilierten wird:

public static void Test() 
{ 
    int num2; 
    try 
    { 
     int num3; 
    Label_0000: 
     num3 = 1; 
     A(); 
    Label_0007: 
     ProjectData.ClearProjectError(); 
     int num = 2; 
    Label_000E: 
     num3 = 3; 
     B(); 
     goto Label_00C0; 
    Label_001A: 
     num3 = 5; 
     C(); 
    Label_0021: 
     num3 = 6; 
     D(); 
    Label_0028: 
     num3 = 7; 
     ProjectData.ClearProjectError(); 
     if (num2 != 0) 
     { 
      goto Label_0047; 
     } 
     throw ProjectData.CreateProjectError(-2146828268); 
    Label_003D: 
     num3 = 9; 
     E(); 
     goto Label_00C0; 
    Label_0047: 
     num2 = 0; 
     switch ((num2 + 1)) 
     { 
      case 1: 
       goto Label_0000; 

      case 2: 
       goto Label_0007; 

      case 3: 
       goto Label_000E; 

      case 4: 
      case 10: 
       goto Label_00C0; 

      case 5: 
       goto Label_001A; 

      case 6: 
       goto Label_0021; 

      case 7: 
       goto Label_0028; 

      case 8: 
      case 9: 
       goto Label_003D; 

      default: 
       goto Label_00B5; 
     } 
    Label_007F: 
     num2 = num3; 
     switch (num) 
     { 
      case 0: 
       goto Label_00B5; 

      case 1: 
       goto Label_0047; 

      case 2: 
       goto Label_0021; 
     } 
    } 
    catch (object obj1) when (?) 
    { 
     ProjectData.SetProjectError((Exception) obj1); 
     goto Label_007F; 
    } 
Label_00B5: 
    throw ProjectData.CreateProjectError(-2146828237); 
Label_00C0: 
    if (num2 != 0) 
    { 
     ProjectData.ClearProjectError(); 
    } 
} 

Abgesehen von den Tatsache, dass es eine Reihe von Schaltern und Gotos verwendet, ich habe keine Ahnung, was dieser Code tatsächlich tut.