|
General
- Understand the boundaries of your codebase (AV0100)
- Prefer composition over inheritance (AV0110)
- Apply the Principle of Least Surprise (AV0112)
- Keep It Simple Stupid (KISS) (AV0115)
- You Ain’t Gonna Need It (YAGNI) (AV0120)
- Don’t Repeat Yourself (DRY), but only within boundaries (AV0125)
- Apply the four pillars of object-oriented programming (AV0130)
- Treat AI-generated code as your own (AV0135)
Class Design
- A class or interface should have a single purpose (AV1000)
- Only include constructor parameters that most or all members need (AV1002)
- Use an interface rather than a base class to support multiple implementations (AV1004)
- Use an interface to decouple classes from each other (AV1005)
- It should be possible to treat a derived type as if it were a base type (AV1011)
- Avoid bidirectional dependencies (AV1020)
- Classes should protect the consistency of their internal state (AV1026)
- Know when to use a record and when to use a class (AV1030)
- Consider a named delegate instead of an interface with a single method (AV1032)
|
**Member Design**
* Allow properties to be set in any order (AV1100)
* Don't use mutually exclusive properties (AV1110)
* A property, method or local function should do only one thing (AV1115)
* Don't hide dependencies behind static members (AV1125)
* Return interfaces to unchangeable collections (AV1130)
* Define parameters as specific and narrow as possible (AV1137)
* Consider creating domain-specific types rather than using primitives (AV1140)
* Use extension members to add behavior without modifying the original type (AV1145)
**Miscellaneous Design**
* Throw exceptions rather than returning some kind of status value (AV1200)
* Throw the most specific exception that is appropriate (AV1205)
* Don't swallow errors by catching generic exceptions (AV1210)
* Properly handle exceptions in asynchronous code (AV1215)
* Use a protected virtual method to raise each event (AV1225)
* Materialize the result of a LINQ expression before returning it (AV1250)
* Do not use `this` and `base` prefixes unless it is required (AV1251)
|
**Maintainability**
* Methods should not exceed 15 statements (AV1500)
* Make all members `private` and types `internal sealed` by default (AV1501)
* Don't use "magic" numbers (AV1515)
* Only use `var` when the type is evident (AV1520)
* Favor object and collection initializers over separate statements (AV1523)
* Always add a block after the keywords `if`, `else`, `do`, `while`, `for`, `foreach` and `case` (AV1535)
* Use concise conditional expressions instead of `if`-`else` blocks (AV1545)
* Prefer interpolated strings over concatenation or `string.Format` (AV1546)
* Don't use `ref` or `out` parameters (AV1562)
* Avoid signatures that take a `bool` parameter (AV1564)
* Align projects and folders with deployment units, not architectural layers (AV1578)
* Make properties required when they must be set during initialization (AV1585)
**Performance**
* Consider using `Any()` to determine whether an `IEnumerable` is empty (AV1800)
* Only use `async`/`await` for I/O-bound or long-running activities (AV1820)
* Prefer `Task.Run` for CPU-intensive activities (AV1825)
* Beware of `async`/`await` deadlocks in UI frameworks (AV1835)
</td>
</tr>
</table>
| Coding Guidelines for C# 14 Cheat Sheet |
</td>
</tr>
|
Testability, Naming & Style |
</table>
|
Testability
- Use short concise functional test names (AV1600)
- Test observable behavior, not private implementation details (AV1605)
- Show what’s important in a test, hide what’s not (AV1608)
- Use Test Data Builders or Object Mothers to construct test objects (AV1610)
- Don’t use production code in test assertions (AV1618)
- Test reusable components separately from their consumers (AV1620)
- Test concrete implementations as part of a larger integration scope (AV1622)
|
**Naming**
* Use US English (AV1701)
* Use proper casing for language elements (AV1702)
* Don't prefix fields (AV1705)
* Don't use abbreviations (AV1706)
* Name members, parameters and variables according to their meaning and not their type (AV1707)
* Name generic type parameters with descriptive names (AV1709)
* Properly name properties (AV1715)
* Name methods and local functions using verbs or verb-object pairs (AV1720)
* Use a verb or verb phrase to name an event (AV1735)
* Use an underscore for irrelevant lambda parameters (AV1739)
* Only suffix methods with `Async` or `TaskAsync` when both synchronous and asynchronous variants exist (AV1755)
**Documentation**
* Write comments and documentation in US English (AV2301)
* Document all `public`, `protected` and `internal` types and members (AV2305)
* Write XML documentation with other developers in mind (AV2306)
* Document the purpose of a member, instead of describing its implementation (AV2308)
* Avoid inline comments (AV2310)
* Only write comments to explain complex algorithms or decisions (AV2316)
|
**Framework**
* Prefer idiomatic C# over .NET Framework APIs (AV2202)
* Build with the highest warning level (AV2210)
* Avoid LINQ query syntax for simple expressions (AV2220)
* Use deconstruction to simplify variable assignments (AV2225)
* Only use the `dynamic` keyword when talking to a dynamic object (AV2230)
**Layout**
* Use a common layout (AV2400)
* Order and group namespaces according to the company (AV2402)
* Place members in a well-defined order (AV2406)
* Do not use `#region` (AV2407)
* Use expression-bodied members appropriately (AV2410)
* Indent 4 spaces, don't use tabs
* Add spaces around operators and after keywords such as `if`
* Keep expression-bodied members on one line when they remain readable
|
|