coding-conventions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCoding Conventions
编码规范
개요
概述
이 SKILL은 개발되는 모든 .NET 프로젝트에 적용되는 코딩 규약을 정의합니다. .NET 8 이후의 최신 기능(C# 12/13/14, .NET 8/9/10)을 적극적으로 활용하여 가독성, 유지보수성, 성능이 높은 코드를 구현하는 것을 목적으로 합니다.
本规范定义了适用于所有.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/C#最新功能(C# 12/13/14、.NET 8/9/10)的使用方针
- 命名规则(类型、成员、变量、参数)
- 代码布局与格式
- 语言功能使用方针(类型推断、集合、异常处理)
- LINQ与Lambda表达式的最佳实践
- 现代C#语法的推荐模式
기본 방침
基本方针
- .NET 8 이후의 최신 기능을 적극적으로 사용한다 (C# 12/13/14, .NET 8/9/10)
- 이전 버전과의 호환성이 필요한 경우를 제외하고 항상 최신 기능을 우선한다
- 오래된 언어 구문은 피한다
- 중요: 언더스코어 접두사() 사용은 절대 금지한다
_field - 중요: 중괄호 생략은 절대 금지한다 (1행으로 기술할 수 있는 경우에도 생략 불가)
- Microsoft 공식 코딩 규약을 따른다
- 일관성을 유지하고 팀 전체에서 동일한 스타일을 적용한다
- 积极使用.NET 8及以后的最新功能(C# 12/13/14、.NET 8/9/10)
- 除非需要与旧版本兼容,否则优先使用最新功能
- 避免使用过时的语言语法
- 重要:绝对禁止使用下划线前缀()
_field - 重要:绝对禁止省略大括号(即使可以写成单行也必须使用)
- 遵循Microsoft官方编码规范
- 保持一致性,在团队内统一应用相同风格
.NET/C# 최신 기능 (버전별)
.NET/C#最新功能(按版本划分)
.NET 8 이후 각 버전에서 도입된 주요 기능을 적극적으로 활용합니다. 이전 버전과의 호환성이 필요한 경우를 제외하고 항상 최신 기능을 우선적으로 사용합니다.
积极运用.NET 8以后各版本引入的主要功能。除非需要与旧版本兼容,否则始终优先使用最新功能。
C# 12 (.NET 8) - 2023년 11월 공식 릴리스
C# 12 (.NET 8) - 2023年11月正式发布
Primary Constructors
Primary Constructors
- 클래스나 struct 선언에서 파라미터를 정의하고 클래스 전체에서 사용할 수 있음
- 명시적인 필드 선언을 줄이고 초기화를 간소화함
좋은 예:
csharp
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");
}
}나쁜 예:
csharp
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;
}- 可在类或struct声明中定义参数,并在整个类中使用
- 减少显式字段声明,简化初始化流程
良好示例:
csharp
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");
}
}不良示例:
csharp
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
Collection Expressions
- 대괄호와 스프레드 연산자를 사용하여 컬렉션을 간결하게 생성함
- 여러 컬렉션을 결합할 때 유용함
좋은 예:
csharp
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];- 使用方括号和扩展运算符简洁地创建集合
- 合并多个集合时非常实用
良好示例:
csharp
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
Default Lambda Parameters
- 람다식에 기본 파라미터 값을 지정할 수 있음
좋은 예:
csharp
var incrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(incrementBy(5));
Console.WriteLine(incrementBy(5, 3));- 可为Lambda表达式指定默认参数值
良好示例:
csharp
var incrementBy = (int source, int increment = 1) => source + increment;
Console.WriteLine(incrementBy(5));
Console.WriteLine(incrementBy(5, 3));Alias Any Type
Alias Any Type
- using 디렉티브로 복잡한 타입에 별칭을 붙일 수 있음
좋은 예:
csharp
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)];- 使用using指令为复杂类型设置别名
良好示例:
csharp
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월 공식 릴리스
C# 13 (.NET 9) - 2024年11月正式发布
Params Collections
Params Collections
- 수식어를 배열 외의 컬렉션 타입에서도 사용 가능해짐
params - ,
List<T>,Span<T>,ReadOnlySpan<T>등에서 사용 가능IEnumerable<T>
좋은 예:
csharp
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);
}
}- 修饰符可用于数组以外的集合类型
params - 支持、
List<T>、Span<T>、ReadOnlySpan<T>等类型IEnumerable<T>
良好示例:
csharp
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
New Lock Type
- 타입을 사용하여 더 빠른 스레드 동기화를 구현함
System.Threading.Lock - 기존 기반 락보다 빠름
Monitor
좋은 예:
csharp
private readonly Lock lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// Critical section
}
}나쁜 예:
csharp
// 기존 object 기반 락 (C# 13에서는 권장되지 않음)
private readonly object lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// Critical section
}
}- 使用类型实现更快速的线程同步
System.Threading.Lock - 比传统基于的锁性能更优
Monitor
良好示例:
csharp
private readonly Lock lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// 临界区代码
}
}不良示例:
csharp
// 传统基于object的锁(C# 13中不推荐使用)
private readonly object lockObject = new();
public void UpdateData()
{
lock (lockObject)
{
// 临界区代码
}
}Partial Properties and Indexers
Partial Properties and Indexers
- partial 프로퍼티와 인덱서를 사용할 수 있게 됨
- 정의와 구현을 분리할 수 있음
좋은 예:
csharp
// 정의 부분
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));
}
}- 支持分部属性和索引器
- 可分离定义与实现
良好示例:
csharp
// 定义部分
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
Implicit Index Access
- 객체 이니셜라이저에서 연산자를 사용할 수 있게 됨
^
좋은 예:
csharp
var countdown = new TimerBuffer
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2
}
};- 对象初始化器中可使用运算符
^
良好示例:
csharp
var countdown = new TimerBuffer
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2
}
};Ref Struct Enhancements
Ref Struct Enhancements
- 타입이 인터페이스를 구현할 수 있게 됨
ref struct - 제네릭 타입에서 를 사용할 수 있게 됨 (
ref struct제약 조건)allows ref struct
좋은 예:
csharp
public ref struct SpanWrapper<T> : IEnumerable<T>
{
private Span<T> span;
public IEnumerator<T> GetEnumerator()
{
foreach (var item in span)
{
yield return item;
}
}
}- 类型可实现接口
ref struct - 泛型类型中可使用(需添加
ref struct约束)allows ref struct
良好示例:
csharp
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월 릴리스 예정
C# 14 (.NET 10) - 预计2025年11月发布
Extension Members
Extension Members
- Extension Members를 활용하여 깔끔한 API 확장을 구현함
- 원래 타입을 오염시키지 않고 기능을 추가할 수 있음
좋은 예:
csharp
extension<TSource>(IEnumerable<TSource> source)
{
public bool IsEmpty => !source.Any();
public int Count => source.Count();
}- 利用Extension Members实现简洁的API扩展
- 可在不污染原类型的前提下添加功能
良好示例:
csharp
extension<TSource>(IEnumerable<TSource> source)
{
public bool IsEmpty => !source.Any();
public int Count => source.Count();
}Field-Backed Properties
Field-Backed Properties
- 키워드를 사용하여 명시적인 backing field를 줄임
field - 검증 로직을 간결하게 기술할 수 있음
- 언더스코어 접두사를 사용한 명시적인 backing field는 절대 금지
좋은 예:
csharp
// 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));
}나쁜 예:
csharp
// 언더스코어 접두사는 절대 금지
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException(nameof(value));
}- 使用关键字减少显式后备字段
field - 可简化验证逻辑
- 绝对禁止使用带下划线前缀的显式后备字段
良好示例:
csharp
// 使用C# 14的field关键字
public string Name
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
// 万不得已需要显式后备字段时,也不能使用下划线
private string name;
public string Name
{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value));
}不良示例:
csharp
// 绝对禁止使用下划线前缀
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException(nameof(value));
}Null-Conditional Assignment
Null-Conditional Assignment
- 를 사용하여 null 체크를 간결하게 기술함
?. - 중복되는 null 체크를 줄임
좋은 예:
csharp
customer?.Order = GetCurrentOrder();나쁜 예:
csharp
if (customer != null)
{
customer.Order = GetCurrentOrder();
}- 使用简化空值检查
?. - 减少重复的空值判断代码
良好示例:
csharp
customer?.Order = GetCurrentOrder();不良示例:
csharp
if (customer != null)
{
customer.Order = GetCurrentOrder();
}Implicit Span Conversions
Implicit Span Conversions
- 성능 중시 코드에서는 와
Span<T>를 활용함ReadOnlySpan<T> - 배열과 스팬 타입 간의 자동 변환을 이용함
- 性能敏感代码中使用和
Span<T>ReadOnlySpan<T> - 利用数组与Span类型之间的自动转换
명명 규칙 (Naming Conventions)
命名规则 (Naming Conventions)
Pascal Casing
Pascal命名法
- 타입 이름 (class, record, struct, interface, enum)
- 퍼블릭 멤버 (프로퍼티, 메서드, 이벤트)
- 네임스페이스
좋은 예:
csharp
public class CustomerOrder
{
public string OrderId { get; set; }
public void ProcessOrder() { }
}- 类型名称(class、record、struct、interface、enum)
- 公共成员(属性、方法、事件)
- 命名空间
良好示例:
csharp
public class CustomerOrder
{
public string OrderId { get; set; }
public void ProcessOrder() { }
}Camel Casing
Camel命名法
- 로컬 변수
- 메서드 파라미터
- 프라이빗 필드 (언더스코어 접두사는 절대 사용하지 않음)
좋은 예:
csharp
public class OrderProcessor
{
// 언더스코어 없음
private string customerName;
// 언더스코어 없음
private int orderCount;
public void ProcessOrder(string orderId)
{
var customerName = GetCustomerName(orderId);
string processedResult = Process(customerName);
}
}나쁜 예:
csharp
public class OrderProcessor
{
// 언더스코어 접두사는 절대 금지
private string _customerName;
// 언더스코어 접두사는 절대 금지
private int _orderCount;
}- 局部变量
- 方法参数
- 私有字段(绝对禁止使用下划线前缀)
良好示例:
csharp
public class OrderProcessor
{
// 无下划线
private string customerName;
// 无下划线
private int orderCount;
public void ProcessOrder(string orderId)
{
var customerName = GetCustomerName(orderId);
string processedResult = Process(customerName);
}
}不良示例:
csharp
public class OrderProcessor
{
// 绝对禁止使用下划线前缀
private string _customerName;
// 绝对禁止使用下划线前缀
private int _orderCount;
}Interface 명명
接口命名
- 접두사 를 사용함
I
좋은 예:
csharp
public interface IOrderProcessor
{
void Process(Order order);
}- 使用前缀
I
良好示例:
csharp
public interface IOrderProcessor
{
void Process(Order order);
}타입 파라미터 명명
类型参数命名
- 접두사 를 사용함
T - 의미 있는 이름을 붙임
좋은 예:
csharp
public class Repository<TEntity> where TEntity : class
{
public void Add(TEntity entity) { }
}- 使用前缀
T - 赋予有意义的名称
良好示例:
csharp
public class Repository<TEntity> where TEntity : class
{
public void Add(TEntity entity) { }
}코드 레이아웃 (Code Layout)
代码布局 (Code Layout)
들여쓰기
缩进
- 공백(Space) 4개를 사용함
- 탭(Tab)은 사용하지 않음
- 使用4个空格
- 禁止使用制表符(Tab)
중괄호 (Curly Braces)
大括号 (Curly Braces)
- Allman 스타일 (시작 중괄호와 종료 중괄호를 별도의 행에 배치)
- 중괄호 생략은 절대 금지 (1행으로 기술할 수 있는 경우에도 반드시 중괄호 사용)
좋은 예:
csharp
public void ProcessOrder(Order order)
{
if (order != null)
{
order.Process();
}
}
// 1행이라도 중괄호를 사용함
if (isValid)
{
Execute();
}
for (int i = 0; i < 10; i++)
{
Process(i);
}나쁜 예:
csharp
// 중괄호 생략 금지
if (isValid)
Execute();
// 중괄호 생략 금지
for (int i = 0; i < 10; i++)
Process(i);
// 중괄호 생략 금지
if (order != null) order.Process();- 采用Allman风格(起始大括号和结束大括号分别单独占一行)
- 绝对禁止省略大括号(即使可以写成单行也必须使用)
良好示例:
csharp
public void ProcessOrder(Order order)
{
if (order != null)
{
order.Process();
}
}
// 即使单行也使用大括号
if (isValid)
{
Execute();
}
for (int i = 0; i < 10; i++)
{
Process(i);
}不良示例:
csharp
// 禁止省略大括号
if (isValid)
Execute();
// 禁止省略大括号
for (int i = 0; i < 10; i++)
Process(i);
// 禁止省略大括号
if (order != null) order.Process();행 기술
行编写
- 1행에 하나의 statement만 기술함
- 1행에 하나의 선언만 기술함
- 메서드 정의와 프로퍼티 정의 사이에 빈 행을 하나 넣음
좋은 예:
csharp
public class Order
{
public string OrderId { get; set; }
public void Process()
{
var result = Validate();
Execute(result);
}
private bool Validate()
{
return OrderId != null;
}
}- 一行只写一条语句
- 一行只写一个声明
- 方法定义与属性定义之间空一行
良好示例:
csharp
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)를 사용함
좋은 예:
csharp
namespace YourProject.Orders;
public class OrderProcessor
{
// Implementation
}나쁜 예:
csharp
namespace YourProject.Orders
{
public class OrderProcessor
{
// Implementation
}
}- 使用文件作用域命名空间(File-scoped namespace)
良好示例:
csharp
namespace YourProject.Orders;
public class OrderProcessor
{
// 实现代码
}不良示例:
csharp
namespace YourProject.Orders
{
public class OrderProcessor
{
// 实现代码
}
}using 디렉티브
using指令
- 네임스페이스 선언 바깥쪽에 배치함
- 알파벳 순으로 정렬함
좋은 예:
csharp
using System;
using System.Collections.Generic;
using System.Linq;
namespace YourProject.Orders;- 放置在命名空间声明外部
- 按字母顺序排序
良好示例:
csharp
using System;
using System.Collections.Generic;
using System.Linq;
namespace YourProject.Orders;타입과 변수
类型与变量
타입 지정
类型指定
- 언어 키워드 (,
string,int)를 사용함bool - 런타임 타입 (,
System.String)은 사용하지 않음System.Int32
좋은 예:
csharp
string name = "John";
int count = 10;
bool isValid = true;나쁜 예:
csharp
String name = "John";
Int32 count = 10;
Boolean isValid = true;- 使用语言关键字(、
string、int)bool - 禁止使用运行时类型(、
System.String)System.Int32
良好示例:
csharp
string name = "John";
int count = 10;
bool isValid = true;不良示例:
csharp
String name = "John";
Int32 count = 10;
Boolean isValid = true;타입 추론 (var)
类型推断 (var)
- 타입이 할당되는 내용으로부터 명백한 경우에만 를 사용함
var - 기본 제공 타입(Built-in type)은 명시적으로 기술함
좋은 예:
csharp
// 명백함
var orders = new List<Order>();
// 명백함
var customer = GetCustomer();
// 기본 타입은 명시
int count = 10;
// 기본 타입은 명시
string name = "John";나쁜 예:
csharp
// 기본 타입에서 var는 피함
var count = 10;
// 기본 타입에서 var는 피함
var name = "John";- 仅当类型可从赋值内容明确判断时使用
var - 内置类型需显式指定
良好示例:
csharp
// 类型明确
var orders = new List<Order>();
// 类型明确
var customer = GetCustomer();
// 内置类型显式指定
int count = 10;
// 内置类型显式指定
string name = "John";不良示例:
csharp
// 内置类型避免使用var
var count = 10;
// 内置类型避免使用var
var name = "John";문자열
字符串
문자열 보간 (String Interpolation)
字符串插值 (String Interpolation)
- 짧은 문자열 결합에는 문자열 보간을 사용함
좋은 예:
csharp
string message = $"Order {orderId} processed successfully";나쁜 예:
csharp
string message = "Order " + orderId + " processed successfully";- 短字符串拼接使用字符串插值
良好示例:
csharp
string message = $"Order {orderId} processed successfully";不良示例:
csharp
string message = "Order " + orderId + " processed successfully";StringBuilder
StringBuilder
- 루프 내에서 대량의 텍스트를 추가하는 경우 를 사용함
StringBuilder
좋은 예:
csharp
var builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
builder.Append($"Line {i}\n");
}- 循环中大量追加文本时使用
StringBuilder
良好示例:
csharp
var builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
builder.Append($"Line {i}\n");
}Raw String Literals
Raw String Literals
- 이스케이프 시퀀스보다 Raw String Literals를 우선함
좋은 예:
csharp
string json = """
{
"name": "John",
"age": 30
}
""";- 优先使用Raw String Literals而非转义序列
良好示例:
csharp
string json = """
{
"name": "John",
"age": 30
}
""";컬렉션과 객체 초기화
集合与对象初始化
컬렉션 초기화
集合初始化
- C# 12 이후의 Collection Expressions를 사용함 (앞부분의 "C# 12 최신 기능" 참조)
- 使用C# 12及以后的Collection Expressions(参考前文“C# 12最新功能”)
객체 이니셜라이저 (Object Initializer)
对象初始化器 (Object Initializer)
- 객체 이니셜라이저를 사용하여 생성을 간소화함
좋은 예:
csharp
var customer = new Customer
{
Name = "John",
Email = "john@example.com"
};- 使用对象初始化器简化对象创建
良好示例:
csharp
var customer = new Customer
{
Name = "John",
Email = "john@example.com"
};예외 처리 (Exception Handling)
异常处理 (Exception Handling)
구체적인 예외 캐치
捕获具体异常
- 일반적인 대신 구체적인 예외를 캐치함
System.Exception
좋은 예:
csharp
try
{
ProcessOrder(order);
}
catch (ArgumentNullException ex)
{
Logger.Error("Order is null", ex);
}나쁜 예:
csharp
try
{
ProcessOrder(order);
}
catch (Exception ex) // 너무 일반적임
{
Logger.Error("Error", ex);
}- 捕获具体异常而非通用的
System.Exception
良好示例:
csharp
try
{
ProcessOrder(order);
}
catch (ArgumentNullException ex)
{
Logger.Error("Order is null", ex);
}不良示例:
csharp
try
{
ProcessOrder(order);
}
catch (Exception ex) // 过于通用
{
Logger.Error("Error", ex);
}using 문
using语句
- try-finally 대신 문을 사용함
using
좋은 예:
csharp
using var connection = new SqlConnection(connectionString);
connection.Open();
// Process나쁜 예:
csharp
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
connection.Open();
// Process
}
finally
{
connection?.Dispose();
}- 使用语句替代try-finally
using
良好示例:
csharp
using var connection = new SqlConnection(connectionString);
connection.Open();
// 处理逻辑不良示例:
csharp
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
connection.Open();
// 处理逻辑
}
finally
{
connection?.Dispose();
}LINQ
LINQ
의미 있는 변수명
有意义的变量名
- 쿼리 변수에는 의미 있는 이름을 사용함
좋은 예:
csharp
var activeCustomers = from customer in customers
where customer.IsActive
select customer;- 查询变量使用有意义的名称
良好示例:
csharp
var activeCustomers = from customer in customers
where customer.IsActive
select customer;조기 필터링
提前过滤
- 절을 사용하여 조기에 데이터를 필터링함
where
좋은 예:
csharp
var result = customers
.Where(c => c.IsActive)
.Select(c => c.Name)
.ToList();- 使用子句提前过滤数据
where
良好示例:
csharp
var result = customers
.Where(c => c.IsActive)
.Select(c => c.Name)
.ToList();암시적 타입 지정
隐式类型指定
- LINQ 선언에서는 암시적 타입 지정을 사용함
좋은 예:
csharp
var query = from customer in customers
where customer.IsActive
select customer;- LINQ查询中使用隐式类型指定
良好示例:
csharp
var query = from customer in customers
where customer.IsActive
select customer;람다식 (Lambda Expressions)
Lambda表达式 (Lambda Expressions)
이벤트 핸들러
事件处理器
- 삭제가 필요 없는 핸들러에는 람다식을 사용함
좋은 예:
csharp
button.Click += (s, e) => ProcessClick();- 无需移除的处理器使用Lambda表达式
良好示例:
csharp
button.Click += (s, e) => ProcessClick();파라미터 수식어
参数修饰符
- C# 14 기능을 활용하여 타입 추론을 유지하면서 수식어를 사용함
좋은 예:
csharp
TryParse<int> parse = (text, out result) => int.TryParse(text, out result);- 利用C# 14功能,在保持类型推断的同时使用修饰符
良好示例:
csharp
TryParse<int> parse = (text, out result) => int.TryParse(text, out result);주석 (Comments)
注释 (Comments)
단일 행 주석
单行注释
- 간결한 설명에는 를 사용함
// - 주석 구분자 뒤에 공백을 하나 넣음
- 주석은 반드시 단독 행에 기술함 (코드와 같은 행에 기술 금지)
- 주석 앞에는 빈 행을 하나 넣음
좋은 예:
csharp
// 고객 주문을 처리함
ProcessOrder(order);
var processor = new OrderProcessor();
// 주문을 실행함
var result = processor.ProcessOrder(order);나쁜 예:
csharp
ProcessOrder(order); // 고객 주문을 처리함 (코드와 같은 행은 금지)
var processor = new OrderProcessor();
// 이 행의 앞에 빈 행이 없음 (나쁜 예)
var result = processor.ProcessOrder(order);- 简短说明使用
// - 注释分隔符后加一个空格
- 注释必须单独占一行(禁止与代码同行)
- 注释前空一行
良好示例:
csharp
// 处理客户订单
ProcessOrder(order);
var processor = new OrderProcessor();
// 执行订单处理
var result = processor.ProcessOrder(order);不良示例:
csharp
ProcessOrder(order); // 处理客户订单(禁止与代码同行)
var processor = new OrderProcessor();
// 此行前无空行(不良示例)
var result = processor.ProcessOrder(order);XML 문서
XML文档
- 퍼블릭 멤버에는 XML 문서를 사용함
좋은 예:
csharp
/// <summary>
/// 지정된 주문을 처리함
/// </summary>
/// <param name="order">처리할 주문</param>
/// <returns>처리 결과</returns>
public bool ProcessOrder(Order order)
{
// Implementation
}- 公共成员使用XML文档注释
良好示例:
csharp
/// <summary>
/// 处理指定的订单
/// </summary>
/// <param name="order">待处理的订单</param>
/// <returns>处理结果</returns>
public bool ProcessOrder(Order order)
{
// 实现代码
}정적 멤버 (Static Members)
静态成员 (Static Members)
클래스 이름에 의한 호출
通过类名调用
- 정적 멤버는 클래스 이름을 통해 호출함
좋은 예:
csharp
var result = OrderProcessor.ProcessOrder(order);나쁜 예:
csharp
var processor = new OrderProcessor();
// 정적 메서드를 인스턴스를 통해 호출하는 것은 오해의 소지가 있음
var result = processor.ProcessOrder(order);- 静态成员通过类名调用
良好示例:
csharp
var result = OrderProcessor.ProcessOrder(order);不良示例:
csharp
var processor = new OrderProcessor();
// 通过实例调用静态方法易引发误解
var result = processor.ProcessOrder(order);체크리스트 (Checklist)
检查清单 (Checklist)
코드 작성 전
代码编写前
- .NET/C#의 최신 기능 (C# 12/13/14)을 파악하고 있음
- 프로젝트의 타겟 프레임워크가 .NET 8 이후로 설정되어 있음
- 명명 규칙을 이해하고 있음
- 了解.NET/C#的最新功能(C# 12/13/14)
- 项目目标框架已设置为.NET 8及以后版本
- 理解命名规则
코드 작성 중
代码编写中
필수 규칙:
- 언더스코어 접두사를 절대 사용하지 않았음
- 중괄호를 생략하지 않았음 (1행이라도 반드시 사용함)
- 주석은 반드시 단독 행에 기술했음 (코드와 같은 행에 기술하지 않았음)
- 주석 앞에 빈 행을 하나 넣었음
C# 12 이후 기능:
- Primary Constructors를 사용하고 있음 (해당하는 경우)
- Collection Expressions를 사용하고 있음
- Default Lambda Parameters를 활용하고 있음 (해당하는 경우)
- Alias Any Type으로 복잡한 타입에 별칭을 붙였음 (해당하는 경우)
C# 13 이후 기능:
- Params Collections를 사용하고 있음 (해당하는 경우)
- New Lock Type을 사용하고 있음 (스레드 동기화가 필요한 경우)
- Partial Properties and Indexers를 활용하고 있음 (해당하는 경우)
- Implicit Index Access를 객체 이니셜라이저에서 사용하고 있음 (해당하는 경우)
C# 14 이후 기능:
- 키워드를 사용하여 backing field를 간결하게 기술했음
field - Extension Members를 활용하고 있음 (해당하는 경우)
- Null-Conditional Assignment를 활용하고 있음
- Lambda Parameters with Modifiers를 사용하고 있음 (해당하는 경우)
기본 규칙:
- 파일 스코프 네임스페이스를 사용하고 있음
- 언어 키워드 (,
string)를 사용하고 있음int - 를 적절히 사용하고 있음 (타입이 명백한 경우에만)
var - 문자열 보간을 사용하고 있음
- Raw String Literals를 사용하고 있음 (해당하는 경우)
- Object Initializers를 사용하고 있음
- 문을 사용하고 있음
using - 구체적인 예외를 캐치하고 있음
- LINQ 식에서 조기 필터링을 실시하고 있음
- 의미 있는 변수명을 사용하고 있음
- 주석이 간결하고 명확함
- 퍼블릭 멤버에 XML 문서를 기술했음
- Allman 스타일로 중괄호를 배치했음
- 들여쓰기에 공백 4개를 사용하고 있음
强制规则:
- 未使用下划线前缀
- 未省略大括号(即使单行也已使用)
- 注释均单独占一行(未与代码同行)
- 注释前已空一行
C# 12及以后功能:
- 已使用Primary Constructors(适用场景)
- 已使用Collection Expressions
- 已利用Default Lambda Parameters(适用场景)
- 已使用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)을 활용하고 있음
- 명명 규칙을 따르고 있음
- 가독성이 높고 유지보수하기 쉬운 코드임
- 代码风格一致
- 已运用.NET 8及以后的最新功能(C# 12/13/14)
- 已遵循命名规则
- 代码可读性高、易于维护