# Csharp Expert

> Expert-level C# development with .NET 8+, ASP.NET Core, LINQ, async/await, and enterprise patterns. Use when the user mentions C#, .NET, ASP.NET, enterprise, or Microsoft platforms, or when the task involves Modern C#, Async/Await, LINQ, or ASP.NET Core.

- Skill: `personamanagmentlayer/csharp-expert` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add personamanagmentlayer/csharp-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/personamanagmentlayer/csharp-expert/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- License: Apache-2.0
- Author: personamanagmentlayer (https://skillmd.com/u/personamanagmentlayer)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/personamanagmentlayer/csharp-expert

---


# 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.

## Best Practices

### 1. Use Modern C# Features

```csharp
// Records for DTOs
public record UserDto(int Id, string Name, string Email);

// Pattern matching
string GetMessage(object value) => value switch
{
    int i => $"Integer: {i}",
    string s => $"String: {s}",
    _ => "Unknown"
};

// Null-coalescing assignment
_cache ??= new Dictionary<string, object>();
```

### 2. Async All the Way

```csharp
// Good - async all the way
public async Task<User> GetUserAsync(int id)
{
    return await _repository.GetByIdAsync(id);
}

// Bad - blocking on async
public User GetUser(int id)
{
    return _repository.GetByIdAsync(id).Result; // Deadlock risk!
}
```

### 3. Use Dependency Injection

```csharp
// Good - constructor injection
public class UserService
{
    private readonly IUserRepository _repository;

    public UserService(IUserRepository repository)
    {
        _repository = repository;
    }
}

// Bad - new keyword
public class UserService
{
    private readonly UserRepository _repository = new UserRepository();
}
```

### 4. IDisposable Pattern

```csharp
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;
    }
}

// Usage
using var manager = new ResourceManager("file.txt");
```

### 5. Configuration

```csharp
// appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=mydb"
  },
  "EmailSettings": {
    "SmtpServer": "smtp.example.com",
    "Port": 587
  }
}

// Strongly-typed configuration
public class EmailSettings
{
    public string SmtpServer { get; set; } = string.Empty;
    public int Port { get; set; }
}

// Register
builder.Services.Configure<EmailSettings>(
    builder.Configuration.GetSection("EmailSettings"));

// Use
public class EmailService
{
    private readonly EmailSettings _settings;

    public EmailService(IOptions<EmailSettings> settings)
    {
        _settings = settings.Value;
    }
}
```

## Common Patterns

### Repository Pattern

```csharp
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

```csharp
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 };
}

// Usage
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

When writing C# code:

1. **Use Modern Features**: Records, pattern matching, nullable references
2. **Async Everywhere**: Don't block on async code
3. **Dependency Injection**: Constructor injection for testability
4. **LINQ for Queries**: Readable and maintainable data operations
5. **Test Thoroughly**: Unit tests with xUnit and Moq
6. **Follow Conventions**: Pascal case for public, camel case for private
7. **Use EF Core**: ORM for database access
8. **Leverage .NET 8+**: Latest features and performance improvements

Always write clean, performant, and maintainable C# code following .NET best practices.

## Reference Documentation

Detailed material lives alongside this skill and is read on demand:

- [Core Expertise](references/CORE_CONCEPTS.md) — Modern C# (C# 12+), Async/Await, LINQ, ASP.NET Core, Entity Framework Core, Testing

