2016-10-15 6 views

답변

3

고토.

한 가지 방법으로 try-catch와 레거시 오류 처리를 결합 할 수 없습니다. On Error Resume Next을 사용하면 메서드의 코드 한 줄에 고유 한 식별자와 함께 레이블이 지정됩니다. 의사 -C# 코드에서 :

int currentId = 0; 

Label1: 
currentId = 1; 
Line1(); 

Label2: 
currentId = 2; 
Line2(); 

Label3: 
currentId = 3; 
Line3(); 

Exit: 

전체 메서드는 try catch로 래핑됩니다. 예외가 발생하면 캐치 처리기는 currentId을 확인하고 줄의 다음 레이블 (ProjectError이 설정 됨)까지 간단한 goto을 수행합니다.

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

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

마음 당신이 내가 디 컴파일 VB.NET 응용 프로그램이있어 단지 구현 세부 사항은 다음과 같습니다 우리의 경우, 다음과 같이 보일 것입니다. 유일한 계약 상 행동은 기본적으로 "프로젝트 오류를 ​​설정하고 다음 진술을 계속"하는 것으로 끝나는 On Error Resume Next에 정의 된 동작입니다. 여기

0

당신은 갈 :

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 

이 (보충 방법없이)로 컴파일 :

.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 

이 수차은 이것에 리플렉터와 디 컴파일됩니다 :로부터 제외

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(); 
    } 
} 

스위치와 멍청한 것들을 사용한다는 사실, 나는 그 코드가 실제로 무엇을하는지 전혀 모릅니다.