次の C# クラスを検討してください。
public class Person
{
public string Name {get;set}
public int Age {get;set}
}
これは、単一のパラメーターを持つ関数でいくつかの変数を渡すためにのみ使用します-構造体を使用する方が良い方法でしょうか?
編集:値が変更されても気にしません。とにかく変更することは想定されていません。
Eric Lippert の優れた「スタックは実装の詳細です」の下部から:
型が意味的に値を表しているのか、意味的に何かへの参照を表しているのかに基づいて、常に値型と参照型の選択を行います。
つまり、2 つのPerson
変数間の等価性はどのように定義されるのでしょうか?それらに同じ値が含まれている場合、またはそれらが 1 つのインスタンスへの 2 つの参照である場合はどうすればよいでしょうか?
それは、値を渡した後に何が起こるかについてのあなたの期待に依存します。関数呼び出しが終了した後に保持される値の変更を気にしない場合は、それを構造体にすることができますが、変更を行うために person 引数を取る関数が必要で、呼び出し元がそれを見る必要がある場合は、クラス 。
また、これがドメイン モデル/データ レイヤーの一部である場合は、クラスに固執します。
それはあなたの条件に依存します。継承したくない場合や、オブジェクト内で変更を加えたくない場合は (値の型であるため)、構造体を使用できます。
それ以外の場合は、特に継承の概念を適用するためにクラスが最適です。
これは重複している可能性があります:データストアの構造体/クラスに最適なのはどれですか?
MSDNから:
クラスは参照型です。クラスのオブジェクトが作成されると、オブジェクトが割り当てられる変数は、そのメモリへの参照のみを保持します。オブジェクト参照が新しい変数に割り当てられると、新しい変数は元のオブジェクトを参照します。どちらの変数も同じデータを参照するため、一方の変数で行われた変更は他方の変数に反映されます。
構造体は値型です。構造体が作成されると、構造体が割り当てられた変数が構造体の実際のデータを保持します。構造体が新しい変数に割り当てられると、それがコピーされます。したがって、新しい変数と元の変数には、同じデータの 2 つの別個のコピーが含まれます。1 つのコピーに加えられた変更は、他のコピーには影響しません。
一般に、クラスは、より複雑な動作や、クラス オブジェクトの作成後に変更する予定のデータをモデル化するために使用されます。構造体は、構造体の作成後に変更する予定のないデータを主に含む小さなデータ構造に最適です。
私の経験則;
とりわけ、構造体を使用すると、これが機能しなくなります。
私の傾向は、(プロパティではなく) パブリック フィールドを持つ単純な構造体を使用することです。このような構造体の素晴らしい点は、フィールドの名前と型を除けば、すべて同じように動作することです。公開されたフィールドMyPeople[]
を持つ構造体の配列が与えられた場合、それが に影響を与えないことがわかります。対照的に、他の点では同一のクラスである場合、そのような保証はありません。読み書き可能なプロパティを持つ構造体であったとしても、プロパティが実際に構造体フィールドのように動作するかどうか、またはクラス オブジェクトに格納されているものにアクセスするかどうかは、その定義を見ないとわかりません。Person
Name
MyPeople[0].Name = "George";
MyPeople[1].Name
Person
Person
Name
一般的にフィールドよりもプロパティを好む理由は、単純な構造体には当てはまらないことに注意してください。オブジェクトがクラス型Fred
のフィールドGeorge
を保持し、それによって参照されるオブジェクトへの参照を外部の世界に公開している場合、そのオブジェクトのプロパティが認識または同意なしに変更されないFred
ことを知る唯一の方法は、George
クラスGeorge
は、少なくとも通知することなく、これらのプロパティを変更させませんFred
(多くの場合、George
どのような状況でもプロパティを変更させないことを単に約束するのが最も簡単です)。対照的に、公開されたフィールド構造体型のFred
フィールドを保持する場合、のフィールドのいずれかが変更されずに変更される方法はありません。Ronald
Ronald
Fred
の知識と同意。誰もFred
それらのフィールドを操作できず、構造体に必要なものを知っているので、必要な不変条件を維持する責任を負うFred
のが最も簡単です。Fred