Help us improve
Share bugs, ideas, or general feedback.
From csharp
C# 核心开发规范:C# 12/.NET 8 语言标准、nullable reference types、pattern matching、primary constructors、collection expressions、Roslyn analyzers 静态分析。新建或审查 C# 项目时加载,是所有 C# 技能的基础依赖。
npx claudepluginhub lazygophers/ccplugin --plugin csharpHow this skill is triggered — by the user, by Claude, or both
Slash command
/csharp:coresonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **csharp:dev** - 开发阶段使用
Write modern, high-performance C# code using records, pattern matching, value objects, async/await, Span<T>/Memory<T>, and best-practice API design patterns. Emphasizes functional-style programming with C# 12+ features. Use when writing new C# code or refactoring existing code, designing public APIs for libraries or services, optimizing performance-critical code paths, or building async/await-heavy applications.
Guides use of modern C# language features for .NET 10 and C# 14, including primary constructors, collection expressions, records, pattern matching, spans, and the field keyword.
Applies opinionated conventions for C# 12 and .NET 8+ code: ASP.NET Core minimal/controller APIs, Blazor, EF Core, async patterns, CQRS with MediatR.
Share bugs, ideas, or general feedback.
<Nullable>enable</Nullable>| 特性 | 说明 | 示例 |
|---|---|---|
| Primary constructors | 类/结构体参数化构造 | public class Service(IRepo repo) |
| Collection expressions | 统一集合初始化 | int[] nums = [1, 2, 3]; |
| Inline arrays | 固定大小栈数组 | [InlineArray(4)] struct Buffer { int _e; } |
| Alias any type | using 别名任何类型 | using Point = (int X, int Y); |
| Lambda defaults | Lambda 默认参数 | var add = (int x, int y = 1) => x + y; |
| Interceptors | 编译时方法替换 | source generator 场景 |
| 特性 | 说明 | 示例 |
|---|---|---|
| params collections | params 支持任何集合 | void Log(params ReadOnlySpan<string> msgs) |
| Lock object | 新的 Lock 类型 | private readonly Lock _lock = new(); |
| Extension types | 扩展类型(预览) | 替代传统 extension methods |
<Nullable>enable</Nullable>// ✅ C# 12 primary constructor(DI 场景)
public class UserService(IUserRepository repo, ILogger<UserService> logger)
{
public async Task<User?> GetAsync(int id, CancellationToken ct = default)
{
logger.LogDebug("Getting user {UserId}", id);
return await repo.FindAsync(id, ct);
}
}
// ✅ record 类型(DTO/值对象)
public record CreateUserRequest(string Name, string Email, int Age);
public record UserResponse(int Id, string Name, string Email);
// ❌ 传统冗余构造函数
public class UserService
{
private readonly IUserRepository _repo;
private readonly ILogger<UserService> _logger;
public UserService(IUserRepository repo, ILogger<UserService> logger)
{
_repo = repo;
_logger = logger;
}
}
// ✅ C# 12 collection expressions
int[] numbers = [1, 2, 3, 4, 5];
List<string> names = ["Alice", "Bob", "Charlie"];
Span<int> span = [1, 2, 3];
ReadOnlySpan<char> vowels = ['a', 'e', 'i', 'o', 'u'];
// ✅ Spread 运算符
int[] first = [1, 2, 3];
int[] second = [4, 5, 6];
int[] all = [..first, ..second]; // [1, 2, 3, 4, 5, 6]
// ❌ 传统初始化
var numbers = new int[] { 1, 2, 3, 4, 5 };
var names = new List<string> { "Alice", "Bob", "Charlie" };
// 项目文件启用
// <Nullable>enable</Nullable>
public class UserService(IUserRepository repo)
{
// ✅ 明确可空性
public string Name { get; set; } = "";
public string? Email { get; set; }
// ✅ 空条件运算符链
public string GetDisplayEmail() => Email?.ToLower() ?? "N/A";
// ✅ null 合并赋值
public List<User> GetUsers(List<User>? input) => input ??= [];
// ✅ 模式匹配空检查
public string Describe(User? user) => user switch
{
{ Name: var name, Email: not null } => $"{name} ({user.Email})",
{ Name: var name } => name,
null => "Unknown"
};
}
// ✅ .NET 8 Keyed Services
builder.Services.AddKeyedScoped<ICache, RedisCache>("redis");
builder.Services.AddKeyedScoped<ICache, MemoryCache>("memory");
public class UserService([FromKeyedServices("redis")] ICache cache) { }
// ✅ IOptions 模式
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
public class EmailService(IOptions<SmtpSettings> options)
{
private readonly SmtpSettings _settings = options.Value;
}
<!-- .csproj 推荐配置 -->
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<!-- Roslyn analyzers -->
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.*" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.*" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.*" />
</ItemGroup>
# 格式化代码
dotnet format
# 运行 analyzers
dotnet build /p:TreatWarningsAsErrors=true
| AI 可能的理性化解释 | 实际应该检查的内容 |
|---|---|
| "传统构造函数可读性更好" | ✅ 简单 DI 类是否用 primary constructors? |
| "new List 已经够简洁" | ✅ 是否用 collection expressions? |
| "不启用 nullable 更方便" | ✅ 是否启用 <Nullable>enable</Nullable>? |
| "class 比 record 灵活" | ✅ DTO/值对象是否用 record? |
| "不需要 analyzers" | ✅ 是否配置 Roslyn + SonarAnalyzer? |
| "手动格式化就行" | ✅ 是否运行 dotnet format? |
[1, 2, 3]<Nullable>enable</Nullable>?.、??、??= 运算符!) 滥用dotnet format 格式化<TreatWarningsAsErrors>true</TreatWarningsAsErrors>