2

2つの構造体の間に循環参照があるとどうなりますか?以下の例では、メモリ割り当てはどのように機能しますか、それともエラーが発生しますか?

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

    public struct Option
    {
        public MultipleChoiceQuestion Question;
    }
4

3 に答える 3

3

OptionsフィールドはMultipleChoiceQuestionここでの単なる参照であり、nullデフォルトで表示されます。のQuestionフィールドOptionはタイプの値でMultipleChoiceQuestionあり、デフォルトでデフォルト値になります。ここでは問題はありません(複数の点で疑わしい設計を除いて)。

論理メモリの問題につながる真の循環参照は、コンパイルに失敗します。

struct Foo
{
    Bar bar;
}

struct Bar
{
    Foo foo;
}

Test.cs(6,9):エラーCS0523:タイプ「Bar」の構造体メンバー「Foo.bar」により、構造体レイアウトでサイクルが発生しますTest.cs(11,9):エラーCS0523:構造体メンバー「Bar.foo」タイプ「Foo」の構造体レイアウトでサイクルが発生します

于 2011-07-04T16:30:32.470 に答える
2

質問(プロパティ)はカプセル化です。質問は、フィールドを介した外部構造体の一部です。

ただし、オプションは、1つ以上のオプションを生成する外部オブジェクトへの参照です。これらは毎回コピーされます。

ここには他にもいくつかの間違いがあります。

  • 可変構造体:EVIL
  • パブリックフィールド:EVIL
  • オプションはリストとしてより良いでしょう。すべての列挙可能なものが再現可能であるとは限りません
  • それらは「値」ではないので、構造体であってはなりません。代わりにクラスを使用してください

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;}
}
于 2011-07-04T16:30:08.287 に答える
0

MultipleChoiceQuestion、IEnumerableであるオブジェクトへの参照(ポインター)を持っているだけなので、スタック上のその構造体のサイズは、単一のIntPtr(x86マシンでは4バイト)になります。

Option構造体のみが含まれているため、構造体のサイズは同じになりますMultipleChoiceQuestion

于 2011-07-04T16:30:17.523 に答える