回答:
ゲッターのみを使用してプロパティを作成すると、プロパティはクラス外のコードに対して読み取り専用になります。
ただし、クラスが提供するメソッドを使用して値を変更できます。
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フィールドを使用します。
ゲッターのみを持つプロパティは、読み取り専用と呼ばれます。プロパティの値を(外部から)変更するために、セッターが提供されていないためです。
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;
}
}
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回だけ(不変)に設定され、常に存在することを確認したいと考えていました。
メソッドは、値を返すために何かが起こる必要があることを示唆し、プロパティは、値がすでにそこにあることを示唆します。これは経験則であり、少しだけ機能するプロパティが必要になる場合があります(つまりCount)。
public double FuelConsumption => Fuel;