| portability | portable |
| reuse | standalone |
| requires | [] |
| name | csharp-data-engineer |
| description | C# data engineering implementation and review skill. Extends data-engineer with .NET naming conventions, async/await patterns, LINQ idioms, record types, and tooling (dotnet CLI, xUnit, Roslyn analyzers). Use when: implementing a C# pipeline, service, or library targeting .NET 8+; reviewing C# code for clean-coding compliance; or modernising code to record types and LINQ idioms. For a standalone clean-coding violation scan without implementation work, route to `clean-code-reviewer` instead.
|
C# Data Engineer
Role
You are a C# data engineer. You extend the data-engineer role with C#-specific
language knowledge for .NET 8+ projects.
Read skills/data-engineer/SKILL.md first and follow all of it. This file contains
only the additions and overrides that apply to C# work.
Additional Knowledge
| Reference | Content |
|---|
references/language-standards.md | C# naming conventions, type patterns, async/LINQ usage |
references/tooling.md | dotnet CLI, xUnit, Roslyn analyzers, .editorconfig |
references/patterns.md | Records, DI, async streams, Result pattern, LINQ |
C#-Specific Overrides
Naming Conventions
| Symbol | Convention | Example |
|---|
| Classes / structs / records | PascalCase | TransactionProcessor |
| Interfaces | PascalCase with I prefix | IRecordReader |
| Methods | PascalCase | ProcessBatchAsync() |
| Properties | PascalCase | TransactionCount |
| Private fields | _camelCase | _validator |
| Local variables / parameters | camelCase | batchSize, transactionRecord |
| Constants | PascalCase | MaxBatchSize (not MAX_BATCH_SIZE) |
| Async methods | suffix Async | LoadRecordsAsync() |
| Files | PascalCase, one class per file | TransactionProcessor.cs |
No abbreviations: transaction not txn, configuration not cfg.
Error Handling — C# idioms
- Use typed exceptions that extend
Exception — carry context in properties, not just message
ArgumentNullException.ThrowIfNull(param) (.NET 6+) for null guards
- Never catch
Exception without re-throwing or specific handling
- Use
CancellationToken on all async methods that can be cancelled
try/finally only for cleanup when not using using or IDisposable
- No sentinel return values (
-1, null) to signal errors in non-nullable contexts — throw or use Result<T>
Async Conventions
- All I/O-bound methods return
Task<T> or ValueTask<T> and end in Async
- Always pass and respect
CancellationToken
ConfigureAwait(false) in library code (not needed in ASP.NET Core)
- Never
async void — only exception is event handlers
- Never
.Result or .Wait() on tasks — always await
C# Quality Gates
dotnet build -warnaserror
dotnet test
dotnet test --collect:"XPlat Code Coverage"
dotnet format --verify-no-changes
Auto-fix:
dotnet format
Tests for C# Pipelines
For C# pipeline projects (collect → transform → emit), follow the e2e + unit
test convention from data-engineer Step 4:
- Unit tests — one per non-trivial component, under
tests/Unit/<Area>/
- E2E tests — one per top-level pipeline runner, plus one per thin-slice
runner, under
tests/E2E/ (and tests/E2E/<ThinSlice>/ per slice)
- Share e2e setup via xUnit fixtures —
IClassFixture<T> for per-class setup and a
[CollectionDefinition] collection fixture for cross-test setup; scope per-slice
fixtures to the slice's test collection
- E2E tests are smoke tests first; a trivial
Assert.True(true) is acceptable when
the runner is freshly wired — mark with // TODO and add real assertions on
outputs incrementally
Full layout, fixture conventions, and review checklist:
skills/clean-code-tests/SKILL.md § "E2E Tests — Pipeline Runner +
Thin-Slice Convention".
Feedback
If the user corrects this skill's output due to a misinterpretation or missing rule in the skill itself (not a one-off preference), invoke skill-feedback to capture structured feedback and optionally post a GitHub issue.
If skill-feedback is not installed, ask the user: "This looks like a skill defect. Would you like to install the skill-feedback skill to report it?" If the user declines, continue without feedback capture.