ReadonlyプロパティとGet onlyプロパティを使用する必要がある場合


100

.NETアプリケーションでは、「ReadOnly」プロパティを使用する必要があるときと、「Get」だけを使用するとき。これら2つの違いは何ですか。

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

または

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
C#> 5の場合、getプロパティを次のように削減できますpublic double FuelConsumption => Fuel;
meJustAndrew

回答:


121

ゲッターのみを使用してプロパティを作成すると、プロパティはクラス外のコードに対して読み取り専用になります。

ただし、クラスが提供するメソッドを使用して値を変更できます。

public class FuelConsumption {
    private double fuel;
    public double Fuel
    {
        get { return this.fuel; }
    }
    public void FillFuelTank(double amount)
    {
        this.fuel += amount;
    }
}

public static void Main()
{
    FuelConsumption f = new FuelConsumption();

    double a;
    a = f.Fuel; // Will work
    f.Fuel = a; // Does not compile

    f.FillFuelTank(10); // Value is changed from the method's code
}

クラスのプライベートフィールドをas readonlyに設定すると、フィールド値を1回だけ設定できます(インライン割り当てまたはクラスコンストラクターを使用)。後で変更することはできません。

public class ReadOnlyFields {
    private readonly double a = 2.0;
    private readonly double b;

    public ReadOnlyFields()
    {
        this.b = 4.0;
    }
}

readonly クラスフィールドは、クラスの構築中に初期化される変数によく使用され、後で変更されることはありません。

つまり、プロパティ値が外部から変更されないようにする必要があるが、クラスコード内から変更できるようにする必要がある場合は、「取得専用」プロパティを使用します。

初期値が設定されたら変更されない値を格納する必要がある場合は、readonlyフィールドを使用します。


14
+ 1(コード例)。ただし、「Get-Only」プロパティは、クラスフィールドにラップされている場合にのみ、クラスメソッドによって変更できることを明確にする必要があります。セッターが存在しない場合、クラスメソッドによっても直接変更することはできません。そうしようとすると、コンパイラエラーが発生します。
Devraj Gadhavi 2013年

13

C#6以降では、「読み取り専用の自動プロパティ」を1行で宣言して初期化できます。

double FuelConsumption { get; } = 2;

コンストラクタから値を設定できますが、他のメソッドは設定できません。


7

ゲッターのみを持つプロパティは、読み取り専用と呼ばれます。プロパティの値を(外部から)変更するために、セッターが提供されていないためです。

C#にはreadonlyというキーワードがあり、フィールドではなくプロパティで使用できます。「読み取り専用」としてマークされているフィールドは、オブジェクトの構築中に(コンストラクターで)1回だけ設定できます。

private string _name = "Foo"; // field for property Name;
private bool _enabled = false; // field for property Enabled;

public string Name{ // This is a readonly property.
  get {
    return _name;  
  }
}

public bool Enabled{ // This is a read- and writeable property.
  get{
    return _enabled;
  }
  set{
    _enabled = value;
  }
} 

2

readonlyプロパティは、フェイルセーフコードを作成するために使用されます。プロパティとバッキングフィールドに関するMark Seemannのカプセル化投稿シリーズが本当に好きです。

http://blog.ploeh.dk/2011/05/24/PokayokeDesignFromSmellToFragrance.aspx

マークの例から:

public class Fragrance : IFragrance
{
    private readonly string name;

    public Fragrance(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }

        this.name = name;
    }

    public string Spread()
    {
        return this.name;
    }
}

この例では、読み取り専用の名前フィールドを使用して、クラス不変式が常に有効であることを確認します。この場合、クラス作成者は、名前フィールドが1回だけ(不変)に設定され、常に存在することを確認したいと考えていました。


0

メソッドは、値を返すために何かが起こる必要があることを示唆し、プロパティは、値がすでにそこにあることを示唆します。これは経験則であり、少しだけ機能するプロパティが必要になる場合があります(つまりCount)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.