0

Is it possible to generate a dynamic type and in a method a dynamic variable using reflection emit? The dynamic type would be something like the code below but created by using reflection emit.

public class MyDynamicType { public void MyTests() { dynamic MyDynamicVar = 10; MyDynamicVar = "whatever"; } } 
2
  • dynamic is part object, part compiler magic. Emit it as object and you should be fine. The compiler magic, if you need it, is something you will have to mimick if you want to act as the compiler. This part, you will not be fine, because mimicking the compiler is going to be super complex regarding dynamic types. Commented Mar 6, 2020 at 8:25
  • What is it your actually trying to achieve? There may be a better solution that generating a class on the fly. Commented Mar 6, 2020 at 8:50

1 Answer 1

2

You can do this - but it would be incredibly difficult (at least if you want to do anything usefully dynamic - just assigning a value to a local varaible would be easy enough, but I assume your real code would do more than that). Dynamic typing is handled by the C# compiler; there's no IL for it... whereas Reflection.Emit is all about generating IL.

So this piece of code:

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

generates the following IL - as well as a generated class, referred to in the 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 

You'd have to write Reflection.Emit code to generate all that IL yourself. I really, really don't think you want to do that.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.