Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

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

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy