Back-end Coding Conventions
Last updated on
C# Coding Conventions
This document outlines commonly accepted coding conventions for C# to promote consistency and readability in codebases.
Table of Contents
Naming Conventions
Item | Convention | Example |
---|---|---|
Class names | PascalCase | CustomerOrder |
Interface names | PascalCase, prefix I |
IRepository |
Method names | PascalCase | CalculateTotal() |
Property names | PascalCase | OrderAmount |
Local variable names | camelCase | totalAmount |
Parameter names | camelCase | string customerName |
Constant | PascalCase | MAX_COUNTING_NUMBER |
Private fields | _camelCase |
_logger |
Enum types and values | PascalCase | OrderStatus.Pending |
Layout and Formatting
- Place each statement on a new line.
Bracing
- Use K&R style braces (Allman style is also acceptable if consistent).
if (condition)
{
DoSomething();
}
else
{
DoSomethingElse();
}
Commenting
- Use XML documentation for public APIs
- Use // for inline or single-line comments.
- Avoid redundant comments that state the obvious.
/// <summary>
/// Update an item using a patch request
/// </summary>
/// <remarks>
/// **Details:**
/// - Partially updates an item for the specified store.
/// </remarks>
/// <param name="storeID">Store ID</param>
/// <param name="id">Item ID</param>
/// <param name="request">Patch request for item</param>
/// <returns>The updated item with details</returns>
[ProducesResponseType(typeof(BaseResponse<ItemWithDetailsQueryDTO>), 200)]
[HttpPatch("{storeID}/{id}")]
public async Task<IActionResult> UpdateItem(string storeID, Guid id, [FromBody] JsonPatchDocument<ItemUpdateRequest> request)
{
var dto = _mapper.Map<JsonPatchDocument<ItemWithDetailsQueryDTO>>(request);
var response = await _itemCommandService.UpdateItem(storeID, id, dto);
return Ok(new BaseResponse<ItemWithDetailsQueryDTO>(response));
}
Framework DI
- Use ILogger
via DI. - With DI service mark it with private and readonly
private readonly ILogger<MyService> _logger;
- Using primary contructor if you can
public class ItemsController(
IItemCommandService itemCommandService,
IItemQueryService itemQueryService,
IMapper mapper) : ControllerBase
{
private readonly IItemCommandService _itemCommandService = itemCommandService;
private readonly IItemQueryService _itemQueryService = itemQueryService;
private readonly IMapper _mapper = mapper;
Language Usage
- Use var when the type is obvious or repeated on the right-hand side:
var stream = new FileStream("file.txt", FileMode.Open);
- Prefer string interpolation over concatenation:
$"Hello, {name}!"
- Use expression-bodied members for simple properties and methods:
public int Square(int x) => x * x;
- Use using statements or using declarations for disposable resources.
using var stream = new FileStream("file.txt", FileMode.Open);
- Use the
Async
suffix** for all asynchronous methods
public async Task SaveChangesAsync()
- Use verbatim and interpolation string if that is multiple line and complicated string
var query = @"
SELECT
CASE
WHEN MIN(r.KitchenIDs) = MAX(r.KitchenIDs) THEN MIN(r.KitchenIDs)
ELSE NULL
END AS KitchentIDs
FROM (
SELECT i.ItemID, STRING_AGG(k.KitchenID , ',') WITHIN GROUP (ORDER BY k.KitchenID) AS KitchenIDs FROM pos.Items i
LEFT JOIN pos.ItemKitchenDetails AS k
ON i.ItemID = k.ItemID AND k.StoreID = @StoreID AND k.IsDeleted = 0
WHERE i.StoreID = @StoreID AND i.DeptDeptID = @ItemCategoryID AND i.IsDeleted = 0
GROUP BY i.ItemID
) AS r
";