2011-05-07 10 views
9

Estaba probando clay in VB.Net pero me di cuenta de que no podía hacer que todo funcionara.¿Por qué mis tipos anónimos no funcionan en Clay cuando se utiliza VB.Net pero funcionan en C#

Aquí es Clay

Esto funciona en C#

dynamic c = new ClayFactory(); 
     var plant = c.Plant(new {LatinName = "test"}); 
     Console.WriteLine(plant.LatinName); 
     Console.ReadLine(); 

pero esto no funciona en VB.Net

Dim c As Object = New ClayFactory 
     Dim plant = c.Plant(New With {.LatinName = "test"}) 
     Console.WriteLine(plant.LatinName) 
     Console.ReadLine() 

me sale este mensaje de error en VB.Net:

> Cannot close over byref parameter 
> '$arg1' referenced in lambda '' 

No estoy 100% seguro de cómo resolver esto si puedo resolverlo. Supongo que la implementación de VB.Net de tipos anónimos es ligeramente diferente.

me sale el error en esta línea:

Dim plant = c.Plant(New With {.LatinName = "test"}) 

Le agradecería si alguien podría explicar esto a mí.

El IL parece ser diferente.

para VB el campo privado Latinname es la siguiente:

.field private initonly !T0 $LatinName 

para C# es:

.field private initonly !'<LatinName>j__TPar' '<LatinName>i__Field' 
.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (01 00 00 00 00 00 00 00) 

Y el Get_LatinName método público es la siguiente.

VB:

 
    .method public specialname instance !T0 get_LatinName() cil managed 
{ 
    .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (01 00 00 00) 
    // Code size  11 (0xb) 
    .maxstack 1 
    .locals init (!T0 V_0) 
    IL_0000: ldarg.0 
    IL_0001: ldfld  !0 class VB$AnonymousType_0`1::$LatinName 
    IL_0006: stloc.0 
    IL_0007: br.s  IL_0009 
    IL_0009: ldloc.0 
    IL_000a: ret 
} // end of method VB$AnonymousType_0`1::get_LatinName 

C#:

 

    .method public hidebysig specialname instance !'j__TPar' 
     get_LatinName() cil managed 
{ 
    // Code size  11 (0xb) 
    .maxstack 1 
    .locals init (!'j__TPar' V_0) 
    IL_0000: ldarg.0 
    IL_0001: ldfld  !0 class 'f__AnonymousType0`1'j__TPar'>::'i__Field' 
    IL_0006: stloc.0 
    IL_0007: br.s  IL_0009 
    IL_0009: ldloc.0 
    IL_000a: ret 
} // end of method 'f__AnonymousType0`1'::get_LatinName 

Y estos son los principales métodos:

VB:

 
    .method public static void Main() cil managed 
{ 
    .entrypoint 
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (01 00 00 00) 
    // Code size  90 (0x5a) 
    .maxstack 7 
    .locals init ([0] object c, 
      [1] object plant, 
      [2] class VB$AnonymousType_0`1 VB$t_ref$S0, 
      [3] object[] VB$t_array$S0) 
    IL_0000: nop 
    IL_0001: newobj  instance void [ClaySharp]ClaySharp.ClayFactory::.ctor() 
    IL_0006: stloc.0 
    IL_0007: ldloc.0 
    IL_0008: ldnull 
    IL_0009: ldstr  "Plant" 
    IL_000e: ldc.i4.1 
    IL_000f: newarr  [mscorlib]System.Object 
    IL_0014: stloc.3 
    IL_0015: ldloc.3 
    IL_0016: ldc.i4.0 
    IL_0017: ldstr  "test" 
    IL_001c: newobj  instance void class VB$AnonymousType_0`1::.ctor(!0) 
    IL_0021: stelem.ref 
    IL_0022: nop 
    IL_0023: ldloc.3 
    IL_0024: ldnull 
    IL_0025: ldnull 
    IL_0026: ldnull 
    IL_0027: call  object [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.NewLateBinding::LateGet(object, 
                                class [mscorlib]System.Type, 
                                string, 
                                object[], 
                                string[], 
                                class [mscorlib]System.Type[], 
                                bool[]) 
    IL_002c: call  object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) 
    IL_0031: stloc.1 
    IL_0032: ldloc.1 
    IL_0033: ldnull 
    IL_0034: ldstr  "LatinName" 
    IL_0039: ldc.i4.0 
    IL_003a: newarr  [mscorlib]System.Object 
    IL_003f: ldnull 
    IL_0040: ldnull 
    IL_0041: ldnull 
    IL_0042: call  object [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.NewLateBinding::LateGet(object, 
                                class [mscorlib]System.Type, 
                                string, 
                                object[], 
                                string[], 
                                class [mscorlib]System.Type[], 
                                bool[]) 
    IL_0047: call  object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) 
    IL_004c: call  void [mscorlib]System.Console::WriteLine(object) 
    IL_0051: nop 
    IL_0052: call  string [mscorlib]System.Console::ReadLine() 
    IL_0057: pop 
    IL_0058: nop 
    IL_0059: ret 
} // end of method Module1::Main

C#:

 
    .method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  299 (0x12b) 
    .maxstack 10 
    .locals init ([0] object c, 
      [1] object plant, 
      [2] class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000) 
    IL_0000: nop 
    IL_0001: newobj  instance void [ClaySharp]ClaySharp.ClayFactory::.ctor() 
    IL_0006: stloc.0 
    IL_0007: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' 
    IL_000c: brtrue.s IL_004c 
    IL_000e: ldc.i4.0 
    IL_000f: ldstr  "Plant" 
    IL_0014: ldnull 
    IL_0015: ldtoken ConsoleApplication2.Program 
    IL_001a: call  class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
    IL_001f: ldc.i4.2 
    IL_0020: newarr  [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo 
    IL_0025: stloc.2 
    IL_0026: ldloc.2 
    IL_0027: ldc.i4.0 
    IL_0028: ldc.i4.0 
    IL_0029: ldnull 
    IL_002a: call  class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 
                                              string) 
    IL_002f: stelem.ref 
    IL_0030: ldloc.2 
    IL_0031: ldc.i4.1 
    IL_0032: ldc.i4.1 
    IL_0033: ldnull 
    IL_0034: call  class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 
                                              string) 
    IL_0039: stelem.ref 
    IL_003a: ldloc.2 
    IL_003b: call  class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 
                                           string, 
                                           class [mscorlib]System.Collections.Generic.IEnumerable`1, 
                                           class [mscorlib]System.Type, 
                                           class [mscorlib]System.Collections.Generic.IEnumerable`1) 
    IL_0040: call  class [System.Core]System.Runtime.CompilerServices.CallSite`1 class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder) 
    IL_0045: stsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' 
    IL_004a: br.s  IL_004c 
    IL_004c: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' 
    IL_0051: ldfld  !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>>::Target 
    IL_0056: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' 
    IL_005b: ldloc.0 
    IL_005c: ldstr  "test" 
    IL_0061: newobj  instance void class 'f__AnonymousType0`1'::.ctor(!0) 
    IL_0066: callvirt instance !3 class [mscorlib]System.Func`4f__AnonymousType0`1',object>::Invoke(!0, 
                                                  !1, 
                                                  !2) 
    IL_006b: stloc.1 
    IL_006c: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' 
    IL_0071: brtrue.s IL_00b6 
    IL_0073: ldc.i4  0x100 
    IL_0078: ldstr  "WriteLine" 
    IL_007d: ldnull 
    IL_007e: ldtoken ConsoleApplication2.Program 
    IL_0083: call  class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
    IL_0088: ldc.i4.2 
    IL_0089: newarr  [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo 
    IL_008e: stloc.2 
    IL_008f: ldloc.2 
    IL_0090: ldc.i4.0 
    IL_0091: ldc.i4.s 33 
    IL_0093: ldnull 
    IL_0094: call  class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 
                                              string) 
    IL_0099: stelem.ref 
    IL_009a: ldloc.2 
    IL_009b: ldc.i4.1 
    IL_009c: ldc.i4.0 
    IL_009d: ldnull 
    IL_009e: call  class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 
                                              string) 
    IL_00a3: stelem.ref 
    IL_00a4: ldloc.2 
    IL_00a5: call  class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 
                                           string, 
                                           class [mscorlib]System.Collections.Generic.IEnumerable`1, 
                                           class [mscorlib]System.Type, 
                                           class [mscorlib]System.Collections.Generic.IEnumerable`1) 
    IL_00aa: call  class [System.Core]System.Runtime.CompilerServices.CallSite`1 class [System.Core]System.Runtime.CompilerServices.CallSite`1>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder) 
    IL_00af: stsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' 
    IL_00b4: br.s  IL_00b6 
    IL_00b6: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' 
    IL_00bb: ldfld  !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1>::Target 
    IL_00c0: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' 
    IL_00c5: ldtoken [mscorlib]System.Console 
    IL_00ca: call  class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
    IL_00cf: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' 
    IL_00d4: brtrue.s IL_0109 
    IL_00d6: ldc.i4.0 
    IL_00d7: ldstr  "LatinName" 
    IL_00dc: ldtoken ConsoleApplication2.Program 
    IL_00e1: call  class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) 
    IL_00e6: ldc.i4.1 
    IL_00e7: newarr  [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo 
    IL_00ec: stloc.2 
    IL_00ed: ldloc.2 
    IL_00ee: ldc.i4.0 
    IL_00ef: ldc.i4.0 
    IL_00f0: ldnull 
    IL_00f1: call  class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 
                                              string) 
    IL_00f6: stelem.ref 
    IL_00f7: ldloc.2 
    IL_00f8: call  class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::GetMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 
                                          string, 
                                          class [mscorlib]System.Type, 
                                          class [mscorlib]System.Collections.Generic.IEnumerable`1) 
    IL_00fd: call  class [System.Core]System.Runtime.CompilerServices.CallSite`1 class [System.Core]System.Runtime.CompilerServices.CallSite`1>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder) 
    IL_0102: stsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' 
    IL_0107: br.s  IL_0109 
    IL_0109: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' 
    IL_010e: ldfld  !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1>::Target 
    IL_0113: ldsfld  class [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' 
    IL_0118: ldloc.1 
    IL_0119: callvirt instance !2 class [mscorlib]System.Func`3::Invoke(!0, 
                                        !1) 
    IL_011e: callvirt instance void class [mscorlib]System.Action`3::Invoke(!0, 
                                              !1, 
                                              !2) 
    IL_0123: nop 
    IL_0124: call  string [mscorlib]System.Console::ReadLine() 
    IL_0129: pop 
    IL_012a: ret 
} // end of method Program::Main 

La versión C# y VB no son iguales. Parece que la versión C# hace mucho más.

+0

Eso es un error extraño teniendo en cuenta que no hay lambda allí. –

+0

Bombardea al compilar el árbol de expresiones. Para muchos trucos undebuggable en este código. –

+1

dado que tu blog tiene la respuesta, creo que deberías publicarlo aquí. – jbtule

Respuesta

2

No sé nada sobre la arcilla, pero hay diferencia de un potencialmente importante entre C# tipos anónimos y los VB: C# tipos anónimos propiedades siempre han de sólo lectura, mientras que de forma predeterminada, los VB son mutables .

Solo las propiedades de solo lectura se usan en igualdad y generación de código hash en VB. Estos se pueden especificar con la palabra clave Key.Así que para estar más cerca de su código C#, VB debe ser:

Dim c As Object = New ClayFactory 
Dim plant = c.Plant(New With { Key .LatinName = "test"}) 
Console.WriteLine(plant.LatinName) 
Console.ReadLine() 

que Dale una oportunidad y ver si ayuda :)

+0

da el mismo mensaje de error. – chrissie1

+0

@ chrissie1: en ese caso, es posible que desee ver el IL generado por ambos compiladores. ¿Qué línea está dando el error? –

+0

la planta tenue = c.planta uno. – chrissie1

Cuestiones relacionadas