coding-conventions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Coding 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

  • field
    키워드를 사용하여 명시적인 backing 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();
}
  • 使用
    using
    语句替代try-finally
良好示例:
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 이후 기능:
  • field
    키워드를 사용하여 backing 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)
  • 已遵循命名规则
  • 代码可读性高、易于维护