coding-conventions について
coding-conventionsは、.NET/C#開発者やチーム向けのコーディング規約スキルです。命名、レイアウト、言語機能、LINQ、例外処理を扱い、新しいC#と.NETの規約を重視します。
主な機能
- 01新しいC#と.NET機能の指針
- 02命名とフォーマットの規約
- 03型、文字列、コレクションのルール
- 04LINQとラムダ式の推奨事項
- 05例外処理の指針
活用シーン
- 01.NETプロジェクト間のスタイル統一
- 02命名とレイアウト規則の確認
- 03新しいコードでのモダンなC#構文の選択
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ icartsh/ icartsh_plugin --skill coding-conventionsインストール後、Claude Code で/coding-conventionsを入力して読み込まれたか確認します。
詳細
コーディング規約
概要
この SKILL では、開発するすべての .NET プロジェクトに適用されるコーディング規約を定義します。.NET 8 以降の最新機能(C# 12/13/14、.NET 8/9/10)を積極的に活用し、可読性、保守性、パフォーマンスに優れたコードを実装することを目的とします。
責任範囲
この SKILL では、次の範囲を扱います。
- .NET/C# の最新機能(C# 12/13/14、.NET 8/9/10)の活用方針
- 命名規則(Type、Member、Variable、Parameter)
- コードのレイアウトとフォーマット
- 言語機能の使用方針(Type inference、Collection、Exception handling)
- LINQ とラムダ式のベストプラクティス
- モダン C# 構文の推奨パターン
基本方針
- .NET 8 以降の最新機能を積極的に使用します(C# 12/13/14、.NET 8/9/10)
- 以前のバージョンとの互換性が必要な場合を除き、常に最新機能を優先します
- 古い言語構文は避けます
- 重要:アンダースコア接頭辞(
_field)の使用は絶対に禁止です - 重要:中括弧の省略は絶対に禁止です(1 行で記述できる場合も省略できません)
- Microsoft の公式コーディング規約に従います
- 一貫性を保ち、チーム全体で同じスタイルを適用します
.NET/C# の最新機能(バージョン別)
.NET 8 以降の各バージョンで導入された主な機能を積極的に活用します。以前のバージョンとの互換性が必要な場合を除き、常に最新機能を優先して使用します。
C# 12(.NET 8)— 2023 年 11 月正式リリース
Primary Constructors
- クラスや struct の宣言でパラメーターを定義し、クラス全体で使用できます
- 明示的なフィールド宣言を減らし、初期化を簡潔にします
良い例:
public class Person(string name, int age)
{
public string Name => name;
public int Age => age;
public void Display()
{
Console.WriteLine($"{name} is {age} years old");
}
}
悪い例:
public class Person
{
private string name;
private int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
public string Name => name;
public int Age => age;
}
Collection Expressions
- 角括弧とスプレッド演算子を使って、コレクションを簡潔に作成します
- 複数のコレクションを結合する場合に便利です
良い例:
int[] array = [1, 2, 3, 4, 5];
List<string> list = ["one", "two", "three"];
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
// 스프레드 연산자로 결합
int[] combined = [..row0, ..row1];
Default Lambda Parameters
- ラムダ式にデフォルトのパラメーター値を指定できます
良い例:
var incrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(incrementBy(5));
Console.WriteLine(incrementBy(5, 3));
Alias Any Type
- using ディレクティブで複雑な型にエイリアスを付けられます
良い例:
using Point = (int x, int y);
using ProductList = System.Collections.Generic.List<(string Name, decimal Price)>;
Point origin = (0, 0);
ProductList products = [("Product1", 100m), ("Product2", 200m)];
C# 13(.NET 9)— 2024 年 11 月正式リリース
Params Collections
params修飾子を配列以外のコレクション型でも使用できるようになりましたList<T>、Span<T>、ReadOnlySpan<T>、IEnumerable<T>などで使用できます
良い例:
public void ProcessItems(params List<string> items)
{
foreach (var item in items)
{
Console.WriteLine(item);
}
}
// 메모리 효율이 중요한 경우
public void ProcessData(params ReadOnlySpan<int> data)
{
foreach (var value in data)
{
Process(value);
}
}
New Lock Type
System.Threading.Lock型を使用して、より高速なスレッド同期を実現します- 従来の
Monitorベースのロックより高速です
良い例:
private readonly Lock lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// Critical section
}
}
悪い例:
// 기존 object 기반 락 (C# 13에서는 권장되지 않음)
private readonly object lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// Critical section
}
}
Partial Properties and Indexers
- partial プロパティとインデクサーを使用できるようになりました
- 定義と実装を分離できます
良い例:
// 정의 부분
public partial class DataModel
{
public partial string Name { get; set; }
}
// 구현 부분
public partial class DataModel
{
private string name;
public partial string Name
{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value));
}
}
Implicit Index Access
- オブジェクト初期化子で
^演算子を使用できるようになりました
良い例:
var countdown = new TimerBuffer
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2
}
};
Ref Struct Enhancements
ref struct型がインターフェイスを実装できるようになりました- ジェネリック型で
ref structを使用できるようになりました(allows ref struct制約)
良い例:
public ref struct SpanWrapper<T> : IEnumerable<T>
{
private Span<T> span;
public IEnumerator<T> GetEnumerator()
{
foreach (var item in span)
{
yield return item;
}
}
}
C# 14(.NET 10)— 2025 年 11 月リリース予定
Extension Members
- Extension Members を活用し、簡潔な API 拡張を実現します
- 元の型を汚染せずに機能を追加できます
良い例:
extension<TSource>(IEnumerable<TSource> source)
{
public bool IsEmpty => !source.Any();
public int Count => source.Count();
}
Field-Backed Properties
fieldキーワードを使用して、明示的なバッキングフィールドを減らします- 検証ロジックを簡潔に記述できます
- アンダースコア接頭辞を使った明示的なバッキングフィールドは絶対に禁止です
良い例:
// C# 14의 field 키워드 사용
public string Name
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
// 어쩔 수 없이 명시적인 backing field가 필요한 경우에도 언더스코어 없음
private string name;
public string Name
{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value));
}
悪い例:
// 언더스코어 접두사는 절대 금지
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException(nameof(value));
}
Null-Conditional Assignment
?.を使用して、null チェックを簡潔に記述します- 重複する null チェックを減らします
良い例:
customer?.Order = GetCurrentOrder();
悪い例:
if (customer != null)
{
customer.Order = GetCurrentOrder();
}
Implicit Span Conversions
- パフォーマンスを重視するコードでは、
Span<T>とReadOnlySpan<T>を活用します - 配列とスパン型の間の自動変換を利用します
命名規則(Naming Conventions)
Pascal Casing
- 型名(class、record、struct、interface、enum)
- パブリックメンバー(プロパティ、メソッド、イベント)
- 名前空間
良い例:
public class CustomerOrder
{
public string OrderId { get; set; }
public void ProcessOrder() { }
}
Camel Casing
- ローカル変数
- メソッドのパラメーター
- プライベートフィールド(アンダースコア接頭辞は絶対に使用しません)
良い例:
public class OrderProcessor
{
// 언더스코어 없음
private string customerName;
// 언더스코어 없음
private int orderCount;
public void ProcessOrder(string orderId)
{
var customerName = GetCustomerName(orderId);
string processedResult = Process(customerName);
}
}
悪い例:
public class OrderProcessor
{
// 언더스코어 접두사는 절대 금지
private string _customerName;
// 언더스코어 접두사는 절대 금지
private int _orderCount;
}
Interface の命名
- 接頭辞
Iを使用します
良い例:
public interface IOrderProcessor
{
void Process(Order order);
}
型パラメーターの命名
- 接頭辞
Tを使用します - 意味のある名前を付けます
良い例:
public class Repository<TEntity> where TEntity : class
{
public void Add(TEntity entity) { }
}
コードのレイアウト(Code Layout)
インデント
- スペース(Space)4 個を使用します
- タブ(Tab)は使用しません
中括弧(Curly Braces)
- Allman スタイル(開始中括弧と終了中括弧を別々の行に配置)
- 中括弧の省略は絶対に禁止です(1 行で記述できる場合も必ず中括弧を使用します)
良い例:
public void ProcessOrder(Order order)
{
if (order != null)
{
order.Process();
}
}
// 1행이라도 중괄호를 사용함
if (isValid)
{
Execute();
}
for (int i = 0; i < 10; i++)
{
Process(i);
}
悪い例:
// 중괄호 생략 금지
if (isValid)
Execute();
// 중괄호 생략 금지
for (int i = 0; i < 10; i++)
Process(i);
// 중괄호 생략 금지
if (order != null) order.Process();
行の記述
- 1 行に 1 つの statement のみを記述します
- 1 行に 1 つの宣言のみを記述します
- メソッド定義とプロパティ定義の間に空行を 1 行入れます
良い例:
public class Order
{
public string OrderId { get; set; }
public void Process()
{
var result = Validate();
Execute(result);
}
private bool Validate()
{
return OrderId != null;
}
}
名前空間
- ファイルスコープの名前空間(File-scoped namespace)を使用します
良い例:
namespace YourProject.Orders;
public class OrderProcessor
{
// Implementation
}
悪い例:
namespace YourProject.Orders
{
public class OrderProcessor
{
// Implementation
}
}
using ディレクティブ
- 名前空間宣言の外側に配置します
- アルファベット順に並べます
良い例:
using System;
using System.Collections.Generic;
using System.Linq;
namespace YourProject.Orders;
型と変数
型の指定
- 言語キーワード(
string、int、bool)を使用します - ランタイム型(
System.String、System.Int32)は使用しません
良い例:
string name = "John";
int count = 10;
bool isValid = true;
悪い例:
String name = "John";
Int32 count = 10;
Boolean isValid = true;
型推論(var)
- 代入される値から型が明らかな場合にのみ
varを使用します - 組み込み型(Built-in type)は明示的に記述します
良い例:
// 명백함
var orders = new List<Order>();
// 명백함
var customer = GetCustomer();
// 기본 타입은 명시
int count = 10;
// 기본 타입은 명시
string name = "John";
悪い例:
// 기본 타입에서 var는 피함
var count = 10;
// 기본 타입에서 var는 피함
var name = "John";
文字列
文字列補間(String Interpolation)
- 短い文字列の結合には文字列補間を使用します
良い例:
string message = $"Order {orderId} processed successfully";
悪い例:
string message = "Order " + orderId + " processed successfully";
StringBuilder
- ループ内で大量のテキストを追加する場合は
StringBuilderを使用します
良い例:
var builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
builder.Append($"Line {i}\n");
}
Raw String Literals
- エスケープシーケンスより Raw String Literals を優先します
良い例:
string json = """
{
"name": "John",
"age": 30
}
""";
コレクションとオブジェクトの初期化
コレクションの初期化
- C# 12 以降の Collection Expressions を使用します(上記の「C# 12 の最新機能」を参照)
オブジェクト初期化子(Object Initializer)
- オブジェクト初期化子を使用して、生成を簡潔にします
良い例:
var customer = new Customer
{
Name = "John",
Email = "[email protected]"
};
例外処理(Exception Handling)
具体的な例外のキャッチ
- 一般的な
System.Exceptionではなく、具体的な例外をキャッチします
良い例:
try
{
ProcessOrder(order);
}
catch (ArgumentNullException ex)
{
Logger.Error("Order is null", ex);
}
悪い例:
try
{
ProcessOrder(order);
}
catch (Exception ex) // 너무 일반적임
{
Logger.Error("Error", ex);
}
using 文
- try-finally ではなく、
using文を使用します
良い例:
using var connection = new SqlConnection(connectionString);
connection.Open();
// Process
悪い例:
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
connection.Open();
// Process
}
finally
{
connection?.Dispose();
}
LINQ
意味のある変数名
- クエリ変数には意味のある名前を使用します
良い例:
var activeCustomers = from customer in customers
where customer.IsActive
select customer;
早期フィルタリング
where節を使用して、早い段階でデータをフィルタリングします
良い例:
var result = customers
.Where(c => c.IsActive)
.Select(c => c.Name)
.ToList();
暗黙的な型指定
- LINQ 宣言では暗黙的な型指定を使用します
良い例:
var query = from customer in customers
where customer.IsActive
select customer;
ラムダ式(Lambda Expressions)
イベントハンドラー
- 削除が不要なハンドラーにはラムダ式を使用します
良い例:
button.Click += (s, e) => ProcessClick();
パラメーター修飾子
- C# 14 の機能を活用し、型推論を維持しながら修飾子を使用します
良い例:
TryParse<int> parse = (text, out result) => int.TryParse(text, out result);
コメント(Comments)
単一行コメント
- 簡潔な説明には
//を使用します - コメント区切り記号の後にスペースを1つ入れます
- コメントは必ず単独の行に記述します(コードと同じ行への記述は禁止)
- コメントの前に空行を1つ入れます
良い例:
// 고객 주문을 처리함
ProcessOrder(order);
var processor = new OrderProcessor();
// 주문을 실행함
var result = processor.ProcessOrder(order);
悪い例:
ProcessOrder(order); // 고객 주문을 처리함 (코드와 같은 행은 금지)
var processor = new OrderProcessor();
// 이 행의 앞에 빈 행이 없음 (나쁜 예)
var result = processor.ProcessOrder(order);
XML ドキュメント
- パブリックメンバーには XML ドキュメントを使用します
良い例:
/// <summary>
/// 지정된 주문을 처리함
/// </summary>
/// <param name="order">처리할 주문</param>
/// <returns>처리 결과</returns>
public bool ProcessOrder(Order order)
{
// Implementation
}
静的メンバー(Static Members)
クラス名による呼び出し
- 静的メンバーはクラス名を通じて呼び出します
良い例:
var result = OrderProcessor.ProcessOrder(order);
悪い例:
var processor = new OrderProcessor();
// 정적 메서드를 인스턴스를 통해 호출하는 것은 오해의 소지가 있음
var result = processor.ProcessOrder(order);
チェックリスト(Checklist)
コードを書く前
- .NET/C# の最新機能(C# 12/13/14)を把握している
- プロジェクトのターゲットフレームワークが .NET 8 以降に設定されている
- 命名規則を理解している
コードを書いている間
必須ルール:
- アンダースコアのプレフィックスを絶対に使用していない
- 中括弧を省略していない(1行の場合でも必ず使用している)
- コメントを必ず単独の行に記述している(コードと同じ行に記述していない)
- コメントの前に空行を1つ入れている
C# 12 以降の機能:
- プライマリコンストラクターを使用している(該当する場合)
- コレクション式を使用している
- デフォルトのラムダパラメーターを活用している(該当する場合)
- Alias Any Type を使用して複雑な型に別名を付けている(該当する場合)
C# 13 以降の機能:
- Params Collections を使用している(該当する場合)
- New Lock Type を使用している(スレッド同期が必要な場合)
- Partial Properties and Indexers を活用している(該当する場合)
- オブジェクト初期化子で Implicit Index Access を使用している(該当する場合)
C# 14 以降の機能:
-
fieldキーワードを使用して、バッキングフィールドを簡潔に記述している - Extension Members を活用している(該当する場合)
- Null-Conditional Assignment を活用している
- Lambda Parameters with Modifiers を使用している(該当する場合)
基本ルール:
- ファイルスコープの名前空間を使用している
- 言語キーワード(
string、int)を使用している -
varを適切に使用している(型が明白な場合のみ) - 文字列補間を使用している
- Raw String Literals を使用している(該当する場合)
- Object Initializers を使用している
-
using文を使用している - 具体的な例外をキャッチしている
- LINQ 式で早期フィルタリングを行っている
- 意味のある変数名を使用している
- コメントが簡潔で明確である
- パブリックメンバーに XML ドキュメントを記述している
- Allman スタイルで中括弧を配置している
- インデントにスペースを4つ使用している
コードを書いた後
- コードが一貫したスタイルで記述されている
- .NET 8 以降の最新機能(C# 12/13/14)を活用している
- 命名規則に従っている
- 読みやすく、保守しやすいコードである
コメント
Markdown 対応