Dynami c переменная в тип Dynami c - PullRequest
0 голосов
/ 06 марта 2020

Можно ли сгенерировать динамический c тип и в методе динамическую c переменную с использованием отражения? Тип Dynami c будет выглядеть примерно так, как показано ниже, но будет создан с использованием отражения emit.

public class MyDynamicType
{
    public void MyTests()
    {
        dynamic MyDynamicVar = 10;
        MyDynamicVar = "whatever";
    }
}

1 Ответ

1 голос
/ 06 марта 2020

Вы можете сделать это - но это будет невероятно сложно (по крайней мере, если вы хотите что-то сделать с пользой, динамически c - просто присвоение значения локальному varaible будет будет достаточно легко, но я предполагаю, что ваш реальный код будет делать больше, чем это). Динамическая печать c обрабатывается компилятором 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 самостоятельно. Я действительно, действительно не думаю, что ты хочешь сделать это.

...