csharp

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,

SKILL.md

GitHub

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

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)

// File-scoped namespaces (C# 10+)
namespace MyApp.Services;

// Primary constructors (C# 12+)
public class UserService(ILogger<UserService> logger, IUserRepository repo)
{
 public async Task<User> GetUserAsync(int id) => 
 await repo.GetByIdAsync(id);
}

// Required properties (C# 11+)
public class User
{
 public required int Id { get; init; }
 public required string Name { get; init; }
}

// Raw string literals (C# 11+)
string json = """
 {
 "name": "John",
 "age": 30
 }
 """;

// Pattern matching
string GetStatus(Order order) => order switch
{
 { Status: "pending", TotalAmount: > 1000 } => "High value pending",
 { Status: "shipped" } => "In transit",
 { Status: "delivered" } => "Completed",
 _ => "Unknown"
};

Common Pitfalls

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