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

Место общения программистов C#
Ответить
Anonymous
 Сгенерированные различия IL для VB.NET и C#

Сообщение Anonymous »

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

VB. СЕТЬ:

Код: Выделить всё

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 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  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 [System.Core]System.Linq.Expressions.Expression::Lambda(class [System.Core]System.Linq.Expressions.Expression,
class [System.Core]System.Linq.Expressions.ParameterExpression[])
IL_007c:  call       class [System.Core]System.Linq.IQueryable`1  [System.Core]System.Linq.Queryable::Where(class [System.Core]System.Linq.IQueryable`1,
class [System.Core]System.Linq.Expressions.Expression`1)
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 [System.Core]System.Linq.Expressions.Expression::Lambda(class [System.Core]System.Linq.Expressions.Expression,
class [System.Core]System.Linq.Expressions.ParameterExpression[])
IL_00af:  call       class [System.Core]System.Linq.IQueryable`1 [System.Core]System.Linq.Queryable::Select(class [System.Core]System.Linq.IQueryable`1,
class [System.Core]System.Linq.Expressions.Expression`1)
IL_00b4:  stloc.0
IL_00b5:  ldloc.0
IL_00b6:  call       int32 [System.Core]System.Linq.Queryable::Count(class [System.Core]System.Linq.IQueryable`1)
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 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  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 [System.Core]System.Linq.Expressions.Expression::Lambda(class [System.Core]System.Linq.Expressions.Expression,
class [System.Core]System.Linq.Expressions.ParameterExpression[])
IL_007a:  call       class [System.Core]System.Linq.IQueryable`1  [System.Core]System.Linq.Queryable::Where(class [System.Core]System.Linq.IQueryable`1,
class [System.Core]System.Linq.Expressions.Expression`1)
IL_007f:  stloc.0
IL_0080:  ldloc.0
IL_0081:  call       int32 [System.Core]System.Linq.Queryable::Count(class [System.Core]System.Linq.IQueryable`1)
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?

Подробнее здесь: https://stackoverflow.com/questions/720 ... nd-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»