csharp-code-style

C# code style and naming conventions based on POCU standards. Covers naming rules (mPascalCase for private, bBoolean prefix, EEnum prefix), code organization, C# 9.0 patterns. Use PROACTIVELY for C# code reviews, refactoring, or establishing project standards.

8 stars

Best use case

csharp-code-style is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

C# code style and naming conventions based on POCU standards. Covers naming rules (mPascalCase for private, bBoolean prefix, EEnum prefix), code organization, C# 9.0 patterns. Use PROACTIVELY for C# code reviews, refactoring, or establishing project standards.

Teams using csharp-code-style should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/csharp-code-style/SKILL.md --create-dirs "https://raw.githubusercontent.com/creator-hian/claude-code-plugins/main/csharp-plugin/skills/csharp-code-style/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/csharp-code-style/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How csharp-code-style Compares

Feature / Agentcsharp-code-styleStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

C# code style and naming conventions based on POCU standards. Covers naming rules (mPascalCase for private, bBoolean prefix, EEnum prefix), code organization, C# 9.0 patterns. Use PROACTIVELY for C# code reviews, refactoring, or establishing project standards.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# C# Code Style Guide

## Overview

C# 코딩 표준 (POCU 기반, C# 9.0 기준)

**Core Topics**:
- 명명 규칙 (m접두어, b접두어, E/S접두어)
- 코드 작성 규칙
- 클래스 구조 순서
- C# 9.0 패턴

## Language Note

이 문서는 한국어를 기본으로 작성되었으며, 코드 예제와 기술 용어는 영어를 사용합니다.
섹션 제목은 영어로 통일하고, 설명과 주석은 한국어로 작성합니다.

- **섹션 제목**: 영어 (Naming Conventions, Code Writing Rules 등)
- **설명/주석**: 한국어
- **코드 예제**: 영어 (변수명, 클래스명, 코드 코멘트)
- **표(Table) 헤더**: 영어, 내용은 영어 또는 한국어 혼용 가능

## Naming Conventions

### Quick Reference

| Element | Convention | Example |
|---------|-----------|---------|
| Class | PascalCase | `PlayerManager`, `OrderService` |
| Struct | SPascalCase | `SUserID`, `SPlayerData` |
| Interface | IPascalCase | `IDisposable`, `IOrderService` |
| Enum | EPascalCase | `EDirection`, `EOrderStatus` |
| Method (public) | PascalCase (동사+명사) | `GetAge()`, `ProcessOrder()` |
| Method (private) | camelCase | `getAge()`, `processOrder()` |
| Property | PascalCase | `Name`, `OrderID` |
| Private Field | mPascalCase | `mAge`, `mOrderRepository` |
| Local Variable | camelCase | `totalAmount`, `isValid` |
| Parameter | camelCase | `customerId`, `orderDate` |
| Constant | ALL_CAPS | `MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT` |
| Static readonly | ALL_CAPS | `MY_CONST_OBJECT` |
| Boolean Variable | bCamelCase / mbPascalCase | `bFired`, `mbIsEnabled` |
| Boolean Property | Is/Has/Can/Should | `IsFired`, `HasChildren` |

### Private Member Pattern

```csharp
public class OrderService
{
    // Private fields: m + PascalCase
    private readonly IOrderRepository mOrderRepository;
    private readonly ILogger mLogger;
    private int mRetryCount;
    private bool mbIsProcessing;  // boolean: mb prefix

    // Constructor parameter: camelCase (no prefix)
    public OrderService(IOrderRepository orderRepository, ILogger logger)
    {
        mOrderRepository = orderRepository;
        mLogger = logger;
    }

    // Public method: PascalCase
    public Order GetOrder(int orderId)
    {
        return getOrderInternal(orderId);
    }

    // Private method: camelCase
    private Order getOrderInternal(int orderId)
    {
        return mOrderRepository.Find(orderId);
    }
}
```

### Enum and Struct Prefixes

```csharp
// Enum: E prefix
public enum EDirection
{
    None,
    North,
    South,
    East,
    West
}

// Bit flags enum: Flags suffix
[Flags]
public enum EVisibilityFlags
{
    None = 0,
    Visible = 1,
    Hidden = 2,
    Collapsed = 4
}

// Struct: S prefix (readonly struct는 제외 가능)
public struct SUserID
{
    public int Value { get; }
}

// readonly record struct: S prefix 불필요
public readonly record struct UserID(int Value);
```

### Nullable Naming

```csharp
// Nullable parameter: OrNull suffix
public Animation GetAnimation(string nameOrNull)
{
    if (nameOrNull == null)
    {
        return DefaultAnimation;
    }
    return mAnimations[nameOrNull];
}

// Nullable return: OrNull suffix
public string GetNameOrNull()
{
    return mbHasName ? mName : null;
}

// Recursive function: Recursive suffix
public int FibonacciRecursive(int n)
{
    if (n <= 1)
    {
        return n;
    }
    return FibonacciRecursive(n - 1) + FibonacciRecursive(n - 2);
}
```

## Code Writing Rules

### Prohibited Patterns

```csharp
// [WRONG] var keyword
var order = GetOrder(1);
var items = new List<Item>();

// [CORRECT] Explicit type
Order order = GetOrder(1);
List<Item> items = new List<Item>();

// [WRONG] Null coalescing operator (??)
string name = inputName ?? "Default";

// [CORRECT] Explicit null check
string name;
if (inputName != null)
{
    name = inputName;
}
else
{
    name = "Default";
}

// [WRONG] using declaration (C# 8.0)
using FileStream stream = new FileStream(path, FileMode.Open);

// [CORRECT] using statement
using (FileStream stream = new FileStream(path, FileMode.Open))
{
    // ...
}

// [WRONG] target-typed new()
List<Order> orders = new();

// [CORRECT] Explicit type
List<Order> orders = new List<Order>();

// [WRONG] Async suffix
public async Task<Order> GetOrderAsync(int id);

// [CORRECT] No Async suffix
public async Task<Order> GetOrder(int id);

// [WRONG] inline out declaration
if (int.TryParse(input, out int result))

// [CORRECT] separate out declaration
int result;
if (int.TryParse(input, out result))
```

### Required Patterns

```csharp
// Always use braces, even for single line
if (condition)
{
    DoSomething();
}

// Float literals with f suffix
float value = 0.5f;
float another = 1.0f;

// Switch must have default case
switch (status)
{
    case EStatus.Active:
        Process();
        break;
    case EStatus.Inactive:
        Skip();
        break;
    default:
        Debug.Fail("Unknown status");
        break;
}

// Debug.Assert for all assumptions
Debug.Assert(order != null, "Order should not be null");
Debug.Assert(count > 0, "Count must be positive");

// Properties instead of getter/setter methods
// [WRONG]
public int GetAge() { return mAge; }
public void SetAge(int age) { mAge = age; }

// [CORRECT] (.NET 5+ only - NOT available in Unity)
public int Age { get; private init; }

// [CORRECT] (Unity compatible)
public int Age { get; private set; }
```

### C# 9.0 Patterns

> **Unity Limitation**: `init` accessor is NOT available in Unity (requires .NET 5+ runtime).
> See [Modern Patterns Reference](references/modern-patterns.md#unity-runtime-limitations) for details and alternatives.

```csharp
// private init (C# 9.0) - .NET 5+ only, NOT available in Unity
public class Customer
{
    public string Name { get; private init; }  // Use 'private set' in Unity
    public string Email { get; private init; }
}

// Record for immutable data
public record OrderDto(int Id, string CustomerName, decimal TotalAmount);

// Pattern matching switch expression (available in Unity)
public string GetStatusMessage(EOrderStatus status)
{
    return status switch
    {
        EOrderStatus.Pending => "Order is pending",
        EOrderStatus.Completed => "Order completed",
        _ => throw new ArgumentOutOfRangeException(nameof(status))
    };
}
```

## Class Structure Order

```csharp
public class OrderService : IOrderService
{
    // 1. Constants
    private const int MAX_RETRY_COUNT = 3;
    public static readonly TimeSpan DEFAULT_TIMEOUT = TimeSpan.FromSeconds(30);

    // 2. Private member variables
    private readonly IOrderRepository mOrderRepository;
    private readonly ILogger mLogger;
    private int mProcessedCount;
    private bool mbIsInitialized;

    // 3. Properties (with private member above if needed)
    public int ProcessedCount => mProcessedCount;
    public bool IsInitialized => mbIsInitialized;

    // 4. Constructors
    public OrderService(IOrderRepository orderRepository, ILogger logger)
    {
        mOrderRepository = orderRepository;
        mLogger = logger;
    }

    // 5. Public methods
    public Order GetOrder(int id)
    {
        Debug.Assert(id > 0, "ID must be positive");
        return mOrderRepository.Find(id);
    }

    public void ProcessOrder(Order order)
    {
        validateOrder(order);
        processInternal(order);
    }

    // 6. Private methods
    private void validateOrder(Order order)
    {
        Debug.Assert(order != null);
    }

    private void processInternal(Order order)
    {
        // Implementation
    }
}
```

## File Organization

- 각 클래스는 독립된 파일에 작성
- 파일명 = 클래스명 (정확히 일치)
- Partial 클래스: `ClassName.SubName.cs`

## Reference Documentation

### [Naming Conventions](references/naming-conventions.md)
Complete naming rules:
- m/mb 접두어 상세
- E/S 접두어 규칙
- OrNull 접미어 패턴
- ALL_CAPS 상수 규칙

### [Modern Patterns](references/modern-patterns.md)
C# 9.0 language features:
- Records and init-only properties
- Pattern matching
- File-scoped namespaces (C# 10)
- 금지 패턴 상세

### [Error Handling](references/error-handling.md)
Error handling patterns:
- Debug.Assert 사용
- 경계에서만 예외 처리
- null 반환/매개변수 회피
- 유효성 검증 패턴

## Key Principles

1. **가독성 최우선**: 명확하고 이해하기 쉬운 코드 작성
2. **명시적 타입**: `var` 사용 금지, 타입 명시
3. **Null 안전**: OrNull 접미어로 nullable 명시
4. **Assertion**: 모든 가정에 Debug.Assert 사용
5. **경계 검증**: 외부 데이터는 경계에서만 검증
6. **Use init**: Prefer C# 9.0 private init (.NET 5+ only, NOT available in Unity)
7. **No Emoji**: 코드 예제 및 문서에서 이모지 사용 금지, 텍스트 태그 사용 ([WRONG], [CORRECT], [CAUTION])

Related Skills

unity-csharp-fundamentals

8
from creator-hian/claude-code-plugins

Unity C# fundamental patterns including TryGetComponent, SerializeField, RequireComponent, and safe coding practices. Essential patterns for robust Unity development. Use PROACTIVELY for any Unity C# code to ensure best practices.

csharp-xml-docs

8
from creator-hian/claude-code-plugins

C# XML documentation with on-demand Haiku→Expert Review→Final workflow. Flexible Korean/English language support. Use when documenting C# APIs, properties, methods, classes, and interfaces.

csharp-async-patterns

8
from creator-hian/claude-code-plugins

Modern C# asynchronous programming patterns using async/await, proper CancellationToken usage, and error handling in async code. Use when guidance needed on async/await best practices, Task composition and coordination, ConfigureAwait usage, ValueTask optimization, or async operation cancellation patterns. Pure .NET framework patterns applicable to any C# application.

unity-vcontainer

8
from creator-hian/claude-code-plugins

VContainer dependency injection expert specializing in IoC container configuration, lifecycle management, and Unity-optimized DI patterns. Masters dependency resolution, scoped containers, and testable architecture design. Use PROACTIVELY for VContainer setup, service registration, or SOLID principle implementation.

unity-unitask

8
from creator-hian/claude-code-plugins

UniTask library expert specializing in allocation-free async/await patterns, coroutine migration, and Unity-optimized asynchronous programming. Masters UniTask performance optimizations, cancellation handling, and memory-efficient async operations. Use PROACTIVELY for UniTask implementation, async optimization, or coroutine replacement.

unity-unirx

8
from creator-hian/claude-code-plugins

UniRx (Reactive Extensions) library expert for legacy Unity projects. Specializes in UniRx-specific patterns, Observable streams, and ReactiveProperty. Use for maintaining existing UniRx codebases. For new projects, use unity-r3 skill instead.

unity-ui

8
from creator-hian/claude-code-plugins

Build and optimize Unity UI with UI Toolkit and UGUI. Masters responsive layouts, event systems, and performance optimization. Use for UI implementation, Canvas optimization, or cross-platform UI challenges.

unity-textmeshpro

8
from creator-hian/claude-code-plugins

TextMeshPro (TMPro) expert for Unity text rendering with advanced typography, performance optimization, and professional text effects. Masters font asset creation, dynamic fonts, rich text formatting, material presets, and text mesh optimization. Use PROACTIVELY for text rendering, font management, localization text, UI text performance, or text effects implementation.

unity-testrunner

8
from creator-hian/claude-code-plugins

Unity Test Framework CLI automation and test writing patterns. Masters batchmode execution, NUnit assertions, EditMode/PlayMode testing, and TDD workflows. Use PROACTIVELY for test automation, CI/CD pipelines, or test-driven development in Unity.

unity-r3

8
from creator-hian/claude-code-plugins

R3 (Reactive Extensions) library expert specializing in modern reactive programming patterns, event-driven architectures, and Observable streams. Masters R3-specific features, async enumerable integration, and Unity-optimized reactive patterns. Use PROACTIVELY for R3 implementation, reactive programming, or MVVM/MVP architecture.

unity-performance

8
from creator-hian/claude-code-plugins

Optimize Unity game performance through profiling, draw call reduction, and resource management. Masters batching, LOD, occlusion culling, and mobile optimization. Use for performance bottlenecks, frame rate issues, or optimization strategies.

unity-networking

8
from creator-hian/claude-code-plugins

Implement multiplayer games with Unity Netcode, Mirror, or Photon. Masters client-server architecture, state synchronization, and lag compensation. Use for multiplayer features, networking issues, or real-time synchronization.