Const-correctnessのポイントは、ユーザーが変更または削除できないインスタンスのビューを提供できることです。コンパイラーは、const関数内からconstnessを解除するとき、またはconstオブジェクトの非const関数を使用しようとするときに指摘することにより、これをサポートします。 constアプローチをコピーせずに、同じ目的を持つC#で使用できる方法はありますか?
私は不変性を知っていますが、名前を付けるためにコンテナーオブジェクトに実際に引き継がれるわけではありませんが、1つの例を示します。
私もこの問題に何度も遭遇し、インターフェースを使用することになりました。
C#は任意の形式、あるいはC++の進化形でさえあるという考えを捨てることが重要だと思います。これらは、ほぼ同じ構文を共有する2つの異なる言語です。
私は通常、クラスの読み取り専用ビューを定義することにより、C#で「constの正確さ」を表現します。
public interface IReadOnlyCustomer
{
String Name { get; }
int Age { get; }
}
public class Customer : IReadOnlyCustomer
{
private string m_name;
private int m_age;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public int Age
{
get { return m_age; }
set { m_age = value; }
}
}
Const-craziness(または関数型プログラミング用語の純粋さ)の利点を得るには、c#のStringクラスと同様に、クラスが不変になるようにクラスを設計する必要があります。
不変クラスを使用すると、マルチタスク環境でデータを簡単に渡すことができるため、このアプローチはオブジェクトを読み取り専用としてマークするよりもはるかに優れています。
System.Collections.Genericsコンテナの多くに、不変のコレクションを返すAsReadOnlyメソッドがあることをお知らせしておきます。
インターフェースは答えであり、実際にはC++の「const」よりも強力です。 constは、「const」が「メンバーを設定しないか、メンバーを設定するものを呼び出さない」と定義されている問題に対する万能のソリューションです。これは、多くのシナリオでconst-nessの良い省略形ですが、すべてではありません。たとえば、一部のメンバーに基づいて値を計算するだけでなく、結果をキャッシュする関数について考えます。 C++では、これは非定数と見なされますが、ユーザーの観点からは本質的に定数です。
インターフェイスを使用すると、クラスから提供する機能の特定のサブセットをより柔軟に定義できます。 const-nessが必要ですか?変更するメソッドのないインターフェースを提供するだけです。一部の設定のみを許可し、他の設定は許可しませんか?それらのメソッドだけのインターフェースを提供します。
不変オブジェクトを作成するためにコンストラクターで初期化する読み取り専用フィールドを使用する他のいくつかに同意します。
public class Customer
{
private readonly string m_name;
private readonly int m_age;
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
}
public int Age
{
get { return m_age; }
}
}
または、プロパティにアクセススコープを追加することもできます(例:public getおよびprotected set?)
public class Customer
{
private string m_name;
private int m_age;
protected Customer()
{}
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
protected set { m_name = value; }
}
public int Age
{
get { return m_age; }
protected set { m_age = value; }
}
}
readonlyの問題は、参照(ポインタ)が一定であることのみを許可することです。参照(ポイント)されているものは、引き続き変更できます。これはトリッキーな部分ですが、それを回避する方法はありません。定数オブジェクトを実装するということは、変更可能なメソッドやプロパティを公開しないことを意味しますが、これは厄介です。
参照 有効なC#:C#を改善するための50の特定の方法 (項目2-constよりも読み取り専用を優先する)