api-versioning
API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
Modern C# language features for .NET 10 and C# 14. Covers primary constructors, collection expressions, the field keyword, extension members, records, pattern matching, spans, and raw string literals. Load this skill when writing any new C# code, reviewing existing code for
$ npx -y skills add codewithmukesh/dotnet-claude-kit --skill modern-csharp --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/modern-csharpContext preview
The summary Claude sees to decide when to auto-load this skill.
Modern C# language features for .NET 10 and C# 14. Covers primary constructors, collection expressions, the field keyword, extension members, records, pattern matching, spans, and raw string literals. Load this skill when writing any new C# code, reviewing existing code for
name: modern-csharp description: > Modern C# language features for .NET 10 and C# 14. Covers primary constructors, collection expressions, the field keyword, extension members, records, pattern matching, spans, and raw string literals. Load this skill when writing any new C# code, reviewing existing code for modernization, using "modern C#", "C# 14", "primary constructor", "collection expression", "records", "pattern matching", "span", "field keyword", or "extension members". Always loaded as the baseline for all agents.
1. **Use the newest stable features** — C# 14 is the target. Prefer language-level constructs over library workarounds. 2. **Readability over cleverness** — Pattern matching and expression-bodied members improve readability when used appropriately; deeply nested patterns do not. 3. **Value types where possible** — Prefer `record struct`, `Span<T>`, and stack allocation to reduce GC pressure. 4. **Immutability by default** — Use `record`, `readonly`, `init`, and `required` to make illegal states unrepresentable.
| Feature | Usage | Example | |---------|-------|---------| | Primary constructors | DI injection, eliminate field assignments | `public class OrderService(IOrderRepo repo, TimeProvider clock) { }` | | Collection expressions | `[]` for all collection types + spread | `List<string> names = ["Alice", "Bob"];` / `int[] all = [..a, ..b, 99];` | | Records | DTOs, value objects, immutable data | `public record CreateOrderRequest(string CustomerId, List<OrderItem> Items);` | | `readonly record struct` | Small stack-allocated value types | `public readonly record struct Money(decimal Amount, string Currency);` | | Pattern matching | Switch expressions, list/property patterns | `order switch { { Total: > 1000 } => "Premium", _ => "Standard" };` | | List patterns | Deconstruct arrays/lists | `items switch { [] => "Empty", [var x] => $"One: {x}", [var f, .., var l] => $"{f}..{l}" };` | | `Span<T>` | Zero-allocation slicing | `ReadOnlySpan<char> trimmed = input.Trim(); int.TryParse(trimmed[4..], out id);` | | Raw string literals | Multi-line SQL, JSON, XML | `var sql = """ SELECT ... """;` / interpolated: `$$""" {"id": "{{id}}"} """;` | | `required` members | Enforce initialization | `public required string ConnectionString { get; init; }` | | `is` pattern + extraction | Null/type/property check | `if (result is { IsSuccess: true, Value: var order }) { ... }` |
Access the auto-generated backing field in property accessors without declaring it manually.
// GOOD — field keyword for validation in auto-property
public class Product
{
public string Name
{
get => field;
set => field = value?.Trim() ?? throw new ArgumentNullException(nameof(value));
}
public decimal Price
{
get => field;
set => field = value >= 0 ? value : throw new ArgumentOutOfRangeException(nameof(value));
}
}public class ProductCatalog
{
// Lazy-load on first access — no manual Lazy<T> or backing field
public IReadOnlyList<Product> Products
{
get => field ??= LoadProducts();
}
private static List<Product> LoadProducts() => /* expensive load */;
}// INotifyPropertyChanged without manual backing fields
public class OrderViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public string CustomerName
{
get => field;
set
{
if (field == value) return;
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CustomerName)));
}
} = "";
public decimal Total
{
get => field;
set
{
if (field == value) return;
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Total)));
}
}
}C# 14 adds `extension` blocks inside static classes. Unlike classic extension methods, they support extension **properties** and **static** extension members — the receiver is declared once for the whole block.
// GOOD — extension block (shipped C# 14 syntax)
public static class OrderExtensions
{
extension(Order order)
{
public decimal TotalWithTax => order.Total * 1.2m;
public bool IsHighValue => order.Total > 1000m;
public string ToSummary() =>
$"Order #{order.Id}: {order.Total:C} ({order.Items.Count} items)";
}
// Static extension members use the type (no receiver instance)
extension(Order)
{
public static Order Empty => Order.Create("none", [], DateTimeOffset.MinValue);
}
}
// Callers see them as if declared on Order
if (order.IsHighValue) { /* ... */ }Classic `this`-parameter extension methods still work and coexist — use extension blocks when you need properties or several members on the same receiver.
// BAD — manual backing field when field keyword works
private string _name;
public string Name
{
get => _name;
set => _name = value ?? throw new ArgumentNullException();
}
// BAD — old-style collection initialization
var list = new List<int>() { 1, 2, 3 };
// BAD — Tuple instead of record for domain types
(string Name, decimal Price) product = ("Widget", 9.99m);
// GOOD — record
public record Product(string Name, decimal Price);// BAD — deeply nested pattern that's hard to read
if (order is { Customer: { Address: { Country: { Code: "US" } } } })
// GOOD — extract to a clear method or use sequential checks
if (order.Customer.Address.Country.Code == "US")API versioning strategies for ASP.NET Core. Covers Asp.Versioning library, URL segment,…
Architecture conformance check: verifies an existing codebase against its declared…
Architecture selection advisor for .NET applications. Asks structured questions about domain…
.NET Aspire for cloud-native orchestration. Covers AppHost configuration, service defaults,…
Authentication and authorization for ASP.NET Core. Covers JWT bearer tokens, OpenID Connect,…
Autonomous iteration loops for .NET: drive a broken build or failing test suite to green with…