20

読み取り専用フィールドは、後で変更してはならないオブジェクトの設定時に認識される変数がある場合に使用する必要があります。

ただし、サブクラスのコンストラクターから読み取り専用フィールドを割り当てることはできません。スーパークラスが抽象クラスの場合でも、これは機能しません。

これが良い考えではない、または C# 言語に欠けている理由を説明できる人はいますか?

abstract class Super
{
    protected readonly int Field;
}

class Sub : Super 
{
    public Sub()
    {
        this.Field = 5; //Not compileable
    }
}

PS:もちろん、スーパークラスの保護されたコンストラクターで読み取り専用フィールドを割り当てることで、同じ結果に到達できます。

4

5 に答える 5

13

これについて私が見ることができる唯一の理由は、仕様に従って、「そのように設計された」ためです。

読み取り専用フィールドへの直接割り当ては、その宣言の一部として、または同じクラスのインスタンス コンストラクターまたは静的コンストラクターでのみ行うことができます。

読み取り専用のポイントは、変更できないことです。派生クラスが変更できる場合、これはもはや真実ではなく、カプセル化に違反します (別のクラスの内部を変更することにより)。

于 2011-10-09T20:56:21.883 に答える
11
public class Father
{
    protected readonly Int32 field;

    protected Father (Int32 field)
    {
        this.field = field;
    }
}

public class Son : Father
{
    public Son() : base(5)
    {

    }
}

代わりに、このようなものを試すことができます。

于 2011-10-09T20:59:51.633 に答える
2

これは、C#の抽象/仮想プロパティでモデル化します。

abstract class Super {
  protected abstract int Field { get; }
}

class Sub : Super {
  protected override int Field { get { return 5; } }
}

私の意見では、これは、すべての読み取り専用フィールドをパラメーターとして含むコンストラクターを使用するよりも優れたソリューションです。1つは、コンパイラーがこれもインライン化できることと、コンストラクターソリューションが派生クラスで次のようになるためです。

class Sub : Super {
  public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}

また、単一のint値をとるコンストラクターがすでにある場合は、これが機能しない可能性があります。

于 2011-10-09T21:05:21.673 に答える
0

主な理由は、すべての .NET 言語の実装が複雑になることだと思います

また、常に簡単な回避策があります。

 abstract class Super
 {
     protected readonly int Field;

     protected Super(int field)
     {
          this.Field = field;
     }
 }


class Sub : Super {
   public Sub():base(5)
   {
   }

}

于 2011-10-09T21:00:26.677 に答える
0

スーパークラスで保護されたコンストラクターを使用することをお勧めします (alexm で言及されているように)、xml コメントを使用します。これにより、DonAndre がコード コメントで述べた問題が解消されるはずです。

于 2012-04-11T18:18:38.517 に答える