这是我的一些代码的简化版本:
public struct info
{
public float a, b;
public info? c;
public info(float a, float b, info? c = null)
{
this.a = a;
this.b = b;
this.c = c;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是Struct member 'info' causes a cycle in the struct layout.我在结构之后的错误,就像值类型行为一样.我可以使用类和克隆成员函数来模拟这个,但我不明白为什么我需要.
这个错误怎么样?在某些类似的情况下,递归可能会永远导致构造,但在这种情况下我无法想到它的任何方式.下面是程序编译时应该没问题的例子.
new info(1, 2);
new info(1, 2, null);
new info(1, 2, new info(3, 4));
Run Code Online (Sandbox Code Playgroud)
编辑:
我使用的解决方案是使"info"成为一个类而不是一个struct,并给它一个成员函数来返回我在传递它时使用的副本.实际上模拟与结构相同但具有类的行为.
我在寻找答案时也创建了以下问题.
创建一个控制台应用程序来重现:
struct Test
{
public static readonly Test? Null = null;
}
class Program
{
static void Main(string[] args)
{
var t = Test.Null;
}
}
Run Code Online (Sandbox Code Playgroud)
它是可编译的,但我们将在运行时具有以下内容:
mscorlib.dll中发生了未处理的"System.TypeLoadException"类型异常.附加信息:无法从程序集"ConsoleApplication17,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null"加载类型"ConsoleApplication17.Test".
这种方法解决了这个问题:
struct Test
{
public static Test? Null => null;
}
Run Code Online (Sandbox Code Playgroud) public struct MyStruct {
static MyStruct? myProperty;
}
Run Code Online (Sandbox Code Playgroud)
试图编译这将给我错误:
Struct member 'myStruct.myProperty' causes a cycle in the struct layout.
从我收集的内容来看,这个错误通常发生在一个struct 的实例包含它自己的struct作为属性时(这对我来说很有意义).
但在这里,它是一个静态属性,所以我不知道这样的递归是如何发生的.另外,只有在声明Nullable结构时才会发生错误,声明静态非可空是安全的.
究竟发生了什么会导致一个循环?
编辑:
我确实发现了我认为是重复的问题; 它解释了为什么当实例具有自己类型的成员时发生递归,但这是关于静态成员的.我从经验中知道struct可以拥有自己类型的静态成员,这些成员在运行时不会中断,这个特定的代码似乎只是因为静态成员是Nullable而中断.
其次,多个人马上告诉我代码为他们编译; 似曾相识,我正在使用的c#的"版本"是针对Unity的,所以我认为这是他们的编译器的另一个错误,我将向他们提出这个问题.
@Evk指出这实际上是一个常见问题:https:
//github.com/dotnet/roslyn/issues/10126
例:
struct Id<T> {
int id;
}
struct Thing {
public Id<Thing> id;
}
Run Code Online (Sandbox Code Playgroud)
这导致循环结构布局,但我没有看到循环.如果Id有一个T类型的字段,sizeof将是未定义的,但它不是.
这是一个单声道的bug,还是规范的一部分?