6

どこからでも割り当てることができるフィールドが必要ですが、一度だけ割り当てることができるはずです(したがって、後続の割り当ては無視する必要があります)。これどうやってするの?

4

3 に答える 3

17

その場合、それは読み取り専用フィールドではありません。実際の読み取り専用フィールドを初期化するための唯一のオプションは、フィールド初期化子とコンストラクターです。

ただし、プロパティを使用して一種の読み取り専用機能を実装することはできます。フィールドをプロパティとして作成します。読み取り専用部分へのこれ以上の更新が許可されないことを示すフラグを反転させる「インスタンスのフリーズ」メソッドを実装します。セッターにこのフラグをチェックしてもらいます。

ランタイムチェックのためにコンパイル時チェックをあきらめていることに注意してください。コンパイラは、宣言/コンストラクタ以外の場所から読み取り専用フィールドに値を割り当てようとした場合に通知します。以下のコードでは、例外が発生します(または、更新を無視することもできます。どちらも最適なIMOではありません)。

編集:チェックの繰り返しを避けるために、読み取り専用機能をクラスにカプセル化できます。

改訂された実装は次のようになります。

class ReadOnlyField<T> {
    public T Value {
        get { return _Value; }
        set { 
            if (Frozen) throw new InvalidOperationException();
            _Value = value;
        }
    }
    private T _Value;

    private bool Frozen;

    public void Freeze() {
        Frozen = true;
    }
}


class Foo {
    public readonly ReadOnlyField<int> FakeReadOnly = new ReadOnlyField<int>();

    // forward to allow freeze of multiple fields
    public void Freeze() {
        FakeReadOnly.Freeze();
    }
}

次に、コードは次のようなことを行うことができます

        var f = new Foo();

        f.FakeReadOnly.Value = 42;

        f.Freeze();

        f.FakeReadOnly.Value = 1337;

最後のステートメントは例外をスローします。

于 2009-10-20T07:14:59.803 に答える
1

次のことを試してください。

class MyClass{
private int num1;

public int Num1
{
   get { return num1; }

}


public MyClass()
{
num1=10;
}

}
于 2009-10-20T07:58:23.037 に答える
0

それとも、誰もが読み取ることができるが、クラス自体だけが書き込むことができるフィールドを意味しますか?その場合は、パブリックゲッターとプライベートセッターでプライベートフィールドを使用します。

private TYPE field;

public TYPE Field
{
   get { return field; }
   private set { field = value; }
}

または自動プロパティを使用します。

public TYPE Field { get; private set; }
于 2009-10-20T07:24:43.163 に答える