结构中的自引用泛型成员 [英] Self referencing generic member in struct

查看:48
本文介绍了结构中的自引用泛型成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要加深对使用泛型时如何编译结构的理解.

I need to broaden my understanding of how structs are compiled when using generics.

我有以下有效的代码

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"

This prints 'Size of test is: 4'

但是,如果我更改TestStruct以尝试提供其自己的大小:

However, if I change TestStruct to attempt to provide its own size:

public struct TestStruct
{
    public GenericStruct<TestStruct> Header;
    public int TestValue;
}

我收到运行时错误: System.TypeLoadException:无法从程序集中加载类型'TestStructGenerics.TestStruct'.

我猜想这与编译器无法创建struct编译时间有关.也许在处理通用分辨率时循环引用有问题.

I'm guessing it has to do with the compiler being unable to create the struct compile time. Or perhaps a problem with circular references when handling the generic resolution.

我刚刚意识到,将第二种情况更改为:

I just realized that I can achieve what I want by changing the second case to:

public struct TestStruct
{
    public GenericStruct<TestStruct> Header => new GenericStruct<TestStruct>();
    public int TestValue;
}

推荐答案

根据这是Roslyn问题,目前尚不清楚此问题是CLR类型加载器限制还是此类程序是否无效,如果无效,则C#编译器是否应该检测到该错误并发出错误.实际上,看来,除非当局做出决定,否则无论结构引入依赖关系的方式如何,我们都必须避免结构之间的类型循环-实例字段(实例结构(因为结构将是无限大小)而永远无法工作),静态字段,已实现的泛型接口,或通用参数.可以在编译时通过将循环中的某些结构更改为类来破坏这些struct类型的循环,或者在运行时通过 object 或接口并进行强制转换.

According to Eric Lippert's comments in this Roslyn issue, it is unclear whether this problem is a CLR type loader limitation or whether programs of this sort are invalid, and, if they are invalid, whether the C# compiler should detect it and emit an error. Practically, it appears that, until the authorities decide, we have to avoid type loops between structs regardless of the mode that introduces dependence - instance field (that's never going to work because the struct would be infinite size), static field, implemented generic interface, or generic argument. One can break these struct type loops at compile time by changing some struct in the loop to a class, or at run time by going through object or interface and casting.

另请参见相应的CLR问题.

这篇关于结构中的自引用泛型成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆