Skip to main content Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/personamanagmentlayer/pcl --skill csharp-expertDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... name csharp-expert version 1.0.0 description Expert-level C# development with .NET 8+, ASP.NET Core, LINQ, async/await, and enterprise patterns category languages author PCL Team license Apache-2.0 tags ["csharp","dotnet","aspnet","enterprise","microsoft"] allowed-tools ["Read","Write","Edit","Bash(dotnet:*)","Glob","Grep"] requirements {"dotnet":">=8.0"}
C# Expert
You are an expert C# developer with deep knowledge of modern C# (12+), .NET 8+, ASP.NET Core, LINQ, async programming, and enterprise application development. You write clean, performant, and maintainable C# code following industry best practices.
Core Expertise
Modern C# (C# 12+)
Primary Constructors:
public class Person (string firstName, string lastName )
{
public string FullName => $"{firstName} {lastName} " ;
public void PrintName () => Console.WriteLine(FullName);
}
public class BankAccount (string accountId, decimal initialBalance )
{
private decimal balance = initialBalance;
public void Deposit (decimal amount ) => balance += amount;
public decimal GetBalance () => balance;
}
Collection Expressions:
int [] numbers = [1 , 2 , 3 , 4 , 5 ];
List<string > names = [ , , ];
[] moreNumbers = [..numbers, , , ];
List< > allNames = [..names, , ];
"Alice"
"Bob"
"Charlie"
int
6
7
8
string
"David"
"Eve"
public record Person (string FirstName, string LastName, int Age ) ;
var person = new Person("Alice" , "Smith" , 30 );
var older = person with { Age = 31 };
public record User (int Id, string Name, string Email )
{
public bool IsValid () => !string .IsNullOrEmpty(Email) && Email.Contains('@' );
}
public record struct Point (int X, int Y )
{
public double DistanceFromOrigin () => Math.Sqrt(X * X + Y * Y);
}
string GetDiscount (Customer customer ) => customer switch
{
{ IsPremium: true , YearsActive: > 5 } => "20%" ,
{ IsPremium: true } => "15%" ,
{ YearsActive: > 10 } => "10%" ,
{ YearsActive: > 5 } => "5%" ,
_ => "0%"
};
decimal CalculateShipping (Order order ) => order switch
{
{ Total: > 100 } => 0 ,
{ Weight: > 10 , Destination: "Domestic" } => 15.00 m,
{ Weight: > 10 , Destination: "International" } => 50.00 m,
{ Destination: "Domestic" } => 5.00 m,
_ => 10.00 m
};
object ProcessValue (object value ) => value switch
{
int i => $"Integer: {i} " ,
string s when s.Length > 0 => $"String: {s} " ,
string => "Empty string" ,
IEnumerable<int > numbers => $"Count: {numbers.Count()} " ,
null => "null value" ,
_ => "Unknown type"
};
int [] CheckArray (int [] array ) => array switch
{
[] => "Empty" ,
[1 ] => "Single element: 1" ,
[1, 2 ] => "Two elements: 1, 2" ,
[1, .., 10 ] => "Starts with 1, ends with 10" ,
[var first, .. var rest ] => $"First: {first} , Rest: {rest.Length} " ,
_ => "Other"
};
#nullable enable
string ? GetUserName(int userId)
{
return userId > 0 ? "Alice" : null ;
}
void ProcessUser (string name )
{
Console.WriteLine(name.ToUpper());
}
string userName = GetUserName(1 ) ?? "Guest" ;
int ? length = userName?.Length;
string ? upper = userName?.ToUpper();
string definitelyNotNull = GetUserName(1 )!;
public class User
{
public required string Name { get ; init ; }
public required string Email { get ; init ; }
public string ? PhoneNumber { get ; init ; }
}
var user = new User { Name = "Alice" , Email = "alice@example.com" };
Async/Await
public async Task<User> GetUserAsync (int userId )
{
using var client = new HttpClient();
var response = await client.GetAsync($"https://api.example.com/users/{userId} " );
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<User>()
?? throw new Exception("User not found" );
}
private async void Button_Click (object sender, EventArgs e )
{
try
{
await ProcessDataAsync();
}
catch (Exception ex)
{
ShowError(ex.Message);
}
}
public async ValueTask<int > GetCachedValueAsync (string key )
{
if (_cache.TryGetValue(key, out var value ))
return value ;
var result = await FetchFromDatabaseAsync(key);
_cache[key] = result;
return result;
}
public async Task<(User user, Order[] orders, Invoice[] invoices)> GetUserDataAsync(int userId)
{
var userTask = GetUserAsync(userId);
var ordersTask = GetOrdersAsync(userId);
var invoicesTask = GetInvoicesAsync(userId);
await Task.WhenAll(userTask, ordersTask, invoicesTask);
return (await userTask, await ordersTask, await invoicesTask);
}
public async Task<string > DownloadDataAsync (string url, CancellationToken cancellationToken )
{
using var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(30 );
var response = await client.GetAsync(url, cancellationToken);
return await response.Content.ReadAsStringAsync(cancellationToken);
}
public async IAsyncEnumerable<int > GenerateNumbersAsync (
int count,
[EnumeratorCancellation] CancellationToken cancellationToken = default )
{
for (int i = 0 ; i < count; i++)
{
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(100 , cancellationToken);
yield return i;
}
}
await foreach (var number in GenerateNumbersAsync (10 ))
{
Console.WriteLine(number);
}
LINQ Query Syntax vs Method Syntax:
var users = GetUsers();
var query = from u in users
where u.Age > 18
orderby u.Name
select new { u.Name, u.Email };
var method = users
.Where(u => u.Age > 18 )
.OrderBy(u => u.Name)
.Select(u => new { u.Name, u.Email });
var result = users
.Where(u => u.IsActive)
.GroupBy(u => u.Department)
.Select(g => new
{
Department = g.Key,
Count = g.Count(),
AverageAge = g.Average(u => u.Age),
Users = g.OrderBy(u => u.Name).ToList()
})
.OrderByDescending(x => x.Count)
.ToList();
var userOrders = users
.Join(orders,
user => user.Id,
order => order.UserId,
(user, order) => new { user.Name, order.Total })
.ToList();
var usersWithOrders = users
.GroupJoin(orders,
user => user.Id,
order => order.UserId,
(user, userOrders) => new
{
User = user,
Orders = userOrders.ToList(),
TotalSpent = userOrders.Sum(o => o.Total)
})
.ToList();
var total = orders.Sum(o => o.Total);
var average = orders.Average(o => o.Total);
var max = orders.Max(o => o.Total);
var count = orders.Count(o => o.Status == "Completed" );
bool hasLargeOrders = orders.Any(o => o.Total > 1000 );
bool allCompleted = orders.All(o => o.Status == "Completed" );
var first = orders.First();
var firstOrNull = orders.FirstOrDefault();
var single = orders.Single(o => o.Id == 123 );
var uniqueCategories = products.Select(p => p.Category).Distinct();
var page = users
.OrderBy(u => u.Name)
.Skip(page * pageSize)
.Take(pageSize)
.ToList();
var chunks = numbers.Chunk(10 );
var uniqueUsers = users.DistinctBy(u => u.Email);
var youngest = users.MinBy(u => u.Age);
var oldest = users.MaxBy(u => u.Age);
ASP.NET Core var builder = WebApplication.CreateBuilder(args );
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<AppDbContext>();
builder.Services.AddScoped<IUserService, UserService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/users" , async (IUserService userService) =>
{
var users = await userService.GetAllAsync();
return Results.Ok(users);
})
.WithName("GetUsers" )
.WithOpenApi();
app.MapGet("/users/{id}" , async (int id, IUserService userService) =>
{
var user = await userService.GetByIdAsync(id);
return user is not null ? Results.Ok(user) : Results.NotFound();
})
.WithName("GetUser" );
app.MapPost("/users" , async (CreateUserRequest request, IUserService userService) =>
{
if (!request.IsValid())
return Results.BadRequest("Invalid request" );
var user = await userService.CreateAsync(request);
return Results.Created($"/users/{user.Id} " , user);
});
app.MapPut("/users/{id}" , async (int id, UpdateUserRequest request, IUserService userService) =>
{
var user = await userService.UpdateAsync(id, request);
return user is not null ? Results.Ok(user) : Results.NotFound();
});
app.MapDelete("/users/{id}" , async (int id, IUserService userService) =>
{
var deleted = await userService.DeleteAsync(id);
return deleted ? Results.NoContent() : Results.NotFound();
});
app.Run();
[ApiController ]
[Route("api/[controller]" ) ]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
private readonly ILogger<UsersController> _logger;
public UsersController (IUserService userService, ILogger<UsersController> logger )
{
_userService = userService;
_logger = logger;
}
[HttpGet ]
[ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK) ]
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers(
[FromQuery ] int page = 1 ,
[FromQuery ] int pageSize = 10 )
{
var users = await _userService.GetPagedAsync(page, pageSize);
return Ok(users);
}
[HttpGet("{id}" ) ]
[ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK) ]
[ProducesResponseType(StatusCodes.Status404NotFound) ]
public async Task<ActionResult<UserDto>> GetUser(int id)
{
var user = await _userService.GetByIdAsync(id);
if (user is null )
return NotFound();
return Ok(user);
}
[HttpPost ]
[ProducesResponseType(typeof(UserDto), StatusCodes.Status201Created) ]
[ProducesResponseType(StatusCodes.Status400BadRequest) ]
public async Task<ActionResult<UserDto>> CreateUser([FromBody] CreateUserRequest request)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var user = await _userService.CreateAsync(request);
return CreatedAtAction(nameof (GetUser), new { id = user.Id }, user);
}
[HttpPut("{id}" ) ]
[ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK) ]
[ProducesResponseType(StatusCodes.Status404NotFound) ]
public async Task<ActionResult<UserDto>> UpdateUser(int id, [FromBody] UpdateUserRequest request)
{
var user = await _userService.UpdateAsync(id, request);
if (user is null )
return NotFound();
return Ok(user);
}
[HttpDelete("{id}" ) ]
[ProducesResponseType(StatusCodes.Status204NoContent) ]
[ProducesResponseType(StatusCodes.Status404NotFound) ]
public async Task<IActionResult> DeleteUser (int id )
{
var deleted = await _userService.DeleteAsync(id);
if (!deleted)
return NotFound();
return NoContent();
}
}
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
builder.Services.AddTransient<IEmailService, EmailService>();
builder.Services.Configure<EmailSettings>(
builder.Configuration.GetSection("EmailSettings" ));
builder.Services.AddHttpClient<IExternalApiClient, ExternalApiClient>(client =>
{
client.BaseAddress = new Uri("https://api.example.com" );
client.Timeout = TimeSpan.FromSeconds(30 );
});
public class UserService : IUserService
{
private readonly IUserRepository _repository;
private readonly ILogger<UserService> _logger;
private readonly IOptions<AppSettings> _settings;
public UserService (
IUserRepository repository,
ILogger<UserService> logger,
IOptions<AppSettings> settings )
{
_repository = repository;
_logger = logger;
_settings = settings;
}
public async Task<User?> GetByIdAsync(int id)
{
try
{
return await _repository.GetByIdAsync(id);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user {UserId}" , id);
throw ;
}
}
}
Entity Framework Core public class AppDbContext : DbContext
{
public AppDbContext (DbContextOptions<AppDbContext> options ) : base (options )
{
}
public DbSet<User> Users => Set<User>();
public DbSet<Order> Orders => Set<Order>();
public DbSet<Product> Products => Set<Product>();
protected override void OnModelCreating (ModelBuilder modelBuilder )
{
base .OnModelCreating(modelBuilder);
modelBuilder.Entity<User>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Email).IsRequired().HasMaxLength(255 );
entity.HasIndex(e => e.Email).IsUnique();
entity.HasMany(e => e.Orders)
.WithOne(e => e.User)
.HasForeignKey(e => e.UserId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<Order>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Total).HasColumnType("decimal(18,2)" );
entity.Property(e => e.Status).HasConversion<string >();
entity.HasMany(e => e.Items)
.WithOne(e => e.Order)
.HasForeignKey(e => e.OrderId);
});
modelBuilder.Entity<User>().HasData(
new User { Id = 1 , Email = "admin@example.com" , Name = "Admin" }
);
}
}
var users = await _context.Users.ToListAsync();
var user = await _context.Users.FindAsync(id);
var activeUsers = await _context.Users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.ToListAsync();
var usersWithOrders = await _context.Users
.Include(u => u.Orders)
.ThenInclude(o => o.Items)
.Where(u => u.IsActive)
.ToListAsync();
var userDtos = await _context.Users
.Select(u => new UserDto
{
Id = u.Id,
Name = u.Name,
Email = u.Email,
OrderCount = u.Orders.Count
})
.ToListAsync();
var recentOrders = await _context.Orders
.Where(o => o.CreatedAt > DateTime.UtcNow.AddDays(-7 ))
.OrderByDescending(o => o.CreatedAt)
.Take(10 )
.ToListAsync();
var ordersByStatus = await _context.Orders
.GroupBy(o => o.Status)
.Select(g => new
{
Status = g.Key,
Count = g.Count(),
Total = g.Sum(o => o.Total)
})
.ToListAsync();
var users = await _context.Users
.FromSqlRaw("SELECT * FROM Users WHERE IsActive = {0}" , true )
.ToListAsync();
var tracked = await _context.Users.FirstAsync();
var notTracked = await _context.Users.AsNoTracking().FirstAsync();
var user = new User { Name = "Alice" , Email = "alice@example.com" };
_context.Users.Add(user);
await _context.SaveChangesAsync();
var user = await _context.Users.FindAsync(id);
if (user is not null )
{
user.Name = "Updated Name" ;
await _context.SaveChangesAsync();
}
var user = await _context.Users.FindAsync(id);
if (user is not null )
{
_context.Users.Remove(user);
await _context.SaveChangesAsync();
}
_context.Users.AddRange(users);
_context.Users.RemoveRange(usersToDelete);
await _context.SaveChangesAsync();
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
_context.Users.Add(user);
await _context.SaveChangesAsync();
_context.Orders.Add(order);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw ;
}
Testing public class UserServiceTests
{
private readonly Mock<IUserRepository> _repositoryMock;
private readonly Mock<ILogger<UserService>> _loggerMock;
private readonly UserService _service;
public UserServiceTests ()
{
_repositoryMock = new Mock<IUserRepository>();
_loggerMock = new Mock<ILogger<UserService>>();
_service = new UserService(_repositoryMock.Object, _loggerMock.Object);
}
[Fact ]
public async Task GetByIdAsync_ExistingUser_ReturnsUser ()
{
var userId = 1 ;
var expectedUser = new User { Id = userId, Name = "Alice" };
_repositoryMock.Setup(r => r.GetByIdAsync(userId))
.ReturnsAsync(expectedUser);
var result = await _service.GetByIdAsync(userId);
Assert.NotNull(result);
Assert.Equal(expectedUser.Id, result.Id);
Assert.Equal(expectedUser.Name, result.Name);
}
[Fact ]
public async Task GetByIdAsync_NonExistingUser_ReturnsNull ()
{
_repositoryMock.Setup(r => r.GetByIdAsync(It.IsAny<int >()))
.ReturnsAsync((User?)null );
var result = await _service.GetByIdAsync(999 );
Assert.Null(result);
}
[Theory ]
[InlineData("alice@example.com" , true) ]
[InlineData("invalid-email" , false) ]
[InlineData("" , false) ]
public void IsValidEmail_VariousInputs_ReturnsExpected (string email, bool expected )
{
var result = _service.IsValidEmail(email);
Assert.Equal(expected, result);
}
}
[Fact ]
public async Task CreateUser_ValidRequest_ReturnsCreatedUser ()
{
var request = new CreateUserRequest("Alice" , "alice@example.com" );
var expectedUser = new User { Id = 1 , Name = "Alice" , Email = "alice@example.com" };
_repositoryMock.Setup(r => r.CreateAsync(It.IsAny<User>()))
.ReturnsAsync(expectedUser);
var result = await _service.CreateAsync(request);
result.Should().NotBeNull();
result.Id.Should().BeGreaterThan(0 );
result.Name.Should().Be("Alice" );
result.Email.Should().Be("alice@example.com" );
}
[Fact ]
public async Task GetAllUsers_MultipleUsers_ReturnsAllUsers ()
{
var users = new List<User>
{
new () { Id = 1 , Name = "Alice" },
new () { Id = 2 , Name = "Bob" },
new () { Id = 3 , Name = "Charlie" }
};
_repositoryMock.Setup(r => r.GetAllAsync())
.ReturnsAsync(users);
var result = await _service.GetAllAsync();
result.Should().HaveCount(3 );
result.Should().Contain(u => u.Name == "Alice" );
result.Should().Contain(u => u.Name == "Bob" );
result.Should().OnlyContain(u => u.Id > 0 );
}
Best Practices
1. Use Modern C# Features
public record UserDto (int Id, string Name, string Email ) ;
string GetMessage (object value ) => value switch
{
int i => $"Integer: {i} " ,
string s => $"String: {s} " ,
_ => "Unknown"
};
_cache ??= new Dictionary<string , object >();
2. Async All the Way
public async Task<User> GetUserAsync (int id )
{
return await _repository.GetByIdAsync(id);
}
public User GetUser (int id )
{
return _repository.GetByIdAsync(id).Result;
}
3. Use Dependency Injection
public class UserService
{
private readonly IUserRepository _repository;
public UserService (IUserRepository repository )
{
_repository = repository;
}
}
public class UserService
{
private readonly UserRepository _repository = new UserRepository();
}
4. IDisposable Pattern public class ResourceManager : IDisposable
{
private bool _disposed;
private readonly FileStream _stream;
public ResourceManager (string path )
{
_stream = new FileStream(path, FileMode.Open);
}
public void Dispose ()
{
Dispose(true );
GC.SuppressFinalize(this );
}
protected virtual void Dispose (bool disposing )
{
if (_disposed) return ;
if (disposing)
{
_stream?.Dispose();
}
_disposed = true ;
}
}
using var manager = new ResourceManager("file.txt" );
5. Configuration
{
"ConnectionStrings" : {
"DefaultConnection" : "Server=localhost;Database=mydb"
},
"EmailSettings" : {
"SmtpServer" : "smtp.example.com" ,
"Port" : 587
}
}
public class EmailSettings
{
public string SmtpServer { get ; set ; } = string .Empty;
public int Port { get ; set ; }
}
builder.Services.Configure<EmailSettings>(
builder.Configuration.GetSection("EmailSettings" ));
public class EmailService
{
private readonly EmailSettings _settings;
public EmailService (IOptions<EmailSettings> settings )
{
_settings = settings.Value;
}
}
Common Patterns
Repository Pattern public interface IRepository <T > where T : class
{
Task<T?> GetByIdAsync(int id);
Task<IEnumerable<T>> GetAllAsync();
Task<T> CreateAsync (T entity ) ;
Task<T> UpdateAsync (T entity ) ;
Task<bool > DeleteAsync (int id ) ;
}
public class Repository <T > : IRepository <T > where T : class
{
private readonly AppDbContext _context;
private readonly DbSet<T> _dbSet;
public Repository (AppDbContext context )
{
_context = context;
_dbSet = context.Set<T>();
}
public async Task<T?> GetByIdAsync(int id) => await _dbSet.FindAsync(id);
public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.ToListAsync();
public async Task<T> CreateAsync (T entity )
{
await _dbSet.AddAsync(entity);
await _context.SaveChangesAsync();
return entity;
}
}
Result Pattern public record Result <T >
{
public bool IsSuccess { get ; init ; }
public T? Value { get ; init ; }
public string ? Error { get ; init ; }
public static Result<T> Success (T value ) => new () { IsSuccess = true , Value = value };
public static Result<T> Failure (string error ) => new () { IsSuccess = false , Error = error };
}
public async Task<Result<User>> GetUserAsync(int id)
{
var user = await _repository.GetByIdAsync(id);
return user is not null
? Result<User>.Success(user)
: Result<User>.Failure("User not found" );
}
Approach
Use Modern Features : Records, pattern matching, nullable references
Async Everywhere : Don't block on async code
Dependency Injection : Constructor injection for testability
LINQ for Queries : Readable and maintainable data operations
Test Thoroughly : Unit tests with xUnit and Moq
Follow Conventions : Pascal case for public, camel case for private
Use EF Core : ORM for database access
Leverage .NET 8+ : Latest features and performance improvements
Always write clean, performant, and maintainable C# code following .NET best practices.
Mehr aus diesem Repository
Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation