From swe-workbench
C# and .NET idioms — .NET 8 LTS, csproj, C# NRT, records, value semantics, switch expressions, async/await, Task, ValueTask, CancellationToken, ConfigureAwait, dependency injection, IOptions<T>, LINQ, Span<T>, ArrayPool, hot path, allocation profiling, and performance. Auto-load when working with .cs files, .csproj, .sln, Directory.Build.props, or when the user mentions C#, dotnet, .NET 8, C# NRT, NRT, records, value semantics, switch expressions, Task, ValueTask, CancellationToken, ConfigureAwait, IOptions, LINQ, Span, or hot-path code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/swe-workbench:language-csharpThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Prefer SDK-style projects with explicit `TargetFramework` (`net8.0`) and shared defaults in `Directory.Build.props`.
TargetFramework (net8.0) and shared defaults in Directory.Build.props.<Nullable>enable</Nullable>.ImplicitUsings when the repository already does; avoid hand-maintaining noisy common imports.<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
T?, required, or a domain type.ArgumentNullException.ThrowIfNull(value) for guard clauses.! except when bridging a framework or serializer limitation; leave a short reason.public sealed class User
{
public required string Email { get; init; }
public string? DisplayName { get; init; }
}
record or readonly record struct for immutable value-like data.with: it is copy-with-change, not validation unless constructors enforce invariants.public sealed record Money(decimal Amount, string Currency);
var discounted = price with { Amount = price.Amount * 0.9m };
when) simple; complex decisions deserve named methods.return command switch
{
CreateUser(var email) when email.Contains('@') => Create(email),
DeleteUser(var id) => Delete(id),
_ => throw new InvalidOperationException("unsupported command")
};
async/await all the way. Avoid .Result, .Wait(), and blocking over async work.CancellationToken through I/O, database, and long-running operations.ConfigureAwait(false) when code does not need a captured context; in modern app code, follow the repo's convention.Task.WhenAll for independent work; avoid unobserved fire-and-forget tasks.public async Task<User> GetUserAsync(string id, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrWhiteSpace(id);
return await repository.FindAsync(id, cancellationToken).ConfigureAwait(false)
?? throw new UserNotFoundException(id);
}
IOptions<T>, IOptionsSnapshot<T>, or IOptionsMonitor<T> based on lifetime needs.public sealed record RetryOptions
{
public int MaxAttempts { get; init; } = 3;
}
public sealed class Worker(IOptions<RetryOptions> options)
{
private readonly RetryOptions retry = options.Value;
}
Any() over Count() > 0, and avoid repeated enumeration of deferred queries.Span<T>, pooling, and allocation-aware APIs only when profiling shows they matter.var activeEmails = users
.Where(user => user.IsActive)
.Select(user => user.Email)
.ToArray();
.Result, .Wait(), or GetAwaiter().GetResult().Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub lugassawan/swe-workbench --plugin swe-workbench