使用c#结构的域模型中的循环引用
本文关键字:循环 引用 模型 结构 使用 | 更新日期: 2023-09-27 18:01:12
当两个结构之间存在循环引用时会发生什么?对于下面的例子,内存分配是如何工作的,还是会产生错误?
public struct MultipleChoiceQuestion
{
public IEnumerable<Option> Options;
}
public struct Option
{
public MultipleChoiceQuestion Question;
}
MultipleChoiceQuestion
中的Options
字段只是此处的引用,默认情况下为null
。Option
中的Question
字段是类型为MultipleChoiceQuestion
的值,默认情况下该值将具有其默认值。这里没有问题(除了在很多方面有问题的设计(。
导致逻辑内存问题的真正循环引用将无法编译:
struct Foo
{
Bar bar;
}
struct Bar
{
Foo foo;
}
Test.cs(6,9(:错误CS0523:"bar"类型的结构成员"Foo.bar"导致结构布局中的循环Test.cs(11,9(:error CS0523:"foo"类型的结构成员"Bar.foo"导致结构布局中的循环
Question(属性(是封装;问题是外部结构的一部分,通过一个字段。
但是,Options是对生成一个或多个Options的外部对象的引用;每次都会复制这些。
这里还有其他几个错误:
- 可变结构:EVIL
- 公共字段:EVIL
- 选项列表会更好;并非所有可枚举项都是可重复的
- 它们不是"值",所以它们不应该是structs;改为使用类
IMO:
public class MultipleChoiceQuestion
{
private readonly List<Option> options
= new List<Option>();
public IList<Option> Options {get { return options; } }
}
public class Option
{
public MultipleChoiceQuestion Question {get;set;}
}
MultipleChoiceQuestion
将只具有一个指向IEnumerable对象的引用(指针(,因此堆栈上该结构的大小将是一个IntPtr(在x86机器上为4字节(。
Option
结构将具有相同的大小,因为它只包含MultipleChoiceQuestion
结构。