2012-06-21 17 views
9

C này # mã không cần thiết:Tại sao Does The Compiler Thêm Một Local Variable

private void LoadAssignments(AssignmentType assignmentType, Collection<Assignment> assignments) 
    { 
     bool flag; 
     DataTable lessons = this.GetResults(assignmentType); 
     try 
     { 
      IEnumerator enumerator = lessons.Rows.GetEnumerator(); 
      try 
      { 
       while (true) 
       { 
        flag = enumerator.MoveNext(); 
        if (!flag) 
        { 
         break; 
        } 
        DataRow row = (DataRow)enumerator.Current; 
       } 
      } 
      finally 
      { 
       IDisposable disposable = enumerator as IDisposable; 
       flag = disposable == null; 
       if (!flag) 
       { 
        disposable.Dispose(); 
       } 
      } 
     } 
     finally 
     { 
      flag = lessons == null; 
      if (!flag) 
      { 
       lessons.Dispose(); 
      } 
     } 
    } 

sản xuất CIL này (NET 4)

.method private hidebysig 
    instance void LoadAssignments (
     valuetype TTReporterCore.AssignmentType assignmentType, 
     class [mscorlib]System.Collections.ObjectModel.Collection`1<valuetype TTReporterCore.Assignment> assignments 
    ) cil managed 
{ 
    .locals init (
     [0] bool flag, 
     [1] class [System.Data]System.Data.DataTable lessons, 
     [2] class [mscorlib]System.Collections.IEnumerator enumerator, 
     [3] class [System.Data]System.Data.DataRow row, 
     [4] class [mscorlib]System.IDisposable disposable, 
     [5] bool flag1 
    ) 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ldarg.1 
    IL_0003: call instance class [System.Data]System.Data.DataTable TTReporterCore.TTReader::GetResults(valuetype TTReporterCore.AssignmentType) 
    IL_0008: stloc.1 
    .try 
    { 
     IL_0009: nop 
     IL_000a: ldloc.1 
     IL_000b: callvirt instance class [System.Data]System.Data.DataRowCollection [System.Data]System.Data.DataTable::get_Rows() 
     IL_0010: callvirt instance class [mscorlib]System.Collections.IEnumerator [System.Data]System.Data.InternalDataCollectionBase::GetEnumerator() 
     IL_0015: stloc.2 
     .try 
     { 
      IL_0016: nop 
      IL_0017: br.s IL_0038 
      .loop 
      { 
       IL_0019: nop 
       IL_001a: ldloc.2 
       IL_001b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() 
       IL_0020: stloc.0 
       IL_0021: ldloc.0 
       IL_0022: stloc.s flag1 
       IL_0024: ldloc.s flag1 
       IL_0026: brtrue.s IL_002b 

       IL_0028: nop 
       IL_0029: br.s IL_003d 

       IL_002b: ldloc.2 
       IL_002c: callvirt instance object [mscorlib]System.Collections.IEnumerator::get_Current() 
       IL_0031: castclass [System.Data]System.Data.DataRow 
       IL_0036: stloc.3 
       IL_0037: nop 

       IL_0038: ldc.i4.1 
       IL_0039: stloc.s flag1 
       IL_003b: br.s IL_0019 
      } 

      IL_003d: nop 
      IL_003e: leave.s IL_0062 
     } 
     finally 
     { 
      IL_0040: nop 
      IL_0041: ldloc.2 
      IL_0042: isinst [mscorlib]System.IDisposable 
      IL_0047: stloc.s disposable 
      IL_0049: ldloc.s disposable 
      IL_004b: ldnull 
      IL_004c: ceq 
      IL_004e: stloc.0 
      IL_004f: ldloc.0 
      IL_0050: stloc.s flag1 
      IL_0052: ldloc.s flag1 
      IL_0054: brtrue.s IL_0060 

      IL_0056: nop 
      IL_0057: ldloc.s disposable 
      IL_0059: callvirt instance void [mscorlib]System.IDisposable::Dispose() 
      IL_005e: nop 
      IL_005f: nop 

      IL_0060: nop 
      IL_0061: endfinally 
     } 

     IL_0062: nop 
     IL_0063: nop 
     IL_0064: leave.s IL_007e 
    } 
    finally 
    { 
     IL_0066: nop 
     IL_0067: ldloc.1 
     IL_0068: ldnull 
     IL_0069: ceq 
     IL_006b: stloc.0 
     IL_006c: ldloc.0 
     IL_006d: stloc.s flag1 
     IL_006f: ldloc.s flag1 
     IL_0071: brtrue.s IL_007c 

     IL_0073: nop 
     IL_0074: ldloc.1 
     IL_0075: callvirt instance void [System]System.ComponentModel.MarshalByValueComponent::Dispose() 
     IL_007a: nop 
     IL_007b: nop 

     IL_007c: nop 
     IL_007d: endfinally 
    } 

    IL_007e: nop 
    IL_007f: ret 
} 

Tại sao MSIL thêm flag1, tiếp tục thực hiện cùng một logic để thiết lập cờ, thiết lập flag1 để cờ và cuối cùng, kiểm tra! flag1. Điều này có vẻ như một trình biên dịch không hiệu quả với tôi.

CẬP NHẬT: Tôi đã sử dụng JustDecompile của Telerik và trong khi kết quả khác với ILDASM, boolean bổ sung vẫn được tạo trong chế độ gỡ lỗi.

Ngoài ra, tôi đã sửa đổi mã bằng cách xóa hoàn toàn boolean và phiên bản gỡ lỗi vẫn thêm boolean. Tôi thực sự tìm kiếm lý do tại sao trình biên dịch thực hiện điều này.

+3

Điều gì sẽ xảy ra nếu bạn biên dịch trong Chế độ phát hành thay vì chế độ Gỡ lỗi? –

+0

Cùng một kết quả trong chế độ phát hành. – kakridge

+0

Tên biến thực tế tương tự như "CS $ 4 $ 0000", không phải "flag1". Và nó * không * được tối ưu hóa trong bản phát hành bản phát hành. Bạn không chắc chắn những gì bạn đang sử dụng disassembler nhưng nó âm thanh borken. Sử dụng ildasm.exe để xem điều này. –

Trả lời

2

Có vẻ như một địa phương tạm thời được tạo để giữ kết quả so sánh (ví dụ: dùng một lần == vô giá trị).

Cố ví dụ này:

class Program 
{ 
    static void Main() 
    { 
     if (1 == 1) return; 
    } 
} 

..is sản xuất IL sau trên hộp của tôi (Microsoft (R) Visual C# 2010 Compiler phiên bản 4.0.30319.1):

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 1 
    .locals init (bool V_0) 
    IL_0000: nop 
    IL_0001: ldc.i4.0 
    IL_0002: stloc.0 
    IL_0003: br.s  IL_0005 
    IL_0005: ret 
} 

V_0 địa phương là được tạo ra, mặc dù nó thực sự không được sử dụng. Tôi tin rằng đó là một sự tối ưu hóa rõ ràng ngay cả đối với việc biên dịch tối ưu hóa 'không' :) .. nhiều khả năng hơn: tất cả các mã cần thiết được tạo ra để cho phép gỡ lỗi. Tôi không biết làm thế nào nó có thể được sử dụng trong một phiên gỡ lỗi, nhưng đó là dự đoán tốt nhất của tôi.

Khi được biên dịch tối ưu hóa (tức là cấu hình phát hành) Tôi không thấy địa phương bổ sung.

0

Khi tôi viết một chương trình tương tự, biến phụ không xuất hiện trong chế độ phát hành. Cùng quan điểm lắp ráp, sửa lỗi cho thấy thêm phúc bộ biến ([ebp-44h]) và phát hành không:

gỡ lỗi:

enter image description here

phát hành:

enter image description here

+4

Dường như bạn đã bỏ qua từ đầu tiên của tiêu đề. –

Các vấn đề liên quan