Versions Compared
Key
- This line was added.
- This line was removed.
- Formatting was changed.
C# Coding Standards & Best Practices
Naming Conventions &
...
Code Structure
Naming Standards
...
Private fields
...
Use _camelCase with a leading underscore (e.g., _userName)
Constants
...
Use PascalCase without underscores (e.g., MaxRetryCount)
Public properties
...
Use PascalCase (e.g., UserName)
Local variables & parameters
...
Use camelCase (e.g., userId)
Interfaces
...
Prefix with I
...
using PascalCase (e.g., IUserRepository)
Async methods
...
Suffix with Async (e.g., GetUserAsync)
Order of content within the
...
class
- Private readonly fields (top of class)
...
- Constants
...
- Constructors
...
- Public properties
...
- Public methods
...
- Protected methods
...
- Private methods
...
- Nested classes/structs (if any)
Code Formatting
- Separate all methods with one blank line
...
- Split constructor parameters one per line for improved readability
...
- Use Ctrl + K + D to format code automatically – Maintain consistent indentation (typically 4 spaces)
...
- Remove unused usings via Ctrl + R + G
...
Examples
...
Classes
...
and methods
| Code Block | ||
|---|---|---|
| ||
namespace EGFlow.Parser.Services |
...
{
public class Blah
{
public Blah(
string thing,
int anotherThing
)
{
}
public string DoSomething(
string something,
int anotherSomething
)
{
return "Hello";
}
}
}
...
{
public class MyFoo
{
public Run(
int index,
string name
)
{
// Do some fun things
this.GetFoo(
index,
name
);
}
private string GetFoo(
int index,
string name
)
{
if (index > 1) {
return "{index} - {name}";
} else {
return name;
}
}
}
} |
Method calls within classes and services
| Code Block | ||
|---|---|---|
| ||
// simple request
var foo = this.GetMyBar(parameter1);
// multiple parameter request (>2)
var foo = this.GetMyBar(
parameter1,
parameter2,
parameter3
); |
String Handling
- Use string.Empty instead of ""
...
...
- Use string.IsNullOrEmpty() for null or empty checks
...
...
- Use string.IsNullOrWhiteSpace() for null, empty, or whitespace-only checks
...
- Use string interpolation ($"{variable}") instead of concatenation for readability
...
- Consider StringBuilder for extensive string manipulation in loops
...
LINQ
...
- Use .Count > 0 when you need the actual count
...
- Use .Any() for existence checks (more performant)
...
- Prefer Method syntax over Query syntax for consistency and readability
...
Code Block language csharp // Method syntax var activeUsers = users.Where(u => u.IsActive); // Query syntax var activeUsers = from u in users where u.IsActive select u;
- Avoid multiple enumeration; materialize
...
- collections with .ToList() when needed
...
- Use .FirstOrDefault() or .SingleOrDefault() appropriately based on expected results
Async/Await
...
- Always use async/await for I/O-bound operations (database, file, network)
...
...
- Never use .Wait() or .Result to prevent deadlocks
...
...
- Use ConfigureAwait(false) in library code to avoid context capture
...
- Return Task or Task<T> for async methods (not async void except event handlers)
Enum
...
- Use Enums in models instead of byte, int, or long for type safety
...
- Avoid
...
- nullable enums in LINQ queries unless explicitly required
...
...
- Define enums with explicit values
Method & Parameter
...
- Minimize method parameters (ideally ≤3-4 parameters)
...
- Follow the Single Responsibility Principle (SRP)
...
- Split large functions into smaller, focused methods
...
- Use meaningful method names that describe intent (Follow ActionVerb pattern in the name)
...
- Use optional parameters or method overloading judiciously
...
- Optional/default parameters should
...
- be stated last in the sequence of parameters. - AVOID optional/default parameters if possible.
Concurrency & Threading
...
- Use locking mechanisms (lock, SemaphoreSlim) to prevent race conditions
...
...
- Prefer async/await over explicit thread management
...
- Use thread-safe collections (ConcurrentDictionary, ConcurrentQueue) when appropriate
...
- Avoid shared mutable state where possible
...
- Consider using Interlocked class for simple atomic operations
Dependency Injection
...
- Avoid creating objects via new inside methods; use DI container
...
- Inject dependencies through constructors (constructor injection)
...
- Register services
...
- with appropriate lifetimes:
...
-
- Transient: New instance per request
...
- Scoped: Single instance per HTTP request/scope
...
- Singleton: Single instance for application lifetime
...
- Depend on interfaces/abstractions, not concrete implementations
...
- Avoid service locator pattern; use explicit injection
Exception Handling
...
- Use specific exception types rather than generic Exception
...
- Avoid catching exceptions you cannot handle meaningfully
...
- Log exceptions with sufficient context for debugging
...
- Use finally blocks or using statements for resource cleanup
...
- Don't swallow exceptions silently without logging
...
- Consider custom exception types for domain-specific errors
Performance & Memory Management
- Dispose of resources properly using statements or IDisposable
...
- Profile
...
- before optimizing; measure actual performance bottlenecks
...
- Consider lazy initialization (Lazy<T>) for expensive object creation
Code Quality & Maintainability
- Write XML documentation comments for public APIs
...
- Follow DRY principle (Don't Repeat Yourself)
...
- Use nullable reference types (C# 8.0+) to reduce null reference exceptions
...
- Implement proper logging
...
- at appropriate levels (Debug, Info, Warning, Error)
...
- Write unit tests with good coverage for critical business logic
...
- Test driven development! Write tests as you go.
Security Best Practices
...
- Validate all inputs at API boundaries
...
- Avoid exposing sensitive information in logs or error messages
...
- Implement proper authentication and authorization
...
- Use secure communication protocols (HTTPS, TLS)
...
- Keep dependencies updated to patch security vulnerabilities
API Design Best Practices
...
- Follow RESTful conventions for HTTP APIs
...
...
- Use appropriate HTTP status codes (200, 201, 400, 404, 500, etc.)
...
- Version your APIs for backward compatibility
...
- Implement proper error response models
...
- Use DTOs (Data Transfer Objects) to separate API contracts from domain models
...
- Document APIs using Swagger/OpenAPI
| Table of Contents |
|---|