良い読書をしてください。
「これらはすべて些細なことです。些細なことです。 しかし、些細なことほど重要なことはありません。」
1.間違ったコレクションタイプを使用する
.Netには多くのコレクションクラスがあり、それらはすべて特定のタスクに特化しています。 クラスの選択は慎重に行う必要があります。 選択を間違えた場合、非効率的なコード、予期しない値を受け取り、コードの意味を理解できなくします。
→ 詳細はこちら
2.利回りリターンを使用しない
呼び出されるオブジェクトをリストするときは、returnコレクションを作成するのではなく、yield returnステートメントを使用する必要があります( 翻訳者のメモ :状況によって異なります)。 このテンプレートの利点:
- コレクション全体をメモリに保存する必要はありません(非常に大きくなる可能性があります)
- yield returnは、各反復後に呼び出し関数の制御を直接返します
- 使用される結果のみが処理されています(呼び出し元の関数が最初の値を取得したい場合にコレクション全体を反復する理由)
3.あいまいな日付の分析
あいまいな日付の分析に関しては、必ず形式を指定してください。 たとえば、「03/04/05」の行では、日、月、年が明確ではないため、ユーザーに重大なエラーが発生する可能性があります。
ここでは、
var date = DateTime.ParseExact("01/12/2000", "MM/dd/yyyy", null)
4.インスタンスで例外を再処理する
例外をキャッチして再処理する場合は、必ず単純なスローを使用してください。 突然throw exを使用すると、例外呼び出しスタックが保存されません。
使用:
catch(SomeException ex) { logger.log(ex); throw; }
使用しないでください:
catch(SomeException ex) { logger.log(ex); throw ex; }
5.コンストラクター内の仮想コンポーネントへのアクセス
仮想記述子を使用すると、派生クラスでクラスメンバーをオーバーライドできます。 コンストラクターは、基本クラスから派生クラスまで実行されます。 つまり、基本クラスのコンストラクターからオーバーライドされたメソッドを呼び出すと、実行準備が整っていないコードが呼び出される可能性があります(これは、独自のコンストラクターでの初期化の完了に依存する場合があります)。
例:
public class Parent { public Parent() { Console.WriteLine("Parent Ctor"); Method(); } public virtual void Method() { Console.WriteLine("Parent method"); } } public class Child : Parent { public Child() { Console.WriteLine("Child Ctor"); } public override void Method() { Console.WriteLine("Child method"); } }
子クラスの初期化は次のようになります。
- 親コンストラクター
- 子メソッド
- 子コンストラクター
つまり 子メソッドは、子コンストラクターの前に呼び出されます。
6.静的コンストラクターの例外
クラスが静的コンストラクターで例外をスローすると、クラスは役に立たなくなります。 非静的設計でさえ不可能です。 クラスは、参照されるたびに(静的または非静的に)System.TypeInitializationExceptionをスローします。
7.外部アセンブリのオプションのパラメーター
外部アセンブリから参照されている場合、オプションのパラメーターが期待どおりに機能しない場合があります。 DLLにいくつかの機能がパッケージ化されているとします。 そして、たとえば、コードに小さな変更を加えたい(オプションのパラメーターを別の値に変更したい)。
DLLのコンシューマーは、変更を有効にするために再コンパイルする必要があります。
→ 詳細はこちら
8.非ユニバーサルオーバーロードを使用するユニバーサルメソッド
型Tのパラメーターと同じ名前の別のメソッドを使用するが、特定の型のパラメーターを使用するユニバーサルメソッドがあるとします。 コンパイラーは、パラメーターの各タイプにより適したメソッドを選択し、明示的に定義されたタイプは、汎用タイプよりも正確です。
たとえば、次のクラスがあります。
class GenericTest { public void Test<T>(T parameter) { Console.WriteLine("Generic method!"); } public void Test(string parameter) { Console.WriteLine("Non-generic method!"); } }
そして、次のコード...
var instance = new GenericTest(); instance.Test(7); instance.Test("foo");
結果が得られます:
Generic method! Non-generic method!
つまり コンパイラは、2番目の呼び出しでより具体的な文字列メソッドを選択します。
9.辞書にオブジェクトを追加した後、ハッシュコードを変更します
辞書は、Object.GetHashCode()メソッドによって返されるキー値に依存します。 つまり、キーのハッシュコードは、辞書に追加された後は変更できません。
10.構造にリンクコンポーネントが含まれる場合、ValueType.Equalsは遅くなります
ValueType.Equalsを使用して2つのインスタンスを比較する場合は、構造に参照コンポーネントが含まれていないことを確認してください。 作業が遅いのは、ValueType.Equalsがリフレクションを使用して参照コンポーネントを定義するためであり、これは予想よりも少し遅い可能性があります。
原作者:ロバート・ベンツソン