] Сгенерированные различия IL для VB.NET и C # [

] [

] Сегодня я играл с Entity Framework и прочитал, что сгенерированный IL для C # отличается от VB.NET для следующего кода : [

] [

] VB.NET: [

] [
Dim ctx As New TravelEntities

Sub Main()
    CallContext()
    CallContext()
    CallContext()
End Sub

Private Sub CallContext()

    Dim someCustomer = From x In ctx.Customer
            Where x.CustomerId.Equals(5)
            Select x
    Console.WriteLine(someCustomer.Count())
End Sub
] [

] C #: [

] [
    private static TravelEntities ctx = new TravelEntities();

    static void Main(string[] args)
    {
        CallContext(); 
        CallContext(); 
        CallContext();
    }

    private static void CallContext()
    {
        var someCustomer = from x in ctx.Customer
                           where x.CustomerId.Equals(5)
                           select x;
        Console.WriteLine(someCustomer.Count());
    }
] [

] Они создают следующий IL: [

] [

] VB: [

] [
.method private static void  CallContext() cil managed
{
  // Code size       195 (0xc3)
  .maxstack  7
  .locals init ([0] class [System.Core]System.Linq.IQueryable`1<class VB_IL_Difference.Customer> someCustomer,
           [1] class [System.Core]System.Linq.Expressions.ParameterExpression VB$t_ref$S0,
           [2] class [System.Core]System.Linq.Expressions.Expression[] VB$t_array$S0,
           [3] class [System.Core]System.Linq.Expressions.ParameterExpression[] VB$t_array$S1,
           [4] class [System.Core]System.Linq.Expressions.ParameterExpression VB$t_ref$S1,
           [5] class [System.Core]System.Linq.Expressions.ParameterExpression[] VB$t_array$S2)
  IL_0000:  nop
  IL_0001:  ldsfld     class VB_IL_Difference.TravelEntities VB_IL_Difference.Module1::ctx
  IL_0006:  callvirt   instance class [System.Data.Entity]System.Data.Objects.ObjectSet`1<class VB_IL_Difference.Customer> VB_IL_Difference.TravelEntities::get_Customer()
  IL_000b:  ldtoken    VB_IL_Difference.Customer
  IL_0010:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_0015:  ldstr      "x"
  IL_001a:  call       class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type,
                                                                                                                                                 string)
  IL_001f:  stloc.1
  IL_0020:  ldloc.1
  IL_0021:  ldtoken    method instance int32 VB_IL_Difference.Customer::get_CustomerId()
  IL_0026:  call       class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
  IL_002b:  castclass  [mscorlib]System.Reflection.MethodInfo
  IL_0030:  call       class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                             class [mscorlib]System.Reflection.MethodInfo)
  IL_0035:  ldtoken    method instance bool [mscorlib]System.Int32::Equals(int32)
  IL_003a:  call       class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
  IL_003f:  castclass  [mscorlib]System.Reflection.MethodInfo
  IL_0044:  ldc.i4.1
  IL_0045:  newarr     [System.Core]System.Linq.Expressions.Expression
  IL_004a:  stloc.2
  IL_004b:  ldloc.2
  IL_004c:  ldc.i4.0
  IL_004d:  ldc.i4.5
  IL_004e:  box        [mscorlib]System.Int32
  IL_0053:  ldtoken    [mscorlib]System.Int32
  IL_0058:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_005d:  call       class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object,
                                                                                                                                               class [mscorlib]System.Type)
  IL_0062:  stelem.ref
  IL_0063:  nop
  IL_0064:  ldloc.2
  IL_0065:  call       class [System.Core]System.Linq.Expressions.MethodCallExpression [System.Core]System.Linq.Expressions.Expression::Call(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                             class [mscorlib]System.Reflection.MethodInfo,
                                                                                                                                             class [System.Core]System.Linq.Expressions.Expression[])
  IL_006a:  ldc.i4.1
  IL_006b:  newarr     [System.Core]System.Linq.Expressions.ParameterExpression
  IL_0070:  stloc.3
  IL_0071:  ldloc.3
  IL_0072:  ldc.i4.0
  IL_0073:  ldloc.1
  IL_0074:  stelem.ref
  IL_0075:  nop
  IL_0076:  ldloc.3
  IL_0077:  call       class [System.Core]System.Linq.Expressions.Expression`1<!!0> [System.Core]System.Linq.Expressions.Expression::Lambda<class [mscorlib]System.Func`2<class VB_IL_Difference.Customer,bool>>(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                                                                                                 class [System.Core]System.Linq.Expressions.ParameterExpression[])
  IL_007c:  call       class [System.Core]System.Linq.IQueryable`1<!!0> [System.Core]System.Linq.Queryable::Where<class VB_IL_Difference.Customer>(class [System.Core]System.Linq.IQueryable`1<!!0>,
                                                                                                                                                   class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`2<!!0,bool>>)
  IL_0081:  ldtoken    VB_IL_Difference.Customer
  IL_0086:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_008b:  ldstr      "x"
  IL_0090:  call       class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type,
                                                                                                                                                 string)
  IL_0095:  stloc.s    VB$t_ref$S1
  IL_0097:  ldloc.s    VB$t_ref$S1
  IL_0099:  ldc.i4.1
  IL_009a:  newarr     [System.Core]System.Linq.Expressions.ParameterExpression
  IL_009f:  stloc.s    VB$t_array$S2
  IL_00a1:  ldloc.s    VB$t_array$S2
  IL_00a3:  ldc.i4.0
  IL_00a4:  ldloc.s    VB$t_ref$S1
  IL_00a6:  stelem.ref
  IL_00a7:  nop
  IL_00a8:  ldloc.s    VB$t_array$S2
  IL_00aa:  call       class [System.Core]System.Linq.Expressions.Expression`1<!!0> [System.Core]System.Linq.Expressions.Expression::Lambda<class [mscorlib]System.Func`2<class VB_IL_Difference.Customer,class VB_IL_Difference.Customer>>(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                                                                                                                            class [System.Core]System.Linq.Expressions.ParameterExpression[])
  IL_00af:  call       class [System.Core]System.Linq.IQueryable`1<!!1> [System.Core]System.Linq.Queryable::Select<class VB_IL_Difference.Customer,class VB_IL_Difference.Customer>(class [System.Core]System.Linq.IQueryable`1<!!0>,
                                                                                                                                                                                    class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`2<!!0,!!1>>)
  IL_00b4:  stloc.0
  IL_00b5:  ldloc.0
  IL_00b6:  call       int32 [System.Core]System.Linq.Queryable::Count<class VB_IL_Difference.Customer>(class [System.Core]System.Linq.IQueryable`1<!!0>)
  IL_00bb:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_00c0:  nop
  IL_00c1:  nop
  IL_00c2:  ret
} // end of method Module1::CallContext
] [

] C #: [

] [
    .method private hidebysig static void  CallContext() cil managed
{
  // Code size       141 (0x8d)
  .maxstack  7
  .locals init ([0] class [System.Core]System.Linq.IQueryable`1<class C_IL_Difference.Customer> someCustomer,
           [1] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
           [2] class [System.Core]System.Linq.Expressions.Expression[] CS$0$0001,
           [3] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0002)
  IL_0000:  nop
  IL_0001:  ldsfld     class C_IL_Difference.TravelEntities C_IL_Difference.Program::ctx
  IL_0006:  callvirt   instance class [System.Data.Entity]System.Data.Objects.ObjectSet`1<class C_IL_Difference.Customer> C_IL_Difference.TravelEntities::get_Customer()
  IL_000b:  ldtoken    C_IL_Difference.Customer
  IL_0010:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_0015:  ldstr      "x"
  IL_001a:  call       class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter(class [mscorlib]System.Type,
                                                                                                                                                 string)
  IL_001f:  stloc.1
  IL_0020:  ldloc.1
  IL_0021:  ldtoken    method instance int32 C_IL_Difference.Customer::get_CustomerId()
  IL_0026:  call       class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
  IL_002b:  castclass  [mscorlib]System.Reflection.MethodInfo
  IL_0030:  call       class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                             class [mscorlib]System.Reflection.MethodInfo)
  IL_0035:  ldtoken    method instance bool [mscorlib]System.Int32::Equals(int32)
  IL_003a:  call       class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
  IL_003f:  castclass  [mscorlib]System.Reflection.MethodInfo
  IL_0044:  ldc.i4.1
  IL_0045:  newarr     [System.Core]System.Linq.Expressions.Expression
  IL_004a:  stloc.2
  IL_004b:  ldloc.2
  IL_004c:  ldc.i4.0
  IL_004d:  ldc.i4.5
  IL_004e:  box        [mscorlib]System.Int32
  IL_0053:  ldtoken    [mscorlib]System.Int32
  IL_0058:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_005d:  call       class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object,
                                                                                                                                               class [mscorlib]System.Type)
  IL_0062:  stelem.ref
  IL_0063:  ldloc.2
  IL_0064:  call       class [System.Core]System.Linq.Expressions.MethodCallExpression [System.Core]System.Linq.Expressions.Expression::Call(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                             class [mscorlib]System.Reflection.MethodInfo,
                                                                                                                                             class [System.Core]System.Linq.Expressions.Expression[])
  IL_0069:  ldc.i4.1
  IL_006a:  newarr     [System.Core]System.Linq.Expressions.ParameterExpression
  IL_006f:  stloc.3
  IL_0070:  ldloc.3
  IL_0071:  ldc.i4.0
  IL_0072:  ldloc.1
  IL_0073:  stelem.ref
  IL_0074:  ldloc.3
  IL_0075:  call       class [System.Core]System.Linq.Expressions.Expression`1<!!0> [System.Core]System.Linq.Expressions.Expression::Lambda<class [mscorlib]System.Func`2<class C_IL_Difference.Customer,bool>>(class [System.Core]System.Linq.Expressions.Expression,
                                                                                                                                                                                                                class [System.Core]System.Linq.Expressions.ParameterExpression[])
  IL_007a:  call       class [System.Core]System.Linq.IQueryable`1<!!0> [System.Core]System.Linq.Queryable::Where<class C_IL_Difference.Customer>(class [System.Core]System.Linq.IQueryable`1<!!0>,
                                                                                                                                                  class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`2<!!0,bool>>)
  IL_007f:  stloc.0
  IL_0080:  ldloc.0
  IL_0081:  call       int32 [System.Core]System.Linq.Queryable::Count<class C_IL_Difference.Customer>(class [System.Core]System.Linq.IQueryable`1<!!0>)
  IL_0086:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_008b:  nop
  IL_008c:  ret
} // end of method Program::CallContext
] [

] Похоже, версия этого кода для VB.NET будет обращаться к базе данных каждый раз, когда код выполняется, в то время как версия C # будет извлекать объекты из кеша, когда код выполняется несколько раз. [

] [

] Почему они заставляют оба языка вести себя таким разным образом? Я ошибочно полагал, что оба языка просто различались по синтаксису и имели почти одинаковый сгенерированный IL. [

] [

] Есть ли еще примеры, когда оба языка генерировали такие разные IL? [

]
6
задан Luc Bos 26 August 2011 в 12:06
поделиться