Agent skill

Type Design Performance

by Aaronontheweb in Aaronontheweb/dotnet-skills

Design .NET types for performance. An agent skill from Aaronontheweb/dotnet-skills.

MITAuto-check passed

Install Type Design Performance

skills CLI
$ npx skills add Aaronontheweb/dotnet-skills --skill type-design-performance -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Aaronontheweb/dotnet-skills type-design-performance --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Aaronontheweb/dotnet-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/csharp-type-design-performance .claude/skills/type-design-performance && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
type-design-performance
GitHub stars
1.2k
Used in
1 other repo
Token cost
~2.5k tokens
SKILL.md length
389 words
Files
1
Skills in repo
33
Repo updated
First seen
Licence
MIT

At a glance

Design .NET types for performance. An agent skill from Aaronontheweb/dotnet-skills.

  • Works in 5 steps: Seal your types - Unless explicitly… → Prefer readonly structs - For small,… → Prefer static pure functions - Better… → …
  • SKILL.md covers When to Use This Skill, Core Principles, Seal Classes by Default and Readonly Structs for Value Types, plus 8 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Type Design Performance is an agent skill from Aaronontheweb/dotnet-skills. Design .NET types for performance. Seal classes, use readonly structs, prefer static pure functions, avoid premature enumeration, and choose the right collection types.

Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It works with .NET and C#. The repository describes itself as: Claude Code skills and sub-agents for .NET Developers. The licence is MIT.

Example prompts

  • “/type-design-performance”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Seal your types - Unless explicitly designed for inheritance
  2. Prefer readonly structs - For small, immutable value types
  3. Prefer static pure functions - Better performance and testability
  4. Defer enumeration - Don't materialize until you need to
  5. Return immutable collections - From API boundaries

What it can do on your machine

Read from SKILL.md and the folder at commit e426ed9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • learn.microsoft.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Type Design Performance loads about 2.5k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 389 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~48
When it runs · the whole SKILL.md, loaded when a task matches
~2.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Aaronontheweb/dotnet-skills at commit e426ed9, republished under its MIT licence (© Aaronontheweb). 389 words, ~2,500 tokens.

Download SKILL.mdSave it as .claude/skills/type-design-performance/SKILL.md (or your agent's skills folder).
name
type-design-performance
description
Design .NET types for performance. Seal classes, use readonly structs, prefer static pure functions, avoid premature enumeration, and choose the right collection types.
invocable
false

Type Design for Performance

When to Use This Skill

Use this skill when:

  • Designing new types and APIs
  • Reviewing code for performance issues
  • Choosing between class, struct, and record
  • Working with collections and enumerables

Core Principles

  1. Seal your types - Unless explicitly designed for inheritance
  2. Prefer readonly structs - For small, immutable value types
  3. Prefer static pure functions - Better performance and testability
  4. Defer enumeration - Don't materialize until you need to
  5. Return immutable collections - From API boundaries

Seal Classes by Default

Sealing classes enables JIT devirtualization and communicates API intent.

csharp
// DO: Seal classes not designed for inheritance
public sealed class OrderProcessor
{
    public void Process(Order order) { }
}

// DO: Seal records (they're classes)
public sealed record OrderCreated(OrderId Id, CustomerId CustomerId);

// DON'T: Leave unsealed without reason
public class OrderProcessor  // Can be subclassed - intentional?
{
    public virtual void Process(Order order) { }  // Virtual = slower
}

Benefits:

  • JIT can devirtualize method calls
  • Communicates "this is not an extension point"
  • Prevents accidental breaking changes

Readonly Structs for Value Types

Structs should be readonly when immutable. This prevents defensive copies.

csharp
// DO: Readonly struct for immutable value types
public readonly record struct OrderId(Guid Value)
{
    public static OrderId New() => new(Guid.NewGuid());
    public override string ToString() => Value.ToString();
}

// DO: Readonly struct for small, short-lived data
public readonly struct Money
{
    public decimal Amount { get; }
    public string Currency { get; }

    public Money(decimal amount, string currency)
    {
        Amount = amount;
        Currency = currency;
    }
}

// DON'T: Mutable struct (causes defensive copies)
public struct Point  // Not readonly!
{
    public int X { get; set; }  // Mutable!
    public int Y { get; set; }
}
When to Use Structs
Use Struct WhenUse Class When
Small (≤16 bytes typically)Larger objects
Short-livedLong-lived
Frequently allocatedShared references needed
Value semantics requiredIdentity semantics required
ImmutableMutable state

Prefer Static Pure Functions

Static methods with no side effects are faster and more testable.

csharp
// DO: Static pure function
public static class OrderCalculator
{
    public static Money CalculateTotal(IReadOnlyList<OrderItem> items)
    {
        var total = items.Sum(i => i.Price * i.Quantity);
        return new Money(total, "USD");
    }
}

// Usage - predictable, testable
var total = OrderCalculator.CalculateTotal(items);

Benefits:

  • No vtable lookup (faster)
  • No hidden state
  • Easier to test (pure input → output)
  • Thread-safe by design
  • Forces explicit dependencies
csharp
// DON'T: Instance method hiding dependencies
public class OrderCalculator
{
    private readonly ITaxService _taxService;  // Hidden dependency
    private readonly IDiscountService _discountService;  // Hidden dependency

    public Money CalculateTotal(IReadOnlyList<OrderItem> items)
    {
        // What does this actually depend on?
    }
}

// BETTER: Explicit dependencies via parameters
public static class OrderCalculator
{
    public static Money CalculateTotal(
        IReadOnlyList<OrderItem> items,
        decimal taxRate,
        decimal discountPercent)
    {
        // All inputs visible
    }
}

Don't go overboard - Use instance methods when you genuinely need state or polymorphism.


Defer Enumeration

Don't materialize enumerables until necessary. Avoid excessive LINQ chains.

csharp
// BAD: Premature materialization
public IReadOnlyList<Order> GetActiveOrders()
{
    return _orders
        .Where(o => o.IsActive)
        .ToList()  // Materialized!
        .OrderBy(o => o.CreatedAt)  // Another iteration
        .ToList();  // Materialized again!
}

// GOOD: Defer until the end
public IReadOnlyList<Order> GetActiveOrders()
{
    return _orders
        .Where(o => o.IsActive)
        .OrderBy(o => o.CreatedAt)
        .ToList();  // Single materialization
}

// GOOD: Return IEnumerable if caller might not need all items
public IEnumerable<Order> GetActiveOrders()
{
    return _orders
        .Where(o => o.IsActive)
        .OrderBy(o => o.CreatedAt);
    // Caller decides when to materialize
}
Async Enumeration

Be careful with async and IEnumerable:

csharp
// BAD: Async in LINQ - hidden allocations
var results = orders
    .Select(async o => await ProcessOrderAsync(o))  // Task per item!
    .ToList();
await Task.WhenAll(results);

// GOOD: Use IAsyncEnumerable for streaming
public async IAsyncEnumerable<OrderResult> ProcessOrdersAsync(
    IEnumerable<Order> orders,
    [EnumeratorCancellation] CancellationToken ct = default)
{
    foreach (var order in orders)
    {
        ct.ThrowIfCancellationRequested();
        yield return await ProcessOrderAsync(order, ct);
    }
}

// GOOD: Batch processing for parallelism
var results = await Task.WhenAll(
    orders.Select(o => ProcessOrderAsync(o)));

Show full SKILL.md (166 more words)Show less

ValueTask vs Task

Use ValueTask for hot paths that often complete synchronously. For real I/O, just use Task.

csharp
// DO: ValueTask for cached/synchronous paths
public ValueTask<User?> GetUserAsync(UserId id)
{
    if (_cache.TryGetValue(id, out var user))
    {
        return ValueTask.FromResult<User?>(user);  // No allocation
    }

    return new ValueTask<User?>(FetchUserAsync(id));
}

// DO: Task for real I/O (simpler, no footguns)
public Task<Order> CreateOrderAsync(CreateOrderCommand cmd)
{
    // This always hits the database
    return _repository.CreateAsync(cmd);
}

ValueTask rules:

  • Never await a ValueTask more than once
  • Never use .Result or .GetAwaiter().GetResult() before completion
  • If in doubt, use Task

Span and Memory for Bytes

Use Span<T> and Memory<T> instead of byte[] for low-level operations.

csharp
// DO: Accept Span for synchronous operations
public static int ParseInt(ReadOnlySpan<char> text)
{
    return int.Parse(text);
}

// DO: Accept Memory for async operations
public async Task WriteAsync(ReadOnlyMemory<byte> data)
{
    await _stream.WriteAsync(data);
}

// DON'T: Force array allocation
public static int ParseInt(string text)  // String allocated
{
    return int.Parse(text);
}
Common Span Patterns
csharp
// Slice without allocation
ReadOnlySpan<char> span = "Hello, World!".AsSpan();
var hello = span[..5];  // No allocation

// Stack allocation for small buffers
Span<byte> buffer = stackalloc byte[256];

// Use ArrayPool for larger buffers
var buffer = ArrayPool<byte>.Shared.Rent(4096);
try
{
    // Use buffer...
}
finally
{
    ArrayPool<byte>.Shared.Return(buffer);
}

Collection Return Types

Return Immutable Collections from APIs
csharp
// DO: Return immutable collection
public IReadOnlyList<Order> GetOrders()
{
    return _orders.ToList();  // Caller can't modify internal state
}

// DO: Use frozen collections for static data (.NET 8+)
private static readonly FrozenDictionary<string, Handler> _handlers =
    new Dictionary<string, Handler>
    {
        ["create"] = new CreateHandler(),
        ["update"] = new UpdateHandler(),
    }.ToFrozenDictionary();

// DON'T: Return mutable collection
public List<Order> GetOrders()
{
    return _orders;  // Caller can modify!
}
Internal Mutation is Fine
csharp
public IReadOnlyList<OrderItem> BuildOrderItems(Cart cart)
{
    var items = new List<OrderItem>();  // Mutable internally

    foreach (var cartItem in cart.Items)
    {
        items.Add(CreateOrderItem(cartItem));
    }

    return items;  // Return as IReadOnlyList
}
Collection Guidelines
ScenarioReturn Type
API boundaryIReadOnlyList<T>, IReadOnlyCollection<T>
Static lookup dataFrozenDictionary<K,V>, FrozenSet<T>
Internal buildingList<T>, then return as readonly
Single item or noneT? (nullable)
Zero or more, lazyIEnumerable<T>

Quick Reference

PatternBenefit
sealed classDevirtualization, clear API
readonly record structNo defensive copies, value semantics
Static pure functionsNo vtable, testable, thread-safe
Defer .ToList()Single materialization
ValueTask for hot pathsAvoid Task allocation
Span<T> for bytesStack allocation, no copying
IReadOnlyList<T> returnImmutable API contract
FrozenDictionaryFastest lookup for static data

Anti-Patterns

csharp
// DON'T: Unsealed class without reason
public class OrderService { }  // Seal it!

// DON'T: Mutable struct
public struct Point { public int X; public int Y; }  // Make readonly

// DON'T: Instance method that could be static
public int Add(int a, int b) => a + b;  // Make static

// DON'T: Multiple ToList() calls
items.Where(...).ToList().OrderBy(...).ToList();  // One ToList at end

// DON'T: Return List<T> from public API
public List<Order> GetOrders();  // Return IReadOnlyList<T>

// DON'T: ValueTask for always-async operations
public ValueTask<Order> CreateOrderAsync();  // Just use Task

Resources

© Aaronontheweb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/csharp-type-design-performance of Aaronontheweb/dotnet-skills.

Open the folder on GitHubat commit e426ed9

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in Aaronontheweb/dotnet-skills, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Type Design Performance next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Type Design Performance compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Type Design Performance this skillAaronontheweb/dotnet-skills1.2k1 repos~2.5kAutomated safety check: PassMIT
Minimax DOCXpoco-ai/poco-claw1.4k7 repos~3.9kAutomated safety check: PassMIT
Speckit ConstitutionWeihanLi/WeihanLi.Common24211 repos~2.1kAutomated safety check: PassApache-2.0
Analyzing .NET Performancedotnet/skills5.6k3 repos~3.1kAutomated safety check: PassMIT
Add Analyzerdotnet/roslynator3.5k—~1.3kAutomated safety check: PassCustom licence
GitVersion .NET DevelopmentGitTools/GitVersion3.1k—~1.7kAutomated safety check: PassMIT

Similar skills

  • Minimax DOCX

    poco-ai/poco-claw

    Professional DOCX document creation, editing, and formatting using OpenXML SDK (.NET).

    1.4k GitHub starsUsed in 7 repos~3.9k tokens
    Documents & OfficeAuto-check passed
  • Speckit Constitution

    WeihanLi/WeihanLi.Common

    Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync.

    242 GitHub starsUsed in 11 repos~2.1k tokens
    DevelopmentAuto-check passed
  • Official

    Scans C# and .NET code for about 50 performance anti-patterns and reports prioritized findings with concrete fixes, at a scan depth you choose.

    5.6k GitHub starsUsed in 3 repos~3.1k tokens
    DevelopmentAuto-check passed
  • Add Analyzer

    dotnet/roslynator

    Official

    A skill your agent uses when adding a new RCS diagnostic in roslynator (RCS0 formatting, RCS1 general, RCS9 code-analysis), wiring roslynator EditorConfig options, or when docs say CHANGELOG.md…

    3.5k GitHub stars~1.3k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • GitVersion .NET Development

    GitTools/GitVersion

    Gives repository-specific .NET guidance for GitVersion: build and test commands, central package management, project layout and coding conventions.

    3.1k GitHub stars~1.7k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Code Review

    dotnet/macios

    Official

    Review dotnet/macios PRs against established rules. An agent skill from dotnet/macios.

    2.9k GitHub stars~1.7k tokensUpdated today
    DevelopmentAuto-check passed

More from Aaronontheweb/dotnet-skills

All 33 skills in this repo
  • .NET API Compatibility Design

    Aaronontheweb/dotnet-skills

    Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely.

    1.2k GitHub starsUsed in 2 repos~2.7k tokens
    Auto-check passed
  • .NET Trimming and Native AOT

    Aaronontheweb/dotnet-skills

    Guides making .NET libraries trimming-safe and Native-AOT compatible: the MSBuild properties, trimming attributes, warning codes and a playbook of safe patterns.

    1.2k GitHub stars~2.9k tokensUpdated 19 days ago
    Auto-check passed
  • Akka.Hosting Actor Patterns

    Aaronontheweb/dotnet-skills

    Shows how to build entity actors with Akka.Hosting so the same code runs in local unit tests and in a sharded cluster in production.

    1.2k GitHub starsUsed in 1 repo~5k tokens
    Auto-check passed
  • Akka.NET Best Practices

    Aaronontheweb/dotnet-skills

    Guidance for Akka.NET actor systems covering EventStream versus DistributedPubSub, supervision, Props versus DependencyResolver, work distribution and testable cluster code.

    1.2k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Akka.NET Management and Discovery

    Aaronontheweb/dotnet-skills

    Sets up Akka.Management and Cluster.Bootstrap so Akka.NET clusters form through service discovery on Kubernetes, Azure or config instead of static seed nodes.

    1.2k GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Akka.NET Testing Patterns

    Aaronontheweb/dotnet-skills

    Shows how to test Akka.NET actors with Akka.Hosting.TestKit: swapping services for fakes, using TestProbes, and checking persistence, plus when the older TestKit still fits.

    1.2k GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check passed

Works with

Questions about Type Design Performance

What does Type Design Performance do?

Design .NET types for performance. An agent skill from Aaronontheweb/dotnet-skills. Type Design Performance is an agent skill from Aaronontheweb/dotnet-skills.NET types for performance.

How do I install Type Design Performance in Claude Code?

Run `npx skills add Aaronontheweb/dotnet-skills --skill type-design-performance -a claude-code`. Or copy the skill folder (skills/csharp-type-design-performance in Aaronontheweb/dotnet-skills) into .claude/skills/type-design-performance in your project. Claude Code loads it when a task matches its description.

How do I install Type Design Performance in Codex?

Run `npx skills add Aaronontheweb/dotnet-skills --skill type-design-performance -a codex`. Or copy the skill folder (skills/csharp-type-design-performance in Aaronontheweb/dotnet-skills) into .agents/skills/type-design-performance in your project. Codex loads it when a task matches its description.

Can I use Type Design Performance in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Aaronontheweb/dotnet-skills --skill type-design-performance -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/type-design-performance, .gemini/skills/type-design-performance, .github/skills/type-design-performance and .opencode/skills/type-design-performance in your project.

What does Type Design Performance need to run?

SKILL.md names no scripts, command-line tools or credentials: Type Design Performance is instructions for the agent only.

Does Type Design Performance access the network?

SKILL.md names 1 domain. As links in the text: learn.microsoft.com. This is read from the text; nothing was executed.

Is Type Design Performance safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Type Design Performance use?

Type Design Performance is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Type Design Performance use?

About 2.5k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Type Design Performance?

Skills that share tags, products or a category with Type Design Performance: Minimax DOCX (poco-ai/poco-claw, 1.4k stars), Speckit Constitution (WeihanLi/WeihanLi.Common, 242 stars), Analyzing .NET Performance (dotnet/skills, 5.6k stars) and Add Analyzer (dotnet/roslynator, 3.5k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Type Design Performance?

Aaronontheweb (a GitHub user) maintains it in Aaronontheweb/dotnet-skills, which has 1,202 GitHub stars. The repository holds 33 skills in this directory. The repository was last updated on September 17, 2026.

Source: Aaronontheweb/dotnet-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.