注
このコンテンツは、 フレームワーク設計ガイドライン (再利用可能な .NET ライブラリの規則、イディオム、パターン、第 2 版) から、Pearson Education, Inc. のアクセス許可によって再印刷されます。 そのエディションは2008年に出版され、その後 、本は第3版で完全に改訂されています。 このページの情報の一部が古くなっている可能性があります。
プロパティは技術的にはメソッドに非常に似ていますが、使用シナリオの点では大きく異なります。 スマート フィールドと見なす必要があります。 フィールドの呼び出し構文と、メソッドの柔軟性があります。
✔️ 呼び出し元がプロパティの値を変更できない場合は、取得専用プロパティを作成してください。
プロパティの型が変更可能な参照型の場合、プロパティが取得専用の場合でも、プロパティ値を変更できることに注意してください。
❌ セットのみのプロパティや getter よりも広いアクセシビリティを持つ setter を持つプロパティは、提供しないでください。
たとえば、パブリック セッターとプロテクトされたゲッターを持つプロパティは使用しないでください。
プロパティ ゲッターを指定できない場合は、代わりにメソッドとして機能を実装します。
Setでメソッド名を開始し、プロパティに名前を付けたものに従うことを検討してください。 たとえば、AppDomainには、SetCachePath というセットのみのプロパティを持つ代わりに、CachePath というメソッドがあります。
✔️ すべてのプロパティに適切な既定値を指定して、既定値がセキュリティ ホールや非常に非効率的なコードにならないことを確認してください。
✔️ オブジェクトの一時的な無効な状態が発生した場合でも、プロパティを任意の順序で設定できます。
同じオブジェクト上の他のプロパティの値を指定すると、1 つのプロパティの一部の値が無効になる可能性がある点に、2 つ以上のプロパティが相互に関連することが一般的です。 このような場合、無効な状態に起因する例外は、相互に関連するプロパティがオブジェクトによって実際に一緒に使用されるまで延期する必要があります。
✔️ プロパティ セッターが例外をスローする場合は、以前の値を維持してください。
❌ プロパティゲッターから例外をスローしないようにします。
プロパティゲッターは単純な操作であり、前提条件を持つべきではありません。 getter が例外を発生させ得る場合は、おそらくメソッドとして再設計する必要があります。 この規則はインデクサーには適用されないことに注意してください。この場合、引数の検証の結果として例外が想定されます。
インデックス付きプロパティのデザイン
インデックス付きプロパティは、パラメーターを持つ特殊なプロパティであり、配列のインデックス作成と同様の特別な構文を使用して呼び出すことができます。
インデックス付きプロパティは、一般にインデクサーと呼ばれます。 インデクサーは、論理コレクション内の項目へのアクセスを提供する API でのみ使用する必要があります。 たとえば、文字列は文字のコレクションであり、 System.String のインデクサーがその文字にアクセスするために追加されました。
✔️ インデクサーを使用して、内部配列に格納されているデータへのアクセスを提供することを検討してください。
✔️ 項目のコレクションを表す型にインデクサーを提供することを検討してください。
❌ 複数のパラメーターでインデックス付きプロパティを使用しないでください。
デザインに複数のパラメーターが必要な場合は、プロパティが論理コレクションのアクセサーを実際に表しているかどうかを再検討します。 そうでない場合は、代わりにメソッドを使用します。
GetまたはSetでメソッド名を開始することを検討してください。
❌ System.Int32、System.Int64、System.String、System.Object、または列挙型以外のパラメーター型を持つインデクサーを回避します。
デザインに他の種類のパラメーターが必要な場合は、API が論理コレクションのアクセサーを実際に表しているかどうかを強く再評価します。 そうでない場合は、メソッドを使用します。
GetまたはSetでメソッド名を開始することを検討してください。
✔️ 明らかに適切な名前がない限り、インデックス付きプロパティに名前Itemを使用してください (例: Chars[]のSystem.Stringプロパティを参照)。
C# では、インデクサーは既定で Item という名前です。 IndexerNameAttributeを使用して、この名前をカスタマイズできます。
❌ 意味的に同等のインデクサーとメソッドの両方を提供しないでください。
❌ 1 つの型でオーバーロードされたインデクサーの複数のファミリを提供しないでください。
これは C# コンパイラによって適用されます。
❌ 既定以外のインデックス付きプロパティは使用しないでください。
これは C# コンパイラによって適用されます。
プロパティ変更通知イベント
プロパティ値の変更をユーザーに通知するイベントを提供すると便利な場合があります。 たとえば、System.Windows.Forms.Controlは、TextChanged プロパティの値が変更された後にText イベントを発生させます。
✔️ 高度な API (通常はデザイナー コンポーネント) のプロパティ値が変更されたときに、変更通知イベントを発生することを検討してください。
ユーザーがオブジェクトのプロパティがいつ変更されているかを知る適切なシナリオがある場合、オブジェクトはプロパティの変更通知イベントを発生させる必要があります。
ただし、基本型やコレクションなど、低レベルの API に対してこのようなイベントを発生させるオーバーヘッドが発生する価値はほとんどありません。 たとえば、新しい項目がリストに追加され、List<T> プロパティが変更された場合、Countはこのようなイベントを発生させません。
✔️ 外部の力によってプロパティの値が変更されたときに、変更通知イベントを発生することを検討してください。
(オブジェクトのメソッドを呼び出す以外の方法で) 何らかの外部力によってプロパティ値が変更された場合、raise イベントは値が変更され、変更されたことを開発者に示します。 良い例は、テキスト ボックス コントロールの Text プロパティです。 ユーザーが TextBoxにテキストを入力すると、プロパティ値が自動的に変更されます。
Portions © 2005, 2009 Microsoft Corporation. All rights reserved.
フレームワーク設計ガイドライン:再利用可能な .NET ライブラリの規則、イディオム、パターン、Krzysztof Cwalina および Brad Abrams による第 2 版は、2008 年 10 月 22 日に Microsoft Windows 開発シリーズの一部として Addison-Wesley Professional によって公開されました。