使用c#结构的域模型中的循环引用

本文关键字:循环 引用 模型 结构 使用 | 更新日期: 2023-09-27 18:01:12

当两个结构之间存在循环引用时会发生什么?对于下面的例子,内存分配是如何工作的,还是会产生错误?

    public struct MultipleChoiceQuestion
    {
        public IEnumerable<Option> Options;
    }
    public struct Option
    {
        public MultipleChoiceQuestion Question;
    }

使用c#结构的域模型中的循环引用

MultipleChoiceQuestion中的Options字段只是此处的引用,默认情况下为nullOption中的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结构。