我需要加深对使用泛型时结构是如何编译的理解。
我有下面的代码,有效
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}");
}
这会打印“测试大小为:4”
但是,如果我更改 TestStruct 以尝试提供它自己的大小:
public struct TestStruct
{
public GenericStruct<TestStruct> Header;
public int TestValue;
}
我收到运行时错误:System.TypeLoadException:无法从程序集中加载类型“TestStructGenerics.TestStruct”。
我猜这与编译器无法创建结构编译时间有关。或者可能是处理通用解析时循环引用的问题。
编辑:
我刚刚意识到我可以通过将第二种情况更改为来实现我想要的:
public struct TestStruct
{
public GenericStruct<TestStruct> Header => new GenericStruct<TestStruct>();
public int TestValue;
}
根据 Eric Lippert 在 this Roslyn issue 中的评论, 目前尚不清楚此问题是 CLR 类型加载程序限制还是此类程序是否无效,以及如果它们无效,C# 编译器是否应检测到它并发出错误。实际上,似乎在当局决定之前,我们必须避免结构之间的类型循环,而不管引入依赖的模式如何——实例字段(这永远不会起作用,因为结构将是无限大的)、静态字段、实现的通用接口(interface), 或通用参数。可以在编译时通过将循环中的某些结构更改为类来打破这些结构类型循环,或者在运行时通过 object
或接口(interface)和转换来打破这些结构类型循环。
另见 corresponding CLR issue .
我是一名优秀的程序员,十分优秀!