csharp – skill Lập trình cho agent AI
Hướng dẫn super-code theo ngôn ngữ dành riêng cho csharp.
Cài skill csharp bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/csharp-459c4.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /csharp – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/csharp-459c4.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $csharp – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/csharp-459c4.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /csharp – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/csharp-459c4.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /csharp – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
C#: Idiomatic Efficiency Reference
Apply only within the requested scope and current project conventions. Preserve behavior, ownership, error handling, accessibility and security; examples are independent fragments, not equivalent rewrites in every context. Verify language/library versions and run relevant checks. Required tests and user-facing progress/results take precedence over brevity rules. Do not install dependencies or delete files merely to follow these examples.
When to Use
- Use this skill when the task matches this description: Language-specific super-code guidelines for csharp.
Table of Contents
1. [LINQ & Collections](#linq)
2. [Null Handling](#nulls)
3. [Async/Await](#async)
4. [Records & Pattern Matching](#records)
5. [Error Handling](#errors)
6. [Resource Management](#resources)
7. [Anti-patterns specific to C#](#antipatterns)
---
1. LINQ & Collections {#linq}
// ❌ Imperative accumulation
var result = new List<string>();
foreach (var item in items) {
if (item.IsActive) result.Add(item.Name.ToUpper());
}
// ✅
var result = items
.Where(i => i.IsActive)
.Select(i => i.Name.ToUpper())
.ToList();// ❌ Manual grouping
var grouped = new Dictionary<string, List<Item>>();
foreach (var item in items) {
if (!grouped.ContainsKey(item.Category))
grouped[item.Category] = new List<Item>();
grouped[item.Category].Add(item);
}
// ✅
var grouped = items.GroupBy(i => i.Category)
.ToDictionary(g => g.Key, g => g.ToList());// ❌ Checking Any() then First()
if (items.Any(i => i.IsValid)) {
var first = items.First(i => i.IsValid);
}
// ✅
var first = items.FirstOrDefault(i => i.IsValid);
if (first is not null) { ... }Prefer method syntax for chains of 2+ operations. Query syntax is fine for complex joins.
---
2. Null Handling {#nulls}
// ❌ Nested null checks
string city = null;
if (user != null && user.Address != null) {
city = user.Address.City;
}
// ✅
var city = user?.Address?.City;// ❌ Ternary for null fallback
var name = user != null ? user.Name : "Unknown";
// ✅
var name = user?.Name ?? "Unknown";// ❌ Null check before event invocation
if (OnChanged != null) OnChanged(this, args);
// ✅
OnChanged?.Invoke(this, args);// ❌ Throwing ArgumentNullException manually
if (name == null) throw new ArgumentNullException(nameof(name));
// ✅ (.NET 6+)
ArgumentNullException.ThrowIfNull(name);Enable nullable reference types (<Nullable>enable</Nullable>) project-wide.
---
3. Async/Await {#async}
// ❌ Blocking on async code
var result = GetDataAsync().Result; // deadlock risk
// ✅
var result = await GetDataAsync();// ❌ async void (exceptions are unobservable)
async void OnButtonClick() { await DoWork(); }
// ✅ — async Task; only async void for event handlers that truly require it
async Task OnButtonClick() { await DoWork(); }// ❌ Sequential awaits for independent work
var a = await FetchA();
var b = await FetchB();
// ✅
var (a, b) = (await Task.WhenAll(FetchA(), FetchB())) switch
{
var r => (r[0], r[1])
};
// or cleaner with ValueTuple:
var taskA = FetchA();
var taskB = FetchB();
var a = await taskA;
var b = await taskB;// ❌ Wrapping synchronous code in Task.Run inside a library
public Task<int> GetValue() => Task.Run(() => ComputeSync());
// ✅ — let the caller decide; expose sync method
public int GetValue() => ComputeSync();Add ConfigureAwait(false) in library code. Omit in app/UI code.
---
4. Records & Pattern Matching {#records}
// ❌ Manual equality, ToString, Deconstruct for data types
class Point {
public int X { get; init; }
public int Y { get; init; }
// + Equals, GetHashCode, ToString...
}
// ✅ (C# 9+)
record Point(int X, int Y);// ❌ if-else chain for type checking
if (shape is Circle) {
var c = (Circle)shape;
return c.Radius * c.Radius * Math.PI;
} else if (shape is Rectangle) { ... }
// ✅
return shape switch {
Circle { Radius: var r } => r * r * Math.PI,
Rectangle { Width: var w, Height: var h } => w * h,
_ => throw new ArgumentException($"Unknown shape: {shape}")
};// ❌ Range checking with &&
if (score >= 0 && score <= 100) { ... }
// ✅ (C# 9+)
if (score is >= 0 and <= 100) { ... }---
5. Error Handling {#errors}
// ❌ Catching Exception to log and swallow
try { Process(); }
catch (Exception ex) { logger.LogError(ex, "error"); }
// ✅ — catch specific, rethrow if you can't handle
try { Process(); }
catch (HttpRequestException ex) {
throw new ServiceException("upstream failure", ex);
}// ❌ throw ex (resets stack trace)
catch (Exception ex) { throw ex; }
// ✅
catch (Exception ex) { throw; } // preserves stack trace
// or wrap: throw new AppException("context", ex);// ❌ Exceptions for flow control
try { return dict[key]; }
catch (KeyNotFoundException) { return defaultValue; }
// ✅
return dict.TryGetValue(key, out var value) ? value : defaultValue;---
6. Resource Management {#resources}
// ❌ Manual Dispose
var conn = new SqlConnection(cs);
conn.Open();
// ... use conn ...
conn.Dispose(); // missed on exception
// ✅
using var conn = new SqlConnection(cs);
conn.Open();
// disposed at end of scope// ❌ Verbose using block
using (var reader = new StreamReader(path)) {
return reader.ReadToEnd();
}
// ✅ (C# 8+)
using var reader = new StreamReader(path);
return reader.ReadToEnd();
// or just: return File.ReadAllText(path);---
7. Anti-patterns specific to C# {#antipatterns}
| Anti-pattern | Preferred |
|---|---|
| string.Format("{0}", x) | $"{x}" string interpolation |
| List<T> as public API return | IReadOnlyList<T> or IEnumerable<T> |
| async void | async Task |
| .Result / .Wait() on Task | await |
| throw ex | throw (preserves stack trace) |
| Manual IEquatable on data types | record |
| object parameters | generics with constraints |
| DateTime.Now | DateTime.UtcNow or DateTimeOffset |
| Mutable public fields | properties with { get; set; } or { get; init; } |
| catch (Exception) { } (swallow all) | catch specific exceptions, rethrow unknown |
| IDisposable without using | using declaration |
Limitations
- These are language-specific guidelines and do not cover overall architectural decisions.
- Over-compression might reduce readability; apply judgement.
Skill liên quan
- csharp-pro – Viết code C# hiện đại với các tính năng nâng cao như record, pattern matching và…
- cucumber-skill – Tạo test BDD Cucumber với tệp feature Gherkin và step definition bằng Java, JavaScript…
- md-review – Chuyển một bản mô tả PR hoặc code review dạng markdown (có khối ```diff và callout GFM…
- cypress-skill – Tạo các bài kiểm thử E2E và component Cypress đạt chuẩn production bằng JavaScript hoặc…
- dart – Hướng dẫn viết code siêu chuẩn riêng cho ngôn ngữ dart.
- sdlc-review – Xem xét các handoff Kanban và chuyển tiếp các kết quả đã xác minh.
- migrate – Chuyển từ Cypress hoặc Selenium sang Playwright. Dùng khi người dùng nhắc đến "cypress"…
- unauth-api-flow-hijack – Khai thác các luồng API nhiều bước không xác thực mà không cần thông tin đăng nhập.