ala*_*ere 21 c# constructor struct member cyclic-reference
这是我的一些代码的简化版本:
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,并给它一个成员函数来返回我在传递它时使用的副本.实际上模拟与结构相同但具有类的行为.
我在寻找答案时也创建了以下问题.
Mar*_*ers 31
拥有一个包含自己作为成员的结构是不合法的.这是因为结构具有固定的大小,并且它必须至少与其每个成员的大小之和一样大.您的类型必须为两个浮点数提供8个字节,至少一个字节用于显示是否info为空,加上另一个浮点数的大小info.这给出了以下不等式:
size of info >= 4 + 4 + 1 + size of info
Run Code Online (Sandbox Code Playgroud)
这显然是不可能的,因为它需要你的类型无限大.
您必须使用引用类型(即类).您可以使您的类不可变并覆盖Equals并GetHashCode提供类似于String类的类似行为的行为.
Jar*_*Par 11
这创造一个循环的原因是它Nullable<T>本身就是一个struct.因为它指的是info你在布局中有一个循环(info有一个字段,Nullable<info>它有一个字段info).它基本上等同于以下内容
public struct MyNullable<T> {
public T value;
public bool hasValue;
}
struct info {
public float a, b;
public MyNullable<info> next;
}
Run Code Online (Sandbox Code Playgroud)
真正的问题在于这一行:
public info? c;
Run Code Online (Sandbox Code Playgroud)
由于这是一个struct,C# 需要知道内部info/s 布局,然后才能生成外部info布局。并且内部info包括内部内部info,内部内部又包括内部内部内部info,依此类推。由于此循环引用问题,编译器无法生成布局。
注意:info? c是一个简写,Nullable<info>它本身就是一个struct.