Как удалить .local init из конструктора, созданного с помощью Reflection.Emit? - PullRequest
0 голосов
/ 04 апреля 2019

Я хочу создать класс с Relfection.Emit для динамического создания прокси-классов во время выполнения.Поскольку я использую Linq Select с Lambda Expressions в своем классе, сгенерированный код IL содержит вложенный класс для хранения замыканий.

Когда я создаю класс в C # и смотрю на сгенерированный код IL из компилятораэто выглядит так:

...
.class nested private auto ansi sealed serializable beforefieldinit '<>c'
        extends [mscorlib]System.Object
    {
        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        // Fields
        .field public static initonly class Namespace.ThemaVOMultiValueProxy/'<>c' '<>9'


        // Methods
        .method private hidebysig specialname rtspecialname static 
            void .cctor () cil managed 
        {
            // Method begins at RVA 0x78808
            // Code size 11 (0xb)
            .maxstack 8

            IL_0000: newobj instance void Namespace.ThemaVOMultiValueProxy/'<>c'::.ctor()
            IL_0005: stsfld class Namespace.ThemaVOMultiValueProxy/'<>c' Namespace.ThemaVOMultiValueProxy/'<>c'::'<>9'
            IL_000a: ret
        } // end of method '<>c'::.cctor

        ...

    } // end of class <>c
...

Вот что я хочу создать сам с помощью Reflection.Emit.

Мой C # -код для этого выглядит так:

...
var c = typeBuilder.DefineNestedType("closures", TypeAttributes.NestedPrivate | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.Serializable | TypeAttributes.BeforeFieldInit);
var closureField_proxy_9 = c.DefineField("proxy_9", c, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly);

var closureStaticConstructor = c.DefineConstructor(MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static, CallingConventions.Any, Type.EmptyTypes);
closureStaticConstructor.InitLocals = false;
var closureStaticConstructorILGenerator = closureStaticConstructor.GetILGenerator();
closureStaticConstructorILGenerator.Emit(Newobj, closureStaticConstructor1);
closureStaticConstructorILGenerator.Emit(Stsfld, closureField_proxy_9);
closureStaticConstructorILGenerator.Emit(Ret);
...

И это порождает этот IL:

...
// Nested Types
.class nested private auto auto sealed serializable beforefieldinit closures
    extends [mscorlib]System.Object
{
    // Fields
    .field public static initonly class RZL.KIS.WPF.ViewObject.ThemaVO_MultiValueProxy/closures proxy_9

    // Methods
    .method public hidebysig specialname rtspecialname 
        instance vararg void .ctor () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 8 (0x8)
        .maxstack 2
        .locals /* Signature type sequence must have at least one element. */ (
        )

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: ret
    } // end of method closures::.ctor

} // end of class closures
...

Теперь у меня вопрос: как удалить этот блок .locals /* Signature type sequence must have at least one element. */ в созданном конструкторе?Мне это не нужно, потому что у меня нет здесь локальных переменных или параметров.

Спасибо!

...