注
このコンテンツは、 フレームワーク設計ガイドライン (再利用可能な .NET ライブラリの規則、イディオム、パターン、第 2 版) から、Pearson Education, Inc. のアクセス許可によって再印刷されます。 そのエディションは2008年に出版され、その後 、本は第3版で完全に改訂されています。 このページの情報の一部が古くなっている可能性があります。
このセクションでは、引数をチェックするためのガイドラインを含む、パラメーターの設計に関する広範なガイドラインを示します。 さらに、「 名前付けパラメーター」で説明されているガイドラインを参照する必要があります。
✔️ メンバーに必要な機能を提供する最小派生パラメーター型を使用してください。
たとえば、コレクションを列挙し、各項目をコンソールに出力するメソッドを設計するとします。 このようなメソッドは、ArrayListやIListではなく、パラメーターとしてIEnumerableを受け取る必要があります。
❌ 予約済みパラメーターは使用しないでください。
将来のバージョンでメンバーに対する入力が増える必要がある場合は、新しいオーバーロードを追加できます。
❌ ポインター、ポインターの配列、または多次元配列をパラメーターとして受け取るパブリックに公開されたメソッドを持たないでください。
ポインターと多次元配列は、適切に使用するのが比較的困難です。 ほとんどの場合、これらの型をパラメーターとして受け取らないように API を再設計できます。
✔️ すべての out
パラメーターは、オーバーロード間のパラメーター順序の不整合が発生した場合でも(パラメーター配列を除く)、すべての by-value パラメーターと ref
パラメーターの後に配置します ( メンバーオーバーロードを参照)。
out
パラメーターは追加の戻り値と見なすことができます。これらをグループ化すると、メソッドシグネチャが理解しやすくなります。
✔️ メンバーをオーバーライドするとき、またはインターフェイス メンバーを実装する場合は、パラメーターの名前付けに一貫性を持たないでください。
これにより、メソッド間の関係がより適切に伝達されます。
列挙型パラメーターとブール型パラメーターの選択
✔️ メンバーに 2 つ以上のブール型パラメーターがある場合は、列挙型を使用します。
❌ 2 つ以上の値が必要になることが絶対に確実でない限り、ブール値を使用しないでください。
列挙型を使用すると、将来値を追加する余地はありますが、列挙型に値を追加することによるすべての影響に注意する必要があります。列挙型 の設計に関する記事で説明されています。
✔️ 真に 2 状態の値であり、単にブール型プロパティを初期化するために使用されるコンストラクター パラメーターにブール値を使用することを検討してください。
引数の検証
✔️ DO は、パブリック、保護、または明示的に実装されたメンバーに渡される引数を検証します。 検証が失敗した場合は、 System.ArgumentExceptionまたはそのサブクラスの 1 つをスローします。
実際の検証は、必ずしもパブリック メンバーまたは保護されたメンバー自体で行う必要はありません。 これは、一部のプライベートルーチンまたは内部ルーチンでは、より低いレベルで発生する可能性があります。 主なポイントは、エンド ユーザーに公開されているサーフェス領域全体が引数をチェックすることです。
✔️ DO は、null 引数が渡され、メンバーが null 引数をサポートしていない場合に ArgumentNullException をスローします。
✔️ 列挙型パラメーターを検証します。
列挙型引数が列挙型によって定義された範囲内にあると想定しないでください。 CLR では、列挙型で値が定義されていない場合でも、任意の整数値を列挙型値にキャストできます。
❌ 列挙型範囲のチェックには Enum.IsDefined を使用しないでください。
✔️ 変更可能な引数は、検証後に変更された可能性があることに注意してください。
メンバーがセキュリティに影響を受けやすい場合は、コピーを作成してから、引数を検証して処理することをお勧めします。
パラメーターの受け渡し
フレームワーク デザイナーの観点から見ると、パラメーターには、値ごとのパラメーター、 ref
パラメーター、 out
パラメーターの 3 つの主要なグループがあります。
引数が値渡しパラメーターを介して渡されると、メンバーは渡された実際の引数のコピーを受け取ります。 引数が値型の場合、引数のコピーがスタックに配置されます。 引数が参照型の場合、参照のコピーがスタックに配置されます。 C#、VB.NET、C++ などの最も一般的な CLR 言語では、既定でパラメーターを値渡しします。
引数が ref
パラメーターを介して渡されると、メンバーは渡された実際の引数への参照を受け取ります。 引数が値型の場合、引数への参照がスタックに配置されます。 引数が参照型の場合、参照への参照がスタックに配置されます。
Ref
パラメーターを使用すると、メンバーが呼び出し元から渡された引数を変更できます。
Out
パラメーターは ref
パラメーターに似ていますが、いくつかの違いがあります。 パラメーターは、最初は未割り当てと見なされ、メンバー本体で読み取ることができないので、何らかの値が割り当てられます。 また、メンバーが戻る前に、パラメーターに値を割り当てる必要があります。
❌
out
またはref
パラメーターの使用は避けてください。
out
またはref
パラメーターを使用するには、ポインターの使用経験、値型と参照型の違い、および複数の戻り値を持つメソッドの処理が必要です。 また、out
パラメーターと ref
パラメーターの違いはあまり理解されていません。 一般ユーザー向けに設計するフレームワーク アーキテクトは、ユーザーが out
や ref
パラメーターの操作に習熟することを期待しないでください。
❌ 参照によって参照型を渡さないでください。
参照のスワップに使用できるメソッドなど、ルールにはいくつかの制限付き例外があります。
可変数のパラメーターを持つメンバー
可変数の引数を受け取ることができるメンバーは、配列パラメーターを指定することによって表されます。 たとえば、 String は次のメソッドを提供します。
public class String {
public static string Format(string format, object[] parameters);
}
その後、ユーザーは次のように String.Format メソッドを呼び出すことができます。
String.Format("File {0} not found in {1}",new object[]{filename,directory});
C# params キーワードを配列パラメーターに追加すると、パラメーターがいわゆる params 配列パラメーターに変更され、一時配列を作成するためのショートカットが提供されます。
public class String {
public static string Format(string format, params object[] parameters);
}
これにより、ユーザーは引数リストで配列要素を直接渡すことによって、メソッドを呼び出すことができます。
String.Format("File {0} not found in {1}",filename,directory);
params キーワードは、パラメーター リストの最後のパラメーターにのみ追加できることに注意してください。
✔️ エンド ユーザーが少数の要素を持つ配列を渡すことが予想される場合は、params キーワードを配列パラメーターに追加することを検討してください。 一般的なシナリオで多数の要素が渡されることが予想される場合、ユーザーはおそらくこれらの要素をインラインで渡さないため、params キーワードは必要ありません。
❌ 呼び出し元がほとんどの場合、配列に既に入力がある場合は、パラメーター配列を使用しないでください。
たとえば、バイト配列パラメーターを持つメンバーは、個々のバイトを渡すことによって呼び出されることはほとんどありません。 このため、.NET Framework のバイト配列パラメーターでは params キーワードは使用されません。
❌ params 配列パラメーターを受け取るメンバーによって配列が変更された場合は、パラメーター配列を使用しないでください。
多くのコンパイラがメンバーの引数を呼び出しサイトの一時配列に変換するため、配列が一時オブジェクトである可能性があるため、配列の変更は失われます。
✔️ より複雑なオーバーロードで使用できなかった場合でも、単純なオーバーロードで params キーワードを使用することを検討してください。
すべてのオーバーロードに含まれていない場合でも、ユーザーが params 配列を 1 つのオーバーロードに含めることに値を設定するかどうかを自問してください。
✔️ パラメーターを並べ替えて params キーワードを使用できるようにしてください。
✔️ パフォーマンスが非常に高い API では、少数の引数を持つ呼び出しに対して特別なオーバーロードとコード パスを提供することを検討してください。
これにより、少数の引数で API が呼び出されたときに配列オブジェクトを作成することを回避できます。 配列パラメーターの単一の形式を取得し、数値サフィックスを追加して、パラメーターの名前を形成します。
これは、配列を作成してより一般的なメソッドを呼び出すだけでなく、コード パス全体を特殊化する場合にのみ行う必要があります。
✔️ null は params 配列引数として渡される可能性があることに注意してください。
処理する前に、配列が null ではないことを検証する必要があります。
❌ 省略記号と呼ばれる varargs
メソッドは使用しないでください。
C++ などの一部の CLR 言語では、 varargs
メソッドと呼ばれる変数パラメーター リストを渡すための代替規則がサポートされています。 規則は CLS に準拠していないため、フレームワークでは使用しないでください。
ポインター パラメーター
一般に、ポインターは、適切に設計されたマネージド コード フレームワークのパブリック サーフェス領域には表示しないでください。 ほとんどの場合、ポインターはカプセル化する必要があります。 ただし、相互運用性の理由からポインターが必要な場合もあり、このような場合はポインターを使用することが適切です。
✔️ ポインターは CLS に準拠していないため、ポインター引数を受け取るメンバーに代わる方法を提供してください。
❌ ポインター引数の高価な引数チェックを行わないようにします。
✔️ ポインターを使用してメンバーを設計するときは、ポインター関連の一般的な規則に従ってください。
たとえば、単純なポインター演算を使用して同じ結果を実現できるため、開始インデックスを渡す必要はありません。
Portions © 2005, 2009 Microsoft Corporation. 無断転載を禁じます。
フレームワーク設計ガイドライン:再利用可能な .NET ライブラリの規則、イディオム、パターン、Krzysztof Cwalina および Brad Abrams による第 2 版は、2008 年 10 月 22 日に Microsoft Windows 開発シリーズの一部として Addison-Wesley Professional によって公開されました。