【发布时间】:2018-04-20 15:20:02
【问题描述】:
我需要加深对使用泛型时如何编译结构的理解。
我有以下代码,它可以工作
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: Could not load type 'TestStructGenerics.TestStruct' from assembly.
我猜这与编译器无法创建结构编译时间有关。或者在处理通用解析时可能存在循环引用问题。
编辑:
我刚刚意识到我可以通过将第二种情况更改为:
public struct TestStruct
{
public GenericStruct<TestStruct> Header => new GenericStruct<TestStruct>();
public int TestValue;
}
【问题讨论】:
-
问题是你打算这样做。您的结构包含另一个具有泛型类型 T 的结构,这是第一个包含另一个具有泛型类型 T 的结构的结构,这是第一个包含另一个具有泛型类型 T 的结构的结构,这是第一个包含另一个结构的结构...你知道这是往哪里走吗?您已经创建了一个编译时递归类型定义。编译器本可以足够聪明地检测到这一点,但显然没有,但无论哪种方式,这是什么意思?
-
那个递归定义永远行不通,因为它没有意义。
-
@LasseV.Karlsen 这就是我的想法。我原以为它会给我提供编译时错误,但显然不是。
-
递归本身并不是一个充分的解释,因为将
TestStruct或GenericStruct更改为class可以消除有问题的行为。这是在结构中处理泛型参数的方式所特有的。