C# Coding Standard

C# coding standard for Cadtastic Solutions.

View the Project on GitHub Cadtastic-Solutions/C-Sharp-Coding-Standard

Naming Conventions

Purpose

Consistent naming conventions are fundamental to code quality and team efficiency. They serve multiple critical purposes:

Readability

Maintainability

Consistency

General Guidelines

Capitalization Rules

Rule Type Convention Example
Class, Record PascalCase OrderProcessor
Interface PascalCase with 'I' prefix IOrderProcessor
Method PascalCase ProcessOrder
Property PascalCase FirstName
Parameter camelCase firstName
Local Variable camelCase orderTotal
Private Field camelCase with underscore prefix _orderProcessor
Constant PascalCase MaxRetryCount
Enum PascalCase OrderStatus
Delegate PascalCase ProcessCompleted

Specific Naming Rules

Classes and Records

// Good
public class CustomerService
public class OrderProcessor
public record CustomerDetails

// Bad
public class customerService        // Wrong casing
public class Process_Order          // Using underscore
public class Util                   // Too vague

Interfaces

// Good
public interface ICustomerService
public interface IOrderProcessor
public interface IRepository<TEntity>

// Bad
public interface CustomerService    // Missing 'I' prefix
public interface IService           // Too vague
public interface ICustSrvc          // Abbreviated

Methods

// Good
public async Task<Order> ProcessOrderAsync()
public void ValidateCustomer()
public string FormatName()

// Bad
public void Process()               // Too vague
public async Task GetDataAsync()    // Too generic
public void DoStuff()               // Meaningless

Properties

// Good
public string FirstName { get; set; }
public int OrderCount { get; private set; }
public bool IsActive { get; }

// Bad
public string fname { get; set; }   // Wrong casing
public int NUMBER { get; set; }     // Wrong casing
public bool flag { get; set; }      // Too vague

Fields

// Good
private readonly ILogger _logger;
private readonly ICustomerRepository _customerRepository;
private int _retryCount;

// Bad
private readonly ILogger logger;              // Missing underscore
private readonly ICustomerRepository m_repo;  // Wrong prefix
private int retry_count;                      // Using underscore in name

Parameters

// Good
public void ProcessOrder(Order order)
public void SendEmail(string recipientEmail, string subject)

// Bad
public void ProcessOrder(Order Order)  // Conflicts with type name
public void SendEmail(string e)        // Too short

Variables

// Good
var customerCount = 0;
var isProcessing = false;
var orderDate = DateTime.Now;

// Bad
var c = 0;                          // Too short
var FLAG = false;                   // Wrong casing
var strName = "John";               // Type prefix unnecessary

Special Cases

Async Methods

// Good
public async Task ProcessOrderAsync()
public async Task<Order> GetOrderAsync(int orderId)

// Bad
public async Task AsyncProcessOrder()   // Wrong suffix placement
public async Task<Order> GetOrder()     // Missing Async suffix

Event Handlers

// Good
public event EventHandler<OrderProcessedEventArgs> OrderProcessed;
protected virtual void OnOrderProcessed(OrderProcessedEventArgs e)

// Bad
public event EventHandler<OrderProcessedEventArgs> HandleOrderProcessed;
protected virtual void OrderProcessedHandler(OrderProcessedEventArgs e)

Generic Type Parameters

// Good
public interface IRepository<TEntity>
public class DataProcessor<TInput, TOutput>

// Bad
public interface IRepository<T>              // Too generic
public class DataProcessor<Type1, Type2>     // Unclear purpose

File Names

Rules

CustomerService.cs
ICustomerService.cs
OrderProcessor.cs

Enforcement

Tools Configuration

.editorconfig

# Naming conventions
dotnet_naming_rule.interface_should_be_begins_with_i.severity = error
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.private_members_with_underscore.symbols  = private_fields
dotnet_naming_rule.private_members_with_underscore.style    = prefix_underscore
dotnet_naming_rule.private_members_with_underscore.severity = error

StyleCop

<Analyzers>
  <Naming>
    <ElementKind>Class</ElementKind>
    <Style>PascalCase</Style>
  </Naming>
</Analyzers>

Common Pitfalls

Avoid

Examples of What to Avoid

// Don't use Hungarian notation
string strName;                    // Use 'name' instead
int iCount;                        // Use 'count' instead

// Don't use single letters (except in loops)
var x = 0;                         // Use meaningful names
var s = "test";                    // Use descriptive names

// Don't use abbreviations
var custSvc;                       // Use 'customerService' instead
var addr;                          // Use 'address' instead

Additional Resources