动态变量为动态类型

问题描述 投票:0回答:1

是否可以生成动态类型,并且在某种方法中可以使用反射发射生成动态变量?动态类型类似于下面的代码,但使用反射发射创建。

public class MyDynamicType
{
    public void MyTests()
    {
        dynamic MyDynamicVar = 10;
        MyDynamicVar = "whatever";
    }
}
c# reflection.emit dynamic-type-feature
1个回答
0
投票

可以执行此操作-但这会很困难。动态类型由C#编译器处理;没有它的IL ...而Reflection.Emit都是关于生成IL的。所以这段代码:

static void Main() { dynamic x = "foo"; dynamic y = x.Substring(1, 2); }

生成以下IL-以及在IL中引用的生成的类:

.method private hidebysig static void Main() cil managed { .entrypoint // Code size 109 (0x6d) .maxstack 9 .locals init (object V_0, object V_1) IL_0000: nop IL_0001: ldstr "foo" IL_0006: stloc.0 IL_0007: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>> Program/'<>o__0'::'<>p__0' IL_000c: brfalse.s IL_0010 IL_000e: br.s IL_0054 IL_0010: ldc.i4.0 IL_0011: ldstr "Substring" IL_0016: ldnull IL_0017: ldtoken Program IL_001c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_0021: ldc.i4.3 IL_0022: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo IL_0027: dup IL_0028: ldc.i4.0 IL_0029: ldc.i4.0 IL_002a: ldnull IL_002b: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string) IL_0030: stelem.ref IL_0031: dup IL_0032: ldc.i4.1 IL_0033: ldc.i4.3 IL_0034: ldnull IL_0035: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string) IL_003a: stelem.ref IL_003b: dup IL_003c: ldc.i4.2 IL_003d: ldc.i4.3 IL_003e: ldnull IL_003f: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string) IL_0044: stelem.ref IL_0045: 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.Type, class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>) IL_004a: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder) IL_004f: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>> Program/'<>o__0'::'<>p__0' IL_0054: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>> Program/'<>o__0'::'<>p__0' IL_0059: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>>::Target IL_005e: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>> Program/'<>o__0'::'<>p__0' IL_0063: ldloc.0 IL_0064: ldc.i4.1 IL_0065: ldc.i4.2 IL_0066: callvirt instance !4 class [mscorlib]System.Func`5<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,int32,object>::Invoke(!0, !1, !2, !3) IL_006b: stloc.1 IL_006c: ret } // end of method Program::Main

您必须编写Reflection.Emit代码以自己生成所有IL。我真的,真的不认为您想要这样做。
© www.soinside.com 2019 - 2024. All rights reserved.