| name | csharp-code-style |
| description | 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. |
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
public class OrderService
{
private readonly IOrderRepository mOrderRepository;
private readonly ILogger mLogger;
private int mRetryCount;
private bool mbIsProcessing;
public OrderService(IOrderRepository orderRepository, ILogger logger)
{
mOrderRepository = orderRepository;
mLogger = logger;
}
public Order GetOrder(int orderId)
{
return getOrderInternal(orderId);
}
private Order getOrderInternal(int orderId)
{
return mOrderRepository.Find(orderId);
}
}
Enum and Struct Prefixes
public enum EDirection
{
None,
North,
South,
East,
West
}
[Flags]
public enum EVisibilityFlags
{
None = 0,
Visible = 1,
Hidden = 2,
Collapsed = 4
}
public struct SUserID
{
public int Value { get; }
}
public readonly record struct UserID(int Value);
Nullable Naming
public Animation GetAnimation(string nameOrNull)
{
if (nameOrNull == null)
{
return DefaultAnimation;
}
return mAnimations[nameOrNull];
}
public string GetNameOrNull()
{
return mbHasName ? mName : null;
}
public int FibonacciRecursive(int n)
{
if (n <= 1)
{
return n;
}
return FibonacciRecursive(n - 1) + FibonacciRecursive(n - 2);
}
Code Writing Rules
Prohibited Patterns
var order = GetOrder(1);
var items = new List<Item>();
Order order = GetOrder(1);
List<Item> items = new List<Item>();
string name = inputName ?? "Default";
string name;
if (inputName != null)
{
name = inputName;
}
else
{
name = "Default";
}
using FileStream stream = new FileStream(path, FileMode.Open);
using (FileStream stream = new FileStream(path, FileMode.Open))
{
}
List<Order> orders = new();
List<Order> orders = new List<Order>();
public async Task<Order> GetOrderAsync(int id);
public async Task<Order> GetOrder(int id);
if (int.TryParse(input, out int result))
int result;
if (int.TryParse(input, out result))
Required Patterns
if (condition)
{
DoSomething();
}
float value = 0.5f;
float another = 1.0f;
switch (status)
{
case EStatus.Active:
Process();
break;
case EStatus.Inactive:
Skip();
break;
default:
Debug.Fail("Unknown status");
break;
}
Debug.Assert(order != null, "Order should not be null");
Debug.Assert(count > 0, "Count must be positive");
public int GetAge() { return mAge; }
public void SetAge(int age) { mAge = age; }
public int Age { get; private init; }
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 for details and alternatives.
public class Customer
{
public string Name { get; private init; }
public string Email { get; private init; }
}
public record OrderDto(int Id, string CustomerName, decimal TotalAmount);
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
public class OrderService : IOrderService
{
private const int MAX_RETRY_COUNT = 3;
public static readonly TimeSpan DEFAULT_TIMEOUT = TimeSpan.FromSeconds(30);
private readonly IOrderRepository mOrderRepository;
private readonly ILogger mLogger;
private int mProcessedCount;
private bool mbIsInitialized;
public int ProcessedCount => mProcessedCount;
public bool IsInitialized => mbIsInitialized;
public OrderService(IOrderRepository orderRepository, ILogger logger)
{
mOrderRepository = orderRepository;
mLogger = logger;
}
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);
}
private void validateOrder(Order order)
{
Debug.Assert(order != null);
}
private void processInternal(Order order)
{
}
}
File Organization
- ๊ฐ ํด๋์ค๋ ๋
๋ฆฝ๋ ํ์ผ์ ์์ฑ
- ํ์ผ๋ช
= ํด๋์ค๋ช
(์ ํํ ์ผ์น)
- Partial ํด๋์ค:
ClassName.SubName.cs
Reference Documentation
Complete naming rules:
- m/mb ์ ๋์ด ์์ธ
- E/S ์ ๋์ด ๊ท์น
- OrNull ์ ๋ฏธ์ด ํจํด
- ALL_CAPS ์์ ๊ท์น
C# 9.0 language features:
- Records and init-only properties
- Pattern matching
- File-scoped namespaces (C# 10)
- ๊ธ์ง ํจํด ์์ธ
Error handling patterns:
- Debug.Assert ์ฌ์ฉ
- ๊ฒฝ๊ณ์์๋ง ์์ธ ์ฒ๋ฆฌ
- null ๋ฐํ/๋งค๊ฐ๋ณ์ ํํผ
- ์ ํจ์ฑ ๊ฒ์ฆ ํจํด
Key Principles
- ๊ฐ๋
์ฑ ์ต์ฐ์ : ๋ช
ํํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด ์ฝ๋ ์์ฑ
- ๋ช
์์ ํ์
:
var ์ฌ์ฉ ๊ธ์ง, ํ์
๋ช
์
- Null ์์ : OrNull ์ ๋ฏธ์ด๋ก nullable ๋ช
์
- Assertion: ๋ชจ๋ ๊ฐ์ ์ Debug.Assert ์ฌ์ฉ
- ๊ฒฝ๊ณ ๊ฒ์ฆ: ์ธ๋ถ ๋ฐ์ดํฐ๋ ๊ฒฝ๊ณ์์๋ง ๊ฒ์ฆ
- Use init: Prefer C# 9.0 private init (.NET 5+ only, NOT available in Unity)
- No Emoji: ์ฝ๋ ์์ ๋ฐ ๋ฌธ์์์ ์ด๋ชจ์ง ์ฌ์ฉ ๊ธ์ง, ํ
์คํธ ํ๊ทธ ์ฌ์ฉ ([WRONG], [CORRECT], [CAUTION])