Versions Compared
compared with
Key
- This line was added.
- This line was removed.
- Formatting was changed.
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 MyFoo
{
public Run(
int index,
string name
)
{
// Do some fun things
this.GetFoo(
index,
name
);
}
publicprivate string GetFoo(
int index,
string name
)
{
return "{index} - {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 |
|---|