AI студия Владимира Ломтева
УСЛУГИПРОЕКТЫСТАТЬИБАЗА ЗНАНИЙМаркетплейсОбучениеПолезные сервисы

Оставьте заявку,
чтобы обсудить проект

Напишите ваш вопрос, не забудьте указать телефон. Мы перезвоним и все расскажем.

Контакты

Москва

Работаем по всей России
и миру (онлайн)

+7 (999) 760-24-41

Ежедневно с 9:00 до 21:00

v.lomtev@airassvet.ru

По вопросам сотрудничества

TelegramWhatsApp

Есть предложение?

Напишите нам в мессенджеры

© 2025 AI студия Владимира Ломтева

Политика конфиденциальностиСогласие на обработку ПДн|ИНН 623412173261
    Modern Csharp Coding Standards — Скилл для ИИ-агентов | AI Рассвет

    Modern Csharp Coding Standards

    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.

    Скиллы для разработки#GitHub#aaronontheweb/dotnet-skills#skills.sh
    Скачивания
    0
    В избранном
    0
    Комментарии
    0
    Просмотры
    1

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add aaronontheweb/dotnet-skills --skill modern-csharp-coding-standards
    Скачать ZIP
    Версия
    1.0.0+ac0deb2f531f
    Автор
    Владимир Ломтев
    Репозиторий
    aaronontheweb/dotnet-skills
    GitHub: aaronontheweb/dotnet-skills

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add aaronontheweb/dotnet-skills --skill modern-csharp-coding-standards
    Скачать ZIP
    Версия
    1.0.0+ac0deb2f531f
    Автор
    Владимир Ломтев
    Репозиторий
    aaronontheweb/dotnet-skills
    GitHub: aaronontheweb/dotnet-skills

    Как установить

    1. 1Скопируйте команду из блока установки.
    2. 2Запустите её в терминале из каталога проекта.

    Документация

    Modern C# Coding Standards

    When to Use This Skill

    Use this skill when:

    • Writing new C# code or refactoring existing code
    • Designing public APIs for libraries or services
    • Optimizing performance-critical code paths
    • Implementing domain models with strong typing
    • Building async/await-heavy applications
    • Working with binary data, buffers, or high-throughput scenarios

    Reference Files

    • value-objects-and-patterns.md: Full value object examples and pattern matching code
    • performance-and-api-design.md: Span/Memory examples and API design principles
    • composition-and-error-handling.md: Composition over inheritance, Result type, testing patterns
    • anti-patterns-and-reflection.md: Reflection avoidance and common anti-patterns

    Core Principles

    1. Immutability by Default - Use record types and init-only properties
    2. Type Safety - Leverage nullable reference types and value objects
    3. Modern Pattern Matching - Use switch expressions and patterns extensively
    4. Async Everywhere - Prefer async APIs with proper cancellation support
    5. Zero-Allocation Patterns - Use Span<T> and Memory<T> for performance-critical code
    6. API Design - Accept abstractions, return appropriately specific types
    7. Composition Over Inheritance - Avoid abstract base classes, prefer composition
    8. Value Objects as Structs - Use readonly record struct for value objects

    Language Patterns

    Records for Immutable Data (C# 9+)

    Use record types for DTOs, messages, events, and domain entities.

    // Simple immutable DTO
    public record CustomerDto(string Id, string Name, string Email);
    
    // Record with validation in constructor
    public record EmailAddress
    {
        public string Value { get; init; }
    
        public EmailAddress(string value)
        {
            if (string.IsNullOrWhiteSpace(value) || !value.Contains('@'))
                throw new ArgumentException("Invalid email address", nameof(value));
    
            Value = value;
        }
    }
    
    // Records with collections - use IReadOnlyList
    public record ShoppingCart(
        string CartId,
        string CustomerId,
        IReadOnlyList<CartItem> Items
    )
    {
        public decimal Total => Items.Sum(item => item.Price * item.Quantity);
    }
    

    When to use record class vs record struct:

    • record class (default): Reference types, use for entities, aggregates, DTOs with multiple properties
    • record struct: Value types, use for value objects (see next section)

    Value Objects as readonly record struct

    Value objects should always be readonly record struct for performance and value semantics. Use explicit conversions, never implicit operators.

    public readonly record struct OrderId(string Value)
    {
        public OrderId(string value) : this(
            !string.IsNullOrWhiteSpace(value)
                ? value
                : throw new ArgumentException("OrderId cannot be empty", nameof(value)))
        { }
        public override string ToString() => Value;
    }
    
    public readonly record struct Money(decimal Amount, string Currency);
    public readonly record struct CustomerId(Guid Value)
    {
        public static CustomerId New() => new(Guid.NewGuid());
    }
    

    See value-objects-and-patterns.md for complete examples including multi-value objects, factory patterns, and the no-implicit-conversion rule.

    Pattern Matching (C# 8-12)

    Use switch expressions, property patterns, relational patterns, and list patterns for cleaner code.

    public decimal CalculateDiscount(Order order) => order switch
    {
        { Total: > 1000m } => order.Total * 0.15m,
        { Total: > 500m } => order.Total * 0.10m,
        { Total: > 100m } => order.Total * 0.05m,
        _ => 0m
    };
    

    See value-objects-and-patterns.md for full pattern matching examples.


    Nullable Reference Types (C# 8+)

    Enable nullable reference types in your project and handle nulls explicitly.

    // In .csproj
    <PropertyGroup>
        <Nullable>enable</Nullable>
    </PropertyGroup>
    
    // Explicit nullability
    public string? FindUserName(string userId)
    {
        var user = _repository.Find(userId);
        return user?.Name;
    }
    
    // Pattern matching with null checks
    public decimal GetDiscount(Customer? customer) => customer switch
    {
        null => 0m,
        { IsVip: true } => 0.20m,
        { OrderCount: > 10 } => 0.10m,
        _ => 0.05m
    };
    
    // Guard clauses with ArgumentNullException.ThrowIfNull (C# 11+)
    public void ProcessOrder(Order? order)
    {
        ArgumentNullException.ThrowIfNull(order);
        // order is now non-nullable in this scope
        Console.WriteLine(order.Id);
    }
    

    Composition Over Inheritance

    Avoid abstract base classes. Use interfaces + composition. Use static helpers for shared logic. Use records with factory methods for variants.

    See composition-and-error-handling.md for full examples.


    Performance Patterns

    Async/Await Best Practices

    // Async all the way - always accept CancellationToken
    public async Task<Order> GetOrderAsync(string orderId, CancellationToken cancellationToken)
    {
        var order = await _repository.GetAsync(orderId, cancellationToken);
        return order;
    }
    
    // ValueTask for frequently-called, often-synchronous methods
    public ValueTask<Order?> GetCachedOrderAsync(string orderId, CancellationToken cancellationToken)
    {
        if (_cache.TryGetValue(orderId, out var order))
            return ValueTask.FromResult<Order?>(order);
        return GetFromDatabaseAsync(orderId, cancellationToken);
    }
    
    // IAsyncEnumerable for streaming
    public async IAsyncEnumerable<Order> StreamOrdersAsync(
        string customerId,
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        await foreach (var order in _repository.StreamAllAsync(cancellationToken))
        {
            if (order.CustomerId == customerId)
                yield return order;
        }
    }
    

    Key rules:

    • Always accept CancellationToken with = default
    • Use ConfigureAwait(false) in library code
    • Never block on async code (no .Result or .Wait())
    • Use linked CancellationTokenSource for timeouts

    Span and Memory

    Use Span<T> for synchronous zero-allocation operations, Memory<T> for async, and ArrayPool<T> for large temporary buffers.

    See performance-and-api-design.md for complete Span/Memory examples and the API design section.


    Error Handling: Result Type

    For expected errors, use a domain-specific result type instead of exceptions, not a generic Result<T>. Use exceptions only for unexpected/system errors.

    See composition-and-error-handling.md for the full Result type implementation and usage examples.


    Avoid Reflection-Based Metaprogramming

    Banned: AutoMapper, Mapster, ExpressMapper. Use explicit mapping extension methods instead. Use UnsafeAccessorAttribute (.NET 8+) when you genuinely need private member access.

    See anti-patterns-and-reflection.md for full guidance.


    Code Organization

    // File: Domain/Orders/Order.cs
    
    namespace MyApp.Domain.Orders;
    
    // 1. Primary domain type
    public record Order(
        OrderId Id,
        CustomerId CustomerId,
        Money Total,
        OrderStatus Status,
        IReadOnlyList<OrderItem> Items
    )
    {
        public bool IsCompleted => Status is OrderStatus.Completed;
    
        public Result<Order, OrderError> AddItem(OrderItem item)
        {
            if (Status is not OrderStatus.Draft)
                return Result<Order, OrderError>.Failure(
                    new OrderError("ORDER_NOT_DRAFT", "Can only add items to draft orders"));
    
            var newItems = Items.Append(item).ToList();
            var newTotal = new Money(
                Items.Sum(i => i.Total.Amount) + item.Total.Amount,
                Total.Currency);
    
            return Result<Order, OrderError>.Success(
                this with { Items = newItems, Total = newTotal });
        }
    }
    
    // 2. Enums for state
    public enum OrderStatus { Draft, Submitted, Processing, Completed, Cancelled }
    
    // 3. Related types
    public record OrderItem(ProductId ProductId, Quantity Quantity, Money UnitPrice)
    {
        public Money Total => new(UnitPrice.Amount * Quantity.Value, UnitPrice.Currency);
    }
    
    // 4. Value objects
    public readonly record struct OrderId(Guid Value)
    {
        public static OrderId New() => new(Guid.NewGuid());
    }
    
    // 5. Errors
    public readonly record struct OrderError(string Code, string Message);
    

    Best Practices Summary

    DO's

    • Use record for DTOs, messages, and domain entities
    • Use readonly record struct for value objects
    • Leverage pattern matching with switch expressions
    • Enable and respect nullable reference types
    • Use async/await for all I/O operations
    • Accept CancellationToken in all async methods
    • Use Span<T> and Memory<T> for high-performance scenarios
    • Accept abstractions (IEnumerable<T>, IReadOnlyList<T>)
    • Use Result<T, TError> for expected errors
    • Pool buffers with ArrayPool<T> for large allocations
    • Prefer composition over inheritance

    DON'Ts

    • Don't use mutable classes when records work
    • Don't use classes for value objects (use readonly record struct)
    • Don't create deep inheritance hierarchies
    • Don't ignore nullable reference type warnings
    • Don't block on async code (.Result, .Wait())
    • Don't use byte[] when Span<byte> suffices
    • Don't forget CancellationToken parameters
    • Don't return mutable collections from APIs
    • Don't throw exceptions for expected business errors
    • Don't allocate large arrays repeatedly (use ArrayPool)

    See anti-patterns-and-reflection.md for detailed anti-pattern examples.


    Additional Resources

    • C# Language Specification: https://learn.microsoft.com/en-us/dotnet/csharp/
    • Pattern Matching: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching
    • Span and Memory: https://learn.microsoft.com/en-us/dotnet/standard/memory-and-spans/
    • Async Best Practices: https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming
    • .NET Performance Tips: https://learn.microsoft.com/en-us/dotnet/framework/performance/

    Требования и возможности

    Источник пакета
    https://github.com/aaronontheweb/dotnet-skills/tree/ac0deb2f531ff5090718cb0069c73ba3f9f95f69/skills/csharp-coding-standards

    Файлы версии

    ПутьРазмерSHA256
    SKILL.md10695e40104dd1b7328ce...
    anti-patterns-and-reflection.md87706dfc0904421bdded...
    composition-and-error-handling.md80824b0033c32b581a7e...
    performance-and-api-design.md10263579c5c798eb68e70...
    value-objects-and-patterns.md126108c27d3f8b6a4c076...

    Частые вопросы

    Как установить Modern Csharp Coding Standards?
    Используйте команду npx skills add aaronontheweb/dotnet-skills --skill modern-csharp-coding-standards или скачайте ZIP-архив.
    Можно ли скачать Modern Csharp Coding Standards бесплатно?
    Да, опубликованную версию можно скачать из маркетплейса бесплатно.

    Похожие инструменты

    Смотреть все
    2ГИС: Карточка организации 2ГИСПолучить подробные данные объекта по идентификатору.2ГИС: Статическая карта 2ГИССформировать PNG-карту с точками, линиями или полигонами.2ГИС: Матрица расстояний 2ГИСРассчитать время и расстояния между наборами точек.2ГИС: Обратное геокодирование 2ГИСНайти адрес и объекты рядом с заданными координатами.
    Комментарии

    Войдите, чтобы оставить комментарий.

    Комментариев пока нет.