Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/miles990/claude-software-skills --skill csharp-dotnet명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Enterprise-grade repository analysis with arc42/C4 architecture documentation, technical debt quantification, security assessment, and multi-stakeholder reporting
Claude Code Plugin 開發、發布、安裝、更新與 Marketplace 管理完整指南
Flame Engine core fundamentals - components, input, collision, camera, animation, scenes
SOC 직업 분류 기준
SKILL.md 표시 중
| name | csharp-dotnet |
| description | C# and .NET development patterns |
| domain | programming-languages |
| version | 1.0.0 |
| tags | ["csharp","dotnet","async","linq","aspnet"] |
| triggers | {"keywords":{"primary":["csharp","c#","dotnet",".net","aspnet","asp.net","nuget"],"secondary":["linq","async","entity framework","ef core","blazor","maui"]},"context_boost":["enterprise","windows","azure","backend","game","unity"],"context_penalty":["python","javascript","java","go"],"priority":"high"} |
Modern C# and .NET development patterns including async programming, LINQ, and ASP.NET Core.
// Record type (immutable by default)
public record User(
string Id,
string Email,
string Name,
DateTime CreatedAt
);
// With-expressions for immutable updates
var user = new User("1", "test@example.com", "Test User", DateTime.UtcNow);
var updated = user with { Name = "Updated Name" };
// Record with validation
public record ValidatedUser
{
public required string Id { get; init; }
public required string Email { get; init; }
public required string Name { get; init; }
public ValidatedUser()
{
// Validation in constructor
}
// Custom validation
public static ValidatedUser Create(string email, string name)
{
if (!email.Contains("@"))
throw new ArgumentException("Invalid email");
return new ValidatedUser
{
Id = Guid.NewGuid().ToString(),
Email = email,
Name = name
};
}
}
// Init-only properties
public class Config
{
public required string ConnectionString { get; init; }
public int Timeout { get; init; } = 30;
}
// Type patterns
public string Describe(object obj) => obj switch
{
string s => $"String of length {s.Length}",
int i when i > 0 => $"Positive integer: {i}",
int i => $"Non-positive integer: {i}",
IEnumerable<int> list => $"Integer list with {list.Count()} items",
null => "Null value",
_ => "Unknown type"
};
// Property patterns
public decimal CalculateDiscount(Order order) => order switch
{
{ Total: > 1000, Customer.IsPremium: true } => order.Total * 0.2m,
{ Total: > 1000 } => order.Total * 0.1m,
{ Customer.IsPremium: true } => order.Total * 0.05m,
_ => 0
};
// List patterns (C# 11)
public string DescribeList(int[] numbers) => numbers switch
{
[] => "Empty",
[var single] => $"Single element: {single}",
[] => ,
[] => ,
};
;
=> point
{
(, ) => ,
(> , > ) => ,
(< , > ) => ,
(< , < ) => ,
(> , < ) => ,
(_, ) (, _) =>
};
#nullable enable
public class UserService
{
// Non-nullable (compiler ensures not null)
public User GetUser(string id)
{
return _repository.Find(id)
?? throw new NotFoundException($"User {id} not found");
}
// Nullable return
public User? FindUser(string id)
{
return _repository.Find(id);
}
// Null handling
public string GetDisplayName(User? user)
{
// Null-conditional
var name = user?.Name;
// Null-coalescing
return user?.Name ?? "Anonymous";
// Null-coalescing assignment
// user ??= CreateDefaultUser();
}
// Null-forgiving operator (use sparingly)
public void ProcessUser(User? user)
{
// When you know it's not null but compiler doesn't
var name = user!.Name;
}
}
// Required members (C# 11)
public class RequiredUser
{
public required string Id { get; ; }
Email { ; ; }
? Nickname { ; ; }
}
using System.Threading.Tasks;
using System.Threading;
public class AsyncService
{
// Basic async method
public async Task<User> GetUserAsync(string id, CancellationToken ct = default)
{
var response = await _httpClient.GetAsync($"/users/{id}", ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<User>(ct)
?? throw new InvalidOperationException("Null response");
}
// Parallel execution
public async Task<IReadOnlyList<User>> GetUsersAsync(IEnumerable<string> ids)
{
var tasks = ids.Select(id => GetUserAsync(id));
return await Task.WhenAll(tasks);
}
// With error handling
public async Task<Result<User>> SafeGetUserAsync(string id)
{
try
{
var user = await GetUserAsync(id);
return Result<User>.Success(user);
}
catch (Exception ex)
{
return Result<User>.Failure(ex.Message);
}
}
// ValueTask for potentially synchronous operations
public ValueTask<User?> ()
{
(_cache.TryGetValue(id, user))
{
ValueTask.FromResult<User?>(user);
}
ValueTask<User?>(FetchAndCacheUserAsync(id));
}
{
page = ;
()
{
users = FetchPageAsync(page, ct);
(!users.Any()) ;
( user users)
{
user;
}
page++;
}
}
{
(
{
ProcessUserAsync(user);
}
}
}
{
Channel<Message> _channel = Channel.CreateBounded<Message>();
{
_channel.Writer.WriteAsync(message);
}
{
( message _channel.Reader.ReadAllAsync(ct))
{
ProcessMessageAsync(message);
}
}
}
using System.Linq;
public class LinqExamples
{
// Query syntax
public IEnumerable<User> GetActiveUsers(IEnumerable<User> users)
{
return from user in users
where user.IsActive
orderby user.Name
select user;
}
// Method syntax (more common)
public IEnumerable<string> GetActiveUserEmails(IEnumerable<User> users)
{
return users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.Select(u => u.Email);
}
// Grouping
public IDictionary<string, List<User>> GroupByDomain(IEnumerable<User> users)
{
return users
.GroupBy(u => u.Email.Split('@')[1])
.ToDictionary(g => g.Key, g => g.ToList());
}
// Join
public IEnumerable<OrderWithUser> JoinOrdersWithUsers(
IEnumerable<Order> orders,
IEnumerable<User> users)
{
return orders.Join(
users,
order => order.UserId,
user => user.Id,
(order, user) => new OrderWithUser(order, user));
}
// Aggregate
public OrderStats GetOrderStats(IEnumerable<Order> orders)
{
return new OrderStats(
Count: orders.Count(),
Total: orders.Sum(o => o.Amount),
Average: orders.Average(o => o.Amount),
Max: orders.Max(o => o.Amount)
);
}
{
orders.SelectMany(o => o.Items);
}
{
orders
.GroupBy(o => o.UserId)
.Select(g =>
{
UserId = g.Key,
TotalSpent = g.Sum(o => o.Amount),
OrderCount = g.Count()
})
.OrderByDescending(x => x.TotalSpent)
.Take()
.Join(users, x => x.UserId, u => u.Id, (x, u) => UserSummary(
u.Name,
x.TotalSpent,
x.OrderCount
));
}
}
using Microsoft.Extensions.DependencyInjection;
// Service registration
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
// Transient - new instance each time
services.AddTransient<IEmailService, EmailService>();
// Scoped - one per request
services.AddScoped<IUserRepository, UserRepository>();
// Singleton - one instance for app lifetime
services.AddSingleton<ICacheService, RedisCacheService>();
// Factory registration
services.AddScoped<IDbConnection>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
return new SqlConnection(config.GetConnectionString("Default"));
});
// Options pattern
services.Configure<EmailOptions>(configuration.GetSection("Email"));
return services;
}
}
// Constructor injection
public class UserService
{
private readonly IUserRepository _repository;
private readonly IEmailService _emailService;
private readonly ILogger<UserService> _logger;
public UserService(
IUserRepository repository,
IEmailService emailService,
ILogger<UserService> logger)
{
_repository = repository;
_emailService = emailService;
_logger = logger;
}
Task<User> ()
{
_logger.LogInformation(, request.Email);
user = User(request.Email, request.Name);
_repository.AddAsync(user);
_emailService.SendWelcomeEmailAsync(user);
user;
}
}
{
{
logger.LogInformation(, request.Email);
!;
}
}
// Generic repository
public interface IRepository<T> where T : class, IEntity
{
Task<T?> FindAsync(string id);
Task<IReadOnlyList<T>> FindAllAsync();
Task AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(string id);
}
public class Repository<T> : IRepository<T> where T : class, IEntity
{
private readonly DbContext _context;
public Repository(DbContext context)
{
_context = context;
}
public async Task<T?> FindAsync(string id)
{
return await _context.Set<T>().FindAsync(id);
}
public async Task<IReadOnlyList<T>> FindAllAsync()
{
return await _context.Set<T>().ToListAsync();
}
{
_context.Set<T>().AddAsync(entity);
_context.SaveChangesAsync();
}
}
<, >
: , <>, ()
:
{
}
< >
{
;
}
< >
{
;
}
// Result type pattern
public readonly struct Result<T>
{
public T? Value { get; }
public string? Error { get; }
public bool IsSuccess => Error is null;
private Result(T value)
{
Value = value;
Error = null;
}
private Result(string error)
{
Value = default;
Error = error;
}
public static Result<T> Success(T value) => new(value);
public static Result<T> Failure(string error) => new(error);
public TResult Match<TResult>(
Func<T, TResult> success,
Func<string, TResult> failure) =>
IsSuccess ? success(Value!) : failure(Error!);
}
// Custom exceptions
public class DomainException : Exception
{
public Code { ; }
{
Code = code;
}
}
:
{
IDictionary<, []> Errors { ; }
{
Errors = errors;
}
}
{
RequestDelegate _next;
ILogger<ExceptionMiddleware> _logger;
{
{
_next(context);
}
(ValidationException ex)
{
context.Response.StatusCode = ;
context.Response.WriteAsJsonAsync( { ex.Code, ex.Errors });
}
(NotFoundException ex)
{
context.Response.StatusCode = ;
context.Response.WriteAsJsonAsync( { ex.Code, ex.Message });
}
(Exception ex)
{
_logger.LogError(ex, );
context.Response.StatusCode = ;
context.Response.WriteAsJsonAsync( { Code = });
}
}
}