public struct Unit
{
Unit u;
}
原因:
“单元”类型的结构成员“Unit.u”会在结构中生成一个循环 布局。
但是
public class Unit
{
Unit u;
}
编译。我理解我认为的问题。引用Unit
对象时将形成无限循环,因为它必须初始化另一个成员Unit
,依此类推。但是为什么编译器只为structs
限制问题? class
问题是否仍然存在?我错过了什么吗?
答案 0 :(得分:21)
问题在于布局。
当Unit
是结构时,Unit
的任何值都必须包含相同类型的另一个值(因此大小相同),无限制。这不可能。我想你可以说,在没有其他字段的情况下,Unit
的字段不会占用任何内存,因此可以在其中包含它 - 但我相信CLR的工作方式可以确保所有结构至少占用1个字节...
当Unit
是一个类时,Unit
对象只需要包含引用到另一个Unit
对象。没有存储问题,并且值可以为null。
可以这样想:你不能拥有一栋房屋,其中包含另一栋由同一块蓝图建造的房屋,但你当然可以拥有一幢房子,里面有一张纸,上面有类似房屋的地址...... / p>
答案 1 :(得分:3)
类是引用类型,所以我想不同的是,在class
示例中,它只需要保存对另一个实例的引用。对于struct
,一个值类型,它需要再次包含整个结构,因此是一个无限循环。
答案 2 :(得分:2)
struct
会自动使用值初始化,因此在您的示例中,Unit
值包含Unit
值,其中包含Unit
值,其中包含{ {1}}价值等......
您的Unit
示例仅初始化对class
的引用,该引用没有无限回归。但是,如果您执行以下操作,则会遇到类似的问题:
null
现在,构建一个class Unit
{
Unit mUnit = new Unit();
}
构造一个Unit
,构造一个Unit
等等......在这种情况下,如果/当你尝试时,你会遇到一个运行时堆栈溢出异常实例化Unit
对象。
我认为您可以通过使用可空类型来避免Unit
问题,但问题仍然存在。我相信这是因为当设置为struct
时,仍可以实例化{nullable struct
。
答案 3 :(得分:1)
因为Struct
是value type
。 Unit
可以保持价值吗?我认为这是不可能的。
但当Unit
为class
时,class
为reference type
。 Unit
对象可以将引用保存到另一个Unit
对象。没关系。