| name | reviewing-dotnet-code |
| description | Reviews and generates .NET/C# code following Microsoft conventions and modern patterns.
Use when reviewing C# files, writing .NET code, refactoring, or when user mentions
"C#", ".NET", "dotnet", "csharp", or asks about naming conventions in .NET projects.
|
| tools | ["Read","Edit","Grep","Glob"] |
Reviewing .NET Code
Apply Microsoft's .NET coding conventions and modern C# patterns when reviewing or generating code.
Quick Reference
Naming Conventions
| Element | Style | Example |
|---|
| Classes, Records | PascalCase | CustomerService, OrderRecord |
| Interfaces | IPascalCase | IRepository, IDisposable |
| Methods | PascalCase | GetCustomer(), ValidateOrder() |
| Properties | PascalCase | FirstName, IsActive |
| Public Fields | PascalCase | MaxRetryCount |
| Parameters | camelCase | customerId, orderDate |
| Local Variables | camelCase | itemCount, isValid |
| Private Fields | _camelCase | _connectionString, _logger |
| Constants | PascalCase | DefaultTimeout, MaxItems |
| Enums | PascalCase (singular) | Color.Red, Status.Active |
| Async Methods | PascalCaseAsync | GetCustomerAsync() |
Type Keywords
Always use language keywords over framework types:
string name;
int count;
bool isActive;
String name;
Int32 count;
Boolean isActive;
Modern C# Patterns (C# 10+)
namespace MyApp.Services;
List<Customer> customers = new();
string[] items = ["one", "two", "three"];
public class Service(ILogger logger, IRepository repo);
public record CustomerDto(string Name, string Email);
var json = """
{ "name": "test" }
""";
Review Workflow
Step 1: Check Naming
Scan for naming violations:
- Classes/methods not in PascalCase
- Private fields without underscore prefix
- Parameters/locals not in camelCase
- Async methods missing
Async suffix
Step 2: Check Patterns
Look for outdated patterns:
String instead of string
new List<T>() instead of new() or []
- Block-scoped namespaces
- Manual null checks instead of
?. or ??
Step 3: Check Async/Await
Flag async anti-patterns:
async void (except event handlers)
.Result or .Wait() blocking calls
- Missing
ConfigureAwait(false) in libraries
Step 4: Check Exception Handling
Verify exception patterns:
- Catching
Exception instead of specific types
- Empty catch blocks
- Not using
using for disposables
Step 5: Check LINQ Usage
Identify LINQ opportunities:
- Manual loops that could be
Select/Where/Any
- Multiple enumerations (should
.ToList())
When to Read Reference Files
Read REFERENCE.md when:
- User asks for detailed naming rules
- Reviewing complex class hierarchies
- Need specific async/await guidance
- Reviewing exception handling patterns
Read EXAMPLES.md when:
- Need before/after refactoring samples
- Showing concrete improvements
- User asks "how should this look?"
Anti-Patterns to Flag
Critical (Always Flag)
public async void ProcessData() { }
var result = GetDataAsync().Result;
task.Wait();
try { } catch { }
catch (Exception ex) { }
Important (Flag in Reviews)
int iCount;
string strName;
const int MAX_SIZE = 100;
String name;
Code Generation Templates
Service Class
namespace MyApp.Services;
public class CustomerService(
ILogger<CustomerService> logger,
ICustomerRepository repository)
{
public async Task<Customer?> GetByIdAsync(
int id,
CancellationToken cancellationToken = default)
{
logger.LogDebug("Getting customer {Id}", id);
return await repository.FindByIdAsync(id, cancellationToken);
}
}
Record DTO
namespace MyApp.Models;
public record CustomerDto(
int Id,
string Name,
string Email,
DateOnly CreatedDate);
Interface
namespace MyApp.Abstractions;
public interface ICustomerRepository
{
Task<Customer?> FindByIdAsync(int id, CancellationToken ct = default);
Task<IReadOnlyList<Customer>> GetAllAsync(CancellationToken ct = default);
Task AddAsync(Customer customer, CancellationToken ct = default);
}
EditorConfig Integration
If project has .editorconfig, defer to those rules for style preferences. Check before suggesting style changes.
Review Checklist