我需要扩展我对使用泛型时编译结构的理解。
我有以下代码,可以使用
public struct TestStruct
{
public GenericStruct<SecondTestStruct> Header;
public int TestValue;
}
public struct GenericStruct<T>
{
public int MessageSize => System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
}
public struct SecondTestStruct
{
public int TestValue;
}
static void Main(string[] args)
{
TestStruct test = new TestStruct();
Console.WriteLine($"Size of test is: {test.Header.MessageSize}");
}
此打印&#39;测试大小为:4&#39;
但是,如果我更改TestStruct以尝试提供自己的大小:
public struct TestStruct
{
public GenericStruct<TestStruct> Header;
public int TestValue;
}
我收到运行时错误:System.TypeLoadException: Could not load type 'TestStructGenerics.TestStruct' from assembly.
我猜测它与编译器无法创建结构编译时间有关。或者在处理通用分辨率时可能存在循环引用的问题。
修改
我刚刚意识到我可以通过将第二种情况更改为:
来实现我想要的目标public struct TestStruct
{
public GenericStruct<TestStruct> Header => new GenericStruct<TestStruct>();
public int TestValue;
}
答案 0 :(得分:1)
根据Eric Lippert在this Roslyn issue中的评论,目前还不清楚这个问题是否是CLR类型加载器限制,或者这类程序是否无效,如果它们无效,C#编译器是否应检测到它并发出错误。实际上,似乎在当局决定之前,我们必须避免结构之间的类型循环而不管引入依赖的模式 - 实例字段(因为结构将是无限大小而永远不会起作用),静态字段,实现的通用接口或通用参数。通过将循环中的某些结构更改为类,或者在运行时通过object
或接口和转换,可以在编译时中断这些结构类型循环。