18

抽象クラスがあり、保護されたコンストラクターで読み取り専用フィールドを初期化したいと思います。この読み取り専用フィールドを派生クラスで使用できるようにしたいと思います。

すべてのフィールドをプライベートにしてプロパティを公開するという私の習慣に従って、これを次のように実装しました。

abstract class Foo
{
    private readonly int _field;

    protected Foo(int field)
    {
        _field = field;
    }

    protected int Field
    {
        get { return _field; }
    }
}

しかし、私はここでフィールドをプライベートに保つことの本当に多くの利点があるのだろうかと思いました。私はプロパティの利点を認識しており、この問題に関して一般的にいくつかのSOの質問がありますが、それらは保護されたフィールドではなく、パブリックフィールドに焦点を当てています。

では、以下の実装に切り替える必要がありますか?どちらの場合でも知っておくべき考慮事項と長所/短所は何ですか?

abstract class Foo
{
    protected readonly int _field;

    protected Foo(int field)
    {
        _field = field;
    }
}
4

7 に答える 7

12

派生クラスは元のコードの「ユーザー」のままです。フィールドもそれらからカプセル化する必要があります。

基本クラスは、内部を公開する単なるクラスではなく、安全で拡張可能な API と考える必要があります。フィールドを非公開に保ちます-何も別として、基本クラスがそのプロパティの値の生成方法を変更できるようにします:)

于 2012-10-23T11:21:56.327 に答える
1

読み取り専用プロパティは C# 6.0 で実装されました。これは次のように簡単です。

protected Foo(int field)
{
    Field = field;
}

protected int Field { get; }
于 2016-11-17T15:28:29.420 に答える
0
abstract class Foo
{
    protected readonly int _field;

    protected Foo(int field)
    {
        _field = field;
    }
}

派生クラスに認識させたい場合に適しています。タイプではないクラスは にFooアクセスできません_field

于 2012-10-23T11:22:01.080 に答える
0

リフレクションを使用すると、読み取り専用フィールドを簡単に上書きできます。プロパティを使用すると、フィールドが非表示になるため、難しくなります (まだ実行できます)。したがって、問題なくゲッターを変更できるため、とにかくクリーンなプロパティを好むでしょう。

パフォーマンスについて考えている場合: ほとんどの場合、プロパティはインライン化されます。

読み取り専用のオーバーライド

class Program
{
    static void Main(string[] args)
    {
        Test t = new Test();
        t.OverrideReadonly("TestField", 5);
        t.OverrideReadonly("TestField2", 6);
        t.OverrideReadonly("TestField3", new Test());
    }
}

class Test
{
    protected readonly Int32 TestField = 1;
    protected readonly Int32 TestField2 = 2;
    protected readonly Test TestField3 = null;

    public void OverrideReadonly(String fieldName, Object value)
    {
        FieldInfo field = typeof(Test).GetField(fieldName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        field.SetValue(this, value);
    }
}
于 2012-10-23T11:22:53.133 に答える
-2

プライベート フィールドと保護されたゲッターを使用すると、わずかな利点があります。追加レベルの間接化が発生しません。

プロパティを宣言する C# の省略形を忘れないでください。

protected int Field { protected get; private set; }
于 2012-10-23T11:22:14.237 に答える