【问题标题】:Why do my anonymous types not work in Clay when using VB.Net but do work in C#为什么我的匿名类型在使用 VB.Net 时不能在 Clay 中工作,但在 C# 中工作
【发布时间】:2011-08-20 20:18:44
【问题描述】:

我正在尝试clay in VB.Net,但发现我无法让一切正常工作。

这里是Clay

这适用于 C#

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

但这在 VB.Net 中不起作用

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

我在 VB.Net 中收到此错误消息:

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

如果我能解决这个问题,我不能 100% 确定如何解决。我猜匿名类型的 VB.Net 实现略有不同。

我在这一行得到错误:

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

如果有人可以向我解释这一点,我将不胜感激。

IL 似乎不一样了。

对于 VB,私有字段 Latinname 是这样的:

.field private initonly !T0 $LatinName

对于 C#,它是:

.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 ) 

公共方法 Get_LatinName 就是这个。

VB:

.method public specialname instance !T0 get_LatinName() cil managed { .custom 实例无效 [​​mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (01 00 00 00) // 代码大小 11 (0xb) .maxstack 1 .locals 初始化 (!T0 V_0) IL_0000:ldarg.0 IL_0001: ldfld !0 类 VB$AnonymousType_0`1::$LatinName IL_0006:stloc.0 IL_0007: 兄弟 IL_0009 IL_0009:ldloc.0 IL_000a:ret } // 方法结束 VB$AnonymousType_0`1::get_LatinName

C#:

.method public hidebysig specialname instance !'j__TPar' get_LatinName() cil 托管 { // 代码大小 11 (0xb) .maxstack 1 .locals init (!'j__TPar' V_0) IL_0000:ldarg.0 IL_0001: ldfld !0 类 'f__AnonymousType0`1'j__TPar'>::'i__Field' IL_0006:stloc.0 IL_0007: 兄弟 IL_0009 IL_0009:ldloc.0 IL_000a:ret } // 方法 'f__AnonymousType0`1'::get_LatinName 结束

这些是主要的方法:

VB:

.method public static void Main() cil 托管 { 。入口点 .custom 实例无效 [​​mscorlib]System.STAThreadAttribute::.ctor() = (01 00 00 00) // 代码大小 90 (0x5a) .maxstack 7 .locals init ([0] 对象 c, [1] 对象植物, [2] 类 VB$AnonymousType_0`1 VB$t_ref$S0, [3] 对象[] VB$t_array$S0) IL_0000:没有 IL_0001:newobj 实例无效 [​​ClaySharp]ClaySharp.ClayFactory::.ctor() IL_0006:stloc.0 IL_0007:ldloc.0 IL_0008:ldnull IL_0009: ldstr "植物" 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“测试” IL_001c:newobj 实例无效类 VB$AnonymousType_0`1::.ctor(!0) IL_0021:stelem.ref IL_0022:没有 IL_0023:ldloc.3 IL_0024:ldnull IL_0025:ldnull IL_0026:ldnull IL_0027:调用对象 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.NewLateBinding::LateGet(object, 类 [mscorlib]System.Type, 细绳, 目的[], 细绳[], 类 [mscorlib]System.Type[], 布尔[]) IL_002c:调用对象 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) IL_0031:stloc.1 IL_0032:ldloc.1 IL_0033:ldnull IL_0034: ldstr "拉丁名" IL_0039:ldc.i4.0 IL_003a:newarr [mscorlib]System.Object IL_003f:ldnull IL_0040:ldnull IL_0041:ldnull IL_0042:调用对象 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.NewLateBinding::LateGet(object, 类 [mscorlib]System.Type, 细绳, 目的[], 细绳[], 类 [mscorlib]System.Type[], 布尔[]) IL_0047:调用对象 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) IL_004c:调用 void [mscorlib]System.Console::WriteLine(object) IL_0051:没有 IL_0052:调用字符串 [mscorlib]System.Console::ReadLine() IL_0057:流行 IL_0058:没有 IL_0059:恢复 } // 方法 Module1::Main 结束

C#:

.method private hidebysig static void Main(string[] args) cil 托管 { 。入口点 // 代码大小 299 (0x12b) .maxstack 10 .locals init ([0] 对象 c, [1] 对象植物, [2] 类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000) IL_0000:没有 IL_0001:newobj 实例无效 [​​ClaySharp]ClaySharp.ClayFactory::.ctor() IL_0006:stloc.0 IL_0007: ldsfld 类 [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 "植物" IL_0014:ldnull IL_0015:ldtoken ConsoleApplication2.Program IL_001a:调用类 [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:调用类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 细绳) IL_002f: stelem.ref IL_0030:ldloc.2 IL_0031:ldc.i4.1 IL_0032:ldc.i4.1 IL_0033:ldnull IL_0034:调用类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 细绳) IL_0039: stelem.ref IL_003a:ldloc.2 IL_003b:调用类 [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 细绳, 类 [mscorlib]System.Collections.Generic.IEnumerable`1, 类 [mscorlib]System.Type, 类 [mscorlib]System.Collections.Generic.IEnumerable`1) IL_0040:调用类 [System.Core]System.Runtime.CompilerServices.CallSite`1 类 [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>>::Create(class [System.Core] System.Runtime.CompilerServices.CallSiteBinder) IL_0045: stsfld 类 [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 类 [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' IL_0051: ldfld !0 类 [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>>::Target IL_0056: ldsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1f__AnonymousType0`1',object>> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site1' IL_005b:ldloc.0 IL_005c:ldstr“测试” IL_0061: newobj 实例无效类'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 类 [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:调用类 [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:调用类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 细绳) IL_0099: stelem.ref IL_009a:ldloc.2 IL_009b:ldc.i4.1 IL_009c:ldc.i4.0 IL_009d:ldnull IL_009e:调用类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 细绳) IL_00a3: stelem.ref IL_00a4:ldloc.2 IL_00a5:调用类 [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 细绳, 类 [mscorlib]System.Collections.Generic.IEnumerable`1, 类 [mscorlib]System.Type, 类 [mscorlib]System.Collections.Generic.IEnumerable`1) IL_00aa:调用类 [System.Core]System.Runtime.CompilerServices.CallSite`1 类 [System.Core]System.Runtime.CompilerServices.CallSite`1>::Create(class [System.Core]System.Runtime.CompilerServices. CallSiteBinder) IL_00af:stsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' IL_00b4: br.s IL_00b6 IL_00b6:ldsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' IL_00bb: ldfld !0 类 [System.Core]System.Runtime.CompilerServices.CallSite`1>::Target IL_00c0:ldsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site2' IL_00c5:ldtoken [mscorlib]System.Console IL_00ca:调用类 [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_00cf:ldsfld 类 [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 "拉丁名" IL_00dc:ldtoken ConsoleApplication2.Program IL_00e1:调用类 [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:调用类 [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, 细绳) IL_00f6: stelem.ref IL_00f7:ldloc.2 IL_00f8:调用类 [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::GetMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, 细绳, 类 [mscorlib]System.Type, 类 [mscorlib]System.Collections.Generic.IEnumerable`1) IL_00fd:调用类 [System.Core]System.Runtime.CompilerServices.CallSite`1 类 [System.Core]System.Runtime.CompilerServices.CallSite`1>::Create(class [System.Core]System.Runtime.CompilerServices. CallSiteBinder) IL_0102:stsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' IL_0107: 兄弟 IL_0109 IL_0109:ldsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' IL_010e: ldfld !0 类 [System.Core]System.Runtime.CompilerServices.CallSite`1>::Target IL_0113:ldsfld 类 [System.Core]System.Runtime.CompilerServices.CallSite`1> ConsoleApplication2.Program/'o__SiteContainer0'::'p__Site3' IL_0118:ldloc.1 IL_0119: callvirt 实例 !2 类 [mscorlib]System.Func`3::Invoke(!0, !1) IL_011e: callvirt 实例无效类 [mscorlib]System.Action`3::Invoke(!0, !1, !2) IL_0123:没有 IL_0124:调用字​​符串 [mscorlib]System.Console::ReadLine() IL_0129:弹出 IL_012a: 回复 } // 方法结束 Program::Main

C# 和 VB 版本完全不同。似乎 C# 版本做得更多。

【问题讨论】:

  • 考虑到那里没有 lambda,这是一个奇怪的错误。
  • 编译表达式树时它会爆炸。这段代码中有许多不可调试的技巧。
  • 既然你的博客有答案,我认为你应该把它贴在这里。
  • 看起来 VB 代码做得更少的一个原因是因为它是:因为 Console.WriteLine 有一个 Object 重载,VB 只使用它,而 C# 有该调用的后期绑定也是如此。

标签: c# vb.net anonymous-types


【解决方案1】:

我对 Clay 一无所知,但 C# 匿名类型和 VB 匿名类型之间存在一个潜在的重要区别:C# 匿名类型总是具有只读属性,而默认情况下,VB 是可变的。

在 VB 中,只有只读属性用于相等和哈希码的生成。这些可以用Key 关键字指定。所以为了更接近你的 C# 代码,VB 应该是:

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

试试看是否有帮助:)

【讨论】:

  • @chrissie1:在这种情况下,您可能想查看两个编译器生成的 IL。哪一行给出了错误?
  • 是的,我现在正在查看 IL。
  • 我添加了 IL,但它的区别是巨大的。我想我松了:-(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2020-03-15
  • 2014-11-26
  • 1970-01-01
  • 2013-04-09
  • 2020-01-22
  • 2015-03-02
相关资源
最近更新 更多