C#コードを簡素化する14の方法 - ティム・コーリーのビデオによるC#のベストプラクティスに関する洞察
ティム・コーリーは、包括的なビデオ"14 Ways to Simplify Your C# Code"で、コードの可読性を向上させ、混乱を減らし、コードベースを保守しやすく保つ実践的な C# のベストプラクティスを紹介しています。 ティムは、ワンライナーや不可解なトリックにこだわるのではなく、他の開発者が従うことができる、きれいで理解しやすいコードを書くための優れたコーディングプラクティスに重点を置いています。
また、Visual Studioでの実際の例を中心に、命名規則、エラー処理、コードを壊さずにリファクタリングする方法まで、各ヒントを組み立てている。 これは単なる理論ではなく、実践がコードをより良くするのです。
この記事では、彼が実演した14の方法をそれぞれ見ていこう。
1.よりクリーンなコードのための静的使用1.
Timはまず、静的アクセスによって繰り返しの呼び出しがどのように簡素化されるかを示します。 宣言することで
using static System.Console;using static System.Console;もう、すべての静的メンバの前に Console... を付ける必要はありません。
これは、単に単語を削除するだけではありません。 ティムは、ConsoleやMathのような頻繁に使用されるクラスで定義された静的メンバを呼び出す場合、この省略記法はコードの可読性を向上させると指摘している。
しかし、良いコーディングの実践の一環として、開発者は衝突を避けるべきだと警告している。 潜在的な予期せぬ動作に対する認識が鍵となります。
2.リストの初期化
C#では、リストをより直接的に初期化できるようになりました:
List<string> names = ["Tim", "Sue", "Bilbo"];List<string> names = ["Tim", "Sue", "Bilbo"];ティムは、これは1つのステートメントにすべてを詰め込むことではなく、セレモニーを減らすことで読みやすく、パフォーマンスを最適化するコードを書くことだと説明する。
新しい文字列のリスト "という定型文を解析する代わりに、読者は、コレクション内の説明的な名前という、重要なものを正確に見ることができます。 ティムはまた、これは配列や辞書にも有効であり、明瞭さを優先するコーディング規約に沿うものであると述べています。
3.ターゲット型新規
もう1つの時間節約:ターゲットタイプの新規作成。 代わりに
List<int> numbers = new List<int>();List<int> numbers = new List<int>();あなたは書くことができます:
List<int> numbers = new();List<int> numbers = new();ティムは、クラス名を繰り返すことは不要であることを強調しています。これは、コードベースをスキャンしやすく保ちながら冗長性を排除することで、良いコーディングプラクティスに従ったものです。
4.varと匿名型
Timは、コーディングプラクティス界で議論を巻き起こしているvarに取り組んでいます。 変数名や型を隠すことを嫌う人もいるが、ティムは匿名型にこそ真の力があると説明する。
DapperによるSQLのような)データソースを扱うとき、ティムはvarがどのようにその場でオブジェクトを作成できるかを示します:
var parameters = new { FirstName = "Tim", LastName = "Corey" };var parameters = new { FirstName = "Tim", LastName = "Corey" };これは、クエリや単発のオブジェクトを書くのに最適です-パラメータのためだけに基底クラスを作成する必要はありません。 ティムが言うように、これによってコード・ベースが不要な型によって汚染されることを避けつつ、何か問題が発生した場合に意味のあるエラー・メッセージを提供することができます。
5.ファイルスコープの名前空間
Timは、ファイルスコープの名前空間に移り、これがどのようなものかを示します:
namespace ProjectName
{
// indented code
}namespace ProjectName
{
// indented code
}となります:
namespace ProjectName;namespace ProjectName;この小さな変更により、無駄なインデントがなくなり、パブリック・メンバーのPascalのケーシングのようなC#の命名規則が遵守されます。 ティムは、ほとんどのファイルには名前空間が1つしか含まれていないため、コードの可読性が向上し、論理的なセクションが整列されると説明しています。
6.1行データ構造のレコード
レコードを使用すると、1つのステートメントだけでデータオブジェクトを定義できます:
public record EmployeeRecord(int Id, string Name);public record EmployeeRecord(int Id, string Name);Timは、これは完全な型-プロパティ、不変性、ToString()-を最小限の労力で生成すると述べている。 派生クラスのシナリオでもクラスは必要だが、オブジェクトが読み取り専用である場合、レコードは1つの仕事をうまくこなすことで、単一責任の原則に従うと彼は明言している。
7.パターンマッチング
Timは、パターン・マッチがどのように例外処理と安全な比較の実行に役立つかを示します。 冗長な型チェックを書く代わりに、それらを組み合わせることができます:
if (emp is EmployeeRecord e)
{
e.Id = 1;
}if (emp is EmployeeRecord e)
{
e.Id = 1;
}この1行でチェックとキャストを行います。 ティムによると、これは良いコーディングプラクティスに沿ったもので、xやyのような1文字の変数名は避け、代わりにeのような説明的な名前を付けるのだそうです。 明確なメソッド名と変数名は、他の開発者がコードを維持しやすくします。
8.文字列の補間
読みやすい文字列を構築するために、ティムは文字列補間を実演します:
$"The employee with ID {e.Id} is {e.Name}"$"The employee with ID {e.Id} is {e.Name}"これにより、意味のあるエラーメッセージやコメントの書き込みが容易になると指摘している。 もつれた連結の代わりに、文字通り英語のように読めるコードを書くことができ、コードの品質が向上し、出力をチェックする将来のユニットテストが簡素化されます。
9.安全なリファクタリングのための nameof()
Timは、コードをリファクタリングする際にnameof()がどのようにあなたを守るかを示します。 文字列でハードコードされた変数名は、名前を変更すると予期しない動作につながる可能性があります。 しかし、こう書くことで
nameof(emp)nameof(emp)コンパイラーは、すべての使用法を自動的に更新します。 これは、コードをきれいに書いて再編成するときに、コードベースを健全に保つベストプラクティスの1つです。
10.複数の戻り値のためのタプル
2つの値を返すためだけに基本クラスを作成する代わりに、Timはタプルを使用します:
(string FirstName, string LastName) SplitName(string fullName)(string FirstName, string LastName) SplitName(string fullName)これは、不必要な外部依存を避け、単一責任の原則を遵守します。 ティムが言うように、過剰なエンジニアリングを避ければ、実践がコードをより良いものにします。
11.デコンストラクション
タプルをベースに、Timは結果をローカル変数に分解する方法を示します:
var (firstName, lastName) = SplitName("Tim Corey");var (firstName, lastName) = SplitName("Tim Corey");これは、変数名を説明的に保ち、後で不可解なタプル構文を避けるためです。 Timは、未使用の値を破棄すること(˶‾᷄ -̫ ̫᷅˵)にも触れています。
12.不要な値の破棄
すべてのタプルパーツが必要ない場合は、Timは破棄を推奨します:
var (firstName, _) = SplitName("Tim Corey");var (firstName, _) = SplitName("Tim Corey");これは、あなたが意図的に価値を無視していることを他の開発者に示すもので、すべての出力が重要ではないフレームワークやユニットテストをテストするのに適しています。
13. ブロックなしでステートメントを使用する
Timはリソース管理とエラー処理に移ります。 以前は
using (var connection = new SqlConnection(connString))
{
// work
}using (var connection = new SqlConnection(connString))
{
// work
}今すぐ使用できます:
using var connection = new SqlConnection(connString);using var connection = new SqlConnection(connString);これは、SOLIDの原則、特に単一責任の原則と依存関係の逆転の原則に沿ったものです。 Timは、この構文はデータベースのような外部依存関係に対してうまく機能し、ほとんどの例外処理がよりクリーンになり、接続が常に閉じられるので、パフォーマンスの問題や、接続が破棄されない場合のSQLインジェクションのシナリオさえも避けることができると述べている。
14.変数宣言のインライン化
最後に、Timは構文解析などのためのインライン・アウト変数宣言について説明します:
if (int.TryParse(numberText, out int numberValue))if (int.TryParse(numberText, out int numberValue))ここでは、同じ行でローカル変数を作成します。こうすることで、コーディング規約を厳格に保ち、メソッド名を説明的にすることができます。コードを適切にグループ化することで、予期せぬ動作を減らし、将来のコードのリファクタリング作業をより安全にすることができます。
まとめ
ティムは、ビデオの最後に、視聴者に次のことを思い出させます:これらの簡略化は、不可解なワンライナーを書くことではありません。 static、records、pattern matching、tuples、discardsを使用することで、クリーンでモダンなC#を書くことができます。
彼は、開発者がこれらの機能を採用する際に、命名規則、エラー処理、意味のある名前について考えるよう奨励している。 コードは人間が読むものです"とティムは言う。"理解しやすいコードを書けば、自分自身や他の開発者の生活をより良いものにできます。
要するに、これらのC#のベストプラクティスを受け入れ、単一責任の原則、インターフェイス分離の原則、依存関係の逆転の原則などのSOLIDの原則に従ってください。

