我有一个很小的C#库,其中有一个静态类,其中包含一个非常大但很简单的四维字节数组,表示一个多维决策表(总共大约90K字节)。
这里还有另一个值得注意的数据结构,一个字典,它帮助索引决策表的第一个维度。
这个决策表是一个静态私有数据成员,由数组静态初始化器初始化。代码是在Visual Studio2010中用T4从Excel文档中生成的。
决策是通过索引到多维数组的静态方法获得的。
当我使用这个库运行一个简单的测试应用程序时,它会弹出一个"System.TypeLoadException: Internal simple : too many“。在第一次调用静态决策方法时引发。
关于Stackoverflow的one remotely related主题提到了包含“太多符号”的库。我可能错了,但我的库中似乎只有很少的符号。
这里发生了什么事?
代码片段:
private static byte[][][][] decisions = new byte[][][][] {
new byte[][][] {
new byte[][] {
new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6}
},
new byte[][] {
new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},
new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6},new byte[]{5,6,6}
},
...and等..。
发布于 2010-10-13 04:53:59
新byte[]{5,6,6}
这里的问题是初始化器{5,6,6}创建了一个静态字段。您可以使用Ildasm.exe查看它。我相信CLR在一个类中最多强制使用65535个字段。您的自动生成的代码超出了它的范围。
你将不得不以不同的方式来做这件事。脑海中突然浮现出一个文件。
发布于 2010-10-13 04:52:45
哇。看起来很有趣。我不能评论那个特定的错误(尽管我认为它实际上是太多的中间局部变量),但在一些非常相似的东西(基于codegen的决策引擎)中,我通过序列化(在我的例子中是二进制的,但任何都应该可以)填充数据。这意味着需要两步加载(创建obj,从文件加载),但它工作得很好。
顺便说一句:我的构造函数足以让反射器爆炸成一堆乱七八糟的东西(非常极端的错误),所以我能感受到你的痛苦。
发布于 2010-10-13 04:59:09
您可以尝试在静态构造函数中显式发出代码,并直接在子数组中索引,而不是使用数组初始值设定项语法。这将阻止静态字段的创建,而是将所有数据设置编码到一个巨大的IL斑点中。我不确定单个方法中的IL数量是否有类似的限制,但如果您相应地修改T4,我相信您会发现这一点。
它看起来是这样的:
static MyClass()
{
decisions = new byte[N1][][][];
decisions[0] = new byte[N2][][];
....
decisions[0][0][0][0] = 5;
decisions[0][0][0][1] = 6;
decisions[0][0][0][2] = 6;
...
}
https://stackoverflow.com/questions/3918785
复制相似问题