Я пишу компилятор, который выводит сборки .NET (используя Mono.Cecil, хотя я не верю, что Cecil имеет отношение к этой проблеме). Одна из возможностей компилятора требует, чтобы у класса был сгенерированный компилятором вложенный класс с некоторыми вспомогательными методами; внешний класс имеет статическое поле, поэтому каждый класс фактически имеет синглтон, ссылающийся на объект вложенного класса. Чтобы инициализировать это, любой такой класс имеет конструктор класса для создания экземпляра вложенного класса и сохранения его в поле.
Проблема: когда мой внешний класс является универсальным классом, я также делаю вложенный класс универсальным (поскольку он должен создавать объекты внешнего класса). Сгенерированный IL проходит через peverify нормально и выглядит хорошо, на мой взгляд, но конструктор класса, создающий экземпляр вложенного класса, выбрасывает OutOfMemoryException во время выполнения.
Я разобрал сборку с помощью ildasm, уменьшил ее до минимального воспроизведения (к сожалению, все еще ~180 строк IL) и убедился, что компиляция IL с помощью ilasm создает исполняемый файл, который все еще демонстрирует проблему.
Отладка с помощью Visual Studio или MDbg меня не просветила - я просто получаю OutOfMemoryException без указания почему. Я готов поверить, что мой IL каким-то образом недействителен, но peverify не указывает на проблему. Кто-нибудь может подсказать, в чем проблема?
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern System
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly Repro1
{
.ver 0:0:0:0
}
.module Repro1
// MVID: {7DA983B6-F5EA-4ACB-8443-C29F25ADDCD4}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x016E0000
.class public abstract auto ansi sealed Repro1
extends [mscorlib]System.Object
{
.method assembly static void '<NemeaProgram>'() cil managed
{
.entrypoint
// Code size 6 (0x6)
.maxstack 0
IL_0000: call void Rep2::Go()
IL_0005: ret
} // end of method Repro1::'<NemeaProgram>'
} // end of class Repro1
.class public abstract auto ansi sealed Rep1
extends [mscorlib]System.Object
{
.class auto ansi nested public TRep
extends [mscorlib]System.Object
{
.class auto ansi nested public '__%NemeaVType'
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method '__%NemeaVType'::.ctor
.method public newslot virtual instance class Rep1/TRep
Create(string Foo) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg Foo
IL_0004: newobj instance void Rep1/TRep::.ctor(string)
IL_0009: ret
} // end of method '__%NemeaVType'::Create
} // end of class '__%NemeaVType'
.field famorassem string FData
.field public static class Rep1/TRep/'__%NemeaVType' '__%NemeaVTypeI'
.method public hidebysig specialname rtspecialname
instance void .ctor(string Foo) cil managed
{
// Code size 17 (0x11)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldarg Foo
IL_000b: stfld string Rep1/TRep::FData
IL_0010: ret
} // end of method TRep::.ctor
.method privatescope specialname rtspecialname static
void '.cctor$PST0600004C'() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: newobj instance void Rep1/TRep/'__%NemeaVType'::.ctor()
IL_0005: stsfld class Rep1/TRep/'__%NemeaVType' Rep1/TRep::'__%NemeaVTypeI'
IL_000a: ret
} // end of method TRep::.cctor
} // end of class TRep
.class auto ansi nested public TItem
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method TItem::.ctor
} // end of class TItem
} // end of class Rep1
.class public abstract auto ansi sealed Rep2
extends [mscorlib]System.Object
{
.class auto ansi nested public TRep<(Rep1/TItem) T>
extends Rep1/TRep
{
.class auto ansi nested public '__%NemeaVType'<(Rep1/TItem) T_vt>
extends Rep1/TRep/'__%NemeaVType'
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void Rep1/TRep/'__%NemeaVType'::.ctor()
IL_0006: ret
} // end of method '__%NemeaVType'::.ctor
.method public virtual instance class Rep1/TRep
Create(string Foo) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg Foo
IL_0004: newobj instance void class Rep2/TRep<!T_vt>::.ctor(string)
IL_0009: ret
} // end of method '__%NemeaVType'::Create
} // end of class '__%NemeaVType'
.field public static class Rep2/TRep/'__%NemeaVType'<!T> '__%NemeaVTypeI'
.method public hidebysig specialname rtspecialname
instance void .ctor(string Foo) cil managed
{
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg Foo
IL_0005: call instance void Rep1/TRep::.ctor(string)
IL_0015: ret
} // end of method TRep::.ctor
.method privatescope specialname rtspecialname static
void '.cctor$PST06000055'() cil managed
{
// Code size 11 (0xb)
.maxstack 8
IL_0000: newobj instance void class Rep2/TRep/'__%NemeaVType'<!T>::.ctor()
IL_0005: stsfld class Rep2/TRep/'__%NemeaVType'<!T> Rep2/TRep::'__%NemeaVTypeI'
IL_000a: ret
} // end of method TRep::.cctor
} // end of class TRep
.method public static void Go() cil managed
{
// Code size 29 (0x1d)
.maxstack 1
.locals init ([0] class Rep1/TRep R)
IL_0000: ldstr "Oi"
IL_0005: newobj instance void class Rep2/TRep<class Rep1/TItem>::.ctor(string)
IL_000a: stloc R
IL_001c: ret
} // end of method Rep2::Go
} // end of class Rep2
T_vt
без использования родительскогоT
, что определенно не то, что вам нужно, и, вероятно, ошибка, которая может вызывать исключение, которое вы видите (поскольку ваш вложенный класс должен использовать все аргументы универсального типа своего родительского класса). - person Luaan   schedule 23.08.2016