Loading...
Loading...
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.
npx skill4agent add creator-hian/claude-code-plugins csharp-code-style| Element | Convention | Example |
|---|---|---|
| Class | PascalCase | |
| Struct | SPascalCase | |
| Interface | IPascalCase | |
| Enum | EPascalCase | |
| Method (public) | PascalCase (동사+명사) | |
| Method (private) | camelCase | |
| Property | PascalCase | |
| Private Field | mPascalCase | |
| Local Variable | camelCase | |
| Parameter | camelCase | |
| Constant | ALL_CAPS | |
| Static readonly | ALL_CAPS | |
| Boolean Variable | bCamelCase / mbPascalCase | |
| Boolean Property | Is/Has/Can/Should | |
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: 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 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);
}// [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))// 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; }Unity Limitation:accessor is NOT available in Unity (requires .NET 5+ runtime). See Modern Patterns Reference for details and alternatives.init
// 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))
};
}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
}
}ClassName.SubName.csvar