| name | csharp |
| description | Write production-ready C# and .NET code following modern best practices. Use when building .NET applications, writing async/await code, using Entity Framework Core, implementing dependency injection, configuring nullable reference types, or optimizing C# performance. |
| metadata | {"author":"AgentX","version":"1.0.0","created":"2025-01-15","updated":"2025-01-15"} |
| compatibility | {"languages":["csharp"],"frameworks":["dotnet","aspnet-core"],"platforms":["windows","linux","macos"]} |
C# / .NET Development
Purpose: Production-ready C# and .NET development standards for building secure, performant, maintainable applications.
Audience: Engineers building .NET applications with C#, ASP.NET Core, Entity Framework Core.
Standard: Follows github/awesome-copilot .NET development patterns.
When to Use This Skill
- Building .NET applications with C#
- Writing async/await code patterns
- Using Entity Framework Core for data access
- Implementing dependency injection
- Configuring nullable reference types
Decision Tree
C# Project Decision
+-- Building a web API?
| +-- REST API? -> ASP.NET Core Minimal API or Controllers
| +-- gRPC service? -> ASP.NET Core gRPC
+-- Data access needed?
| +-- Relational DB? -> Entity Framework Core
| +-- NoSQL / document? -> Azure Cosmos DB SDK
| +-- Simple queries? -> Dapper
+-- Background processing?
| +-- Scheduled jobs? -> IHostedService / BackgroundService
| +-- Message-driven? -> Azure Service Bus + Worker Service
+-- Desktop / cross-platform UI?
| +-- Cross-platform? -> .NET MAUI
| +-- Windows only? -> WPF or WinForms
+-- Library / shared code? -> .NET Class Library with NuGet packaging
Prerequisites
- .NET 8+ SDK installed
- C# 12+ language features
- IDE with C# support
Quick Reference
| Need | Solution | Pattern |
|---|
| Async code | Use async/await everywhere | async Task<T> GetDataAsync() |
| Null safety | Enable nullable reference types | <Nullable>enable</Nullable> |
| Error handling | Use Result types or exceptions | try-catch with specific types |
| DI | Constructor injection with interfaces | IServiceCollection |
| Testing | xUnit, NUnit, or TUnit | [Fact], [Test] |
| Logging | ILogger<T> with structured logging | _logger.LogInformation("User {UserId}", id) |
C# Language Version
Current: C# 14 (.NET 10+)
Minimum: C# 8 (.NET Core 3.1+)
Modern C# Features (Use These)
namespace MyApp.Services;
public class UserService(ILogger<UserService> logger, IUserRepository repo)
{
public async Task<User> GetUserAsync(int id) =>
await repo.GetByIdAsync(id);
}
public class User
{
public required int Id { get; init; }
public required string Name { get; init; }
}
string json = """
{
"name": "John",
"age": 30
}
""";
string GetStatus(Order order) => order switch
{
{ Status: "pending", TotalAmount: > 1000 } => "High value pending",
{ Status: "shipped" } => "In transit",
{ Status: "delivered" } => "Completed",
_ => "Unknown"
};
Core Rules
- Async All the Way - Use
async/await throughout the call chain; never call .Result or .Wait() on tasks
- Enable Nullable References - Set
<Nullable>enable</Nullable> in .csproj; treat all warnings as errors
- Constructor Injection - Use constructor injection with interfaces for all dependencies; avoid service locator pattern
- Structured Logging - Use
ILogger<T> with message templates ({UserId}), not string interpolation
- Pass CancellationToken - Accept and forward
CancellationToken in all async methods
- Catch Specific Exceptions - Catch the most specific exception type; never catch bare
Exception without re-throwing
- Use Modern C# Features - Prefer primary constructors, file-scoped namespaces, pattern matching, and raw string literals
- Validate Inputs Early - Validate method arguments at entry points using guard clauses or
ArgumentException
Anti-Patterns
| Issue | Problem | Solution |
|---|
| Sync over async | Using .Result or .Wait() | Always use await |
| No cancellation | Long operations can't be cancelled | Pass CancellationToken |
| N+1 queries | Loading related data in loop | Use .Include() for eager loading |
| Magic strings | Hardcoded strings everywhere | Use nameof() or constants |
| No null checks | NullReferenceException | Enable nullable reference types |
| Poor logging | Unstructured log messages | Use structured logging with parameters |
Resources
See Also: Skills.md - AGENTS.md
Last Updated: January 27, 2026
Scripts
| Script | Purpose | Usage |
|---|
scaffold-solution.ps1 | Create .NET solution with API/Core/Infrastructure + xUnit tests | ./scripts/scaffold-solution.ps1 -Name MyApp [-Framework net9.0] |
Troubleshooting
| Issue | Solution |
|---|
| Deadlock with async code | Use async/await all the way up, never call .Result or .Wait() on async methods |
| EF Core migration errors | Run dotnet ef migrations list to check state, recreate if corrupted |
| Nullable warnings everywhere | Enable Nullable in .csproj, fix warnings incrementally |
References