Skip to content

Commit

Permalink
Changed rule references into hyperlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisdoomen committed Aug 3, 2019
1 parent 2b4ded9 commit 7a66f74
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 20 deletions.
5 changes: 5 additions & 0 deletions Build/default.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,17 @@ task Compile {
$content = $content.replace('%commitdate%', $script:CommitDate)
$content = $content.replace('![](/assets', '![](assets')

# Extract the title of the section from the Frontmatter block
if ($content -match "---(.|\n)*title\: (.+)") {
$title = $Matches[2]
}

# Remove the entire Frontmatter block
$content = ($content -replace '---\r?\n(.|\r?\n)+?---\r?\n', "")

# Replace cross-page relative links with local links (since everything becomes a single HTML)
$content = ($content -replace '\(\/.+?(#av\d+)\)', '($1)')

if ($title) {
$content = "<h1>$title</h1>" + $content;
}
Expand Down
10 changes: 5 additions & 5 deletions _includes/0001_Introduction.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## 1.1. What is this?

This document attempts to provide guidelines (or coding standards if you like) for coding in C# 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 7.1, 7.2 or 7.3 that are both useful and pragmatic. Of course, if you create such a document you should practice what you preach. So rest assured, these guidelines are representative to what we at [Aviva Solutions](http://www.avivasolutions.nl) do in our day-to-day work. Notice that not all guidelines have a clear rationale. Some of them are simply choices we made at Aviva Solutions. In the end, it doesn't matter what choice you made, as long as you make one and apply it consistently.
This document attempts to provide guidelines (or coding standards if you like) for all versions of C# up to and including that are both valuable and pragmatic. Of course, if you create such a document you should practice what you preach. So rest assured, these guidelines are representative to what we at [Aviva Solutions](https://www.avivasolutions.nl) do in our day-to-day work. Notice that not all guidelines have a clear rationale. Some of them are simply choices we made at Aviva Solutions. In the end, it doesn't matter what choice you made, as long as you make one and apply it consistently.

## 1.2. Why would you use this document?

Although some might see coding guidelines as undesired overhead or something that limits creativity, this approach has already proven its value for many years. This is because not every developer:

- is aware that code is generally read 10 times more than it is changed;
- is aware of the potential pitfalls of certain constructions in C#;
- is up to speed on certain conventions when using the .NET Framework such as `IDisposable` or the deferred execution nature of LINQ;
- is up to speed on certain conventions when using the .NET Framework such as `IDisposable`, `async`/`await`, or the deferred execution nature of LINQ;
- is aware of the impact of using (or neglecting to use) particular solutions on aspects like security, performance, multi-language support, etc;
- realizes that not every developer is as capable, skilled or experienced to understand elegant, but potentially very abstract solutions;

Expand All @@ -33,13 +33,13 @@ Regardless of the elegance of someone's solution, if it's too complex for the or
- Make sure there are always a few hard copies of the [Cheat Sheet](https://github.com/dennisdoomen/CSharpGuidelines/releases/latest) close at hand.
- Include the most critical coding guidelines on your [Project Checklist](https://www.continuousimprover.com/2010/03/alm-practices-5-checklists.html) and verify the remainder as part of your [Peer Review](https://www.continuousimprover.com/2010/02/tfs-development-practices-part-2-peer.html).
- Consider forking the [original sources](https://github.com/dennisdoomen/csharpguidelines) on [GitHub](https://github.com/) and create your own [internal](https://github.com/dennisdoomen/csharpguidelines/blob/master/LICENSE.md) version of the document.
- [ReSharper](http://www.jetbrains.com/resharper/) has an intelligent code inspection engine that, with some configuration, already supports many aspects of the Coding Guidelines. It automatically highlights any code that does not match the rules for naming members (e.g. Pascal or Camel casing), detects dead code, and many other things. One click of the mouse button (or the corresponding keyboard shortcut) is usually enough to fix it.
- Jetbrain's [ReSharper](http://www.jetbrains.com/resharper/) and their fully fledged Visual Studio replacement [Rider](https://www.jetbrains.com/rider/), has an intelligent code inspection engine that, with some configuration, already supports many aspects of the Coding Guidelines. It automatically highlights any code that does not match the rules for naming members (e.g. Pascal or Camel casing), detects dead code, and many other things. One click of the mouse button (or the corresponding keyboard shortcut) is usually enough to fix it.
- ReSharper also has a File Structure window that displays an overview of the members of your class or interface, and allows you to easily rearrange them using a simple drag-and-drop action.
- [CSharpGuidelinesAnalyzer](https://github.com/bkoelman/CSharpGuidelinesAnalyzer) verifies over 40 of our guidelines, while typing code in Visual Studio 2017 and during CI builds. An updated Resharper settings file is included.

## 1.5. Why did we create it?

The idea started in 2002 when Vic Hartog (Philips Medical Systems) and I were assigned the task of writing up a [coding standard](http://www.tiobe.com/content/paperinfo/gemrcsharpcs.pdf) for C# 1.0. Since then, I've regularly added, removed and changed rules based on experiences, feedback from the community and new tooling support offered by a continuous stream of new Visual Studio releases.
The idea started in 2002 when Vic Hartog (Philips Medical Systems) and I were assigned the task of writing up a [coding standard](http://www.tiobe.com/content/paperinfo/gemrcsharpcs.pdf) for C# 1.0. Since then, I've regularly added, removed and changed rules based on experiences, feedback from the community and new tooling support offered by a continuous stream of new developments in the .NET ecosystem. Special thanks go to [Bart Koelman](https://github.com/bkoelman) for being a very active contributor over all those years.

Additionally, after reading [Robert C. Martin](https://sites.google.com/site/unclebobconsultingllc/)'s book [Clean Code: A Handbook of Agile Software Craftsmanship](http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882), I became a big fan of his ideas and decided to include some of his smells and heuristics as guidelines. Notice though, that this document is in no way a replacement for his book. I sincerely recommend that you read his book to gain a solid understanding of the rationale behind his recommendations.

Expand All @@ -59,7 +59,7 @@ To help you in this decision, I've assigned a level of importance to each guidel

## 1.7. Feedback and disclaimer

This document has been compiled using many contributions from community members, blog posts, on-line discussions and many years of developing in C#. If you have questions, comments or suggestions, just let me know by sending me an email at [[email protected]](mailto:[email protected]), [creating an issue](https://github.com/dennisdoomen/csharpguidelines/issues) or Pull Request on GitHub, or ping me at [http://twitter.com/ddoomen](http://twitter.com/ddoomen). I will try to revise and republish this document with new insights, experiences and remarks on a regular basis.
This document has been compiled using many contributions from community members, blog posts, on-line discussions and two decades of developing in C#. If you have questions, comments or suggestions, just let me know by sending me an email at [[email protected]](mailto:[email protected]), [creating an issue](https://github.com/dennisdoomen/csharpguidelines/issues) or Pull Request on GitHub, ping me at [http://twitter.com/ddoomen](http://twitter.com/ddoomen) or join the [Gitter discussions](https://gitter.im/dennisdoomen/CSharpGuidelines). I will try to revise and republish this document with new insights, experiences and remarks on a regular basis.

Notice though that it merely reflects my view on proper C# code so Aviva Solutions will not be liable for any direct or indirect damages caused by applying the guidelines of this document. This document is published under a Creative Commons license, specifically the [Creative Commons Attribution-ShareAlike 4.0](http://creativecommons.org/licenses/by-sa/4.0/) license.

Expand Down
4 changes: 2 additions & 2 deletions _pages/1000_ClassDesignGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ A class or interface should have a single purpose within the system it functions

### <a name="av1001"></a> Only create a constructor that returns a useful object (AV1001) ![](/assets/images/3.png)

There should be no need to set additional properties before the object can be used for whatever purpose it was designed. However, if your constructor needs more than three parameters (which violates AV1561), your class might have too much responsibility (and violates AV1000).
There should be no need to set additional properties before the object can be used for whatever purpose it was designed. However, if your constructor needs more than three parameters (which violates [AV1561](/maintainability-guidelines#av1561)), your class might have too much responsibility (and violates [AV1000](#av1000)).

### <a name="av1003"></a> An interface should be small and focused (AV1003) ![](/assets/images/2.png)

Expand Down Expand Up @@ -106,7 +106,7 @@ This means that two classes know about each other's public members or rely on ea

### <a name="av1025"></a> Classes should have state and behavior (AV1025) ![](/assets/images/1.png)

In general, if you find a lot of data-only classes in your code base, you probably also have a few (static) classes with a lot of behavior (see AV1008). Use the principles of object-orientation explained in this section and move the logic close to the data it applies to.
In general, if you find a lot of data-only classes in your code base, you probably also have a few (static) classes with a lot of behavior (see [AV1008](#av1008)). Use the principles of object-orientation explained in this section and move the logic close to the data it applies to.

**Exception:** The only exceptions to this rule are classes that are used to transfer data over a communication channel, also called [Data Transfer Objects](http://martinfowler.com/eaaCatalog/dataTransferObject.html), or a class that wraps several parameters of a method.

Expand Down
2 changes: 1 addition & 1 deletion _pages/1100_MemberDesignGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This violation is often seen in domain models and introduces all kinds of condit

### <a name="av1115"></a> A property, method or local function should do only one thing (AV1115) ![](/assets/images/1.png)

Similarly to rule AV1000, a method body should have a single responsibility.
Similarly to rule [AV1000](/class-design-guidelines#av1000), a method body should have a single responsibility.

### <a name="av1125"></a> Don't expose stateful objects through static members (AV1125) ![](/assets/images/2.png)

Expand Down
6 changes: 3 additions & 3 deletions _pages/1500_MaintainabilityGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ For example:
}

### <a name="av1540"></a> Be reluctant with multiple `return` statements (AV1540) ![](/assets/images/2.png)
One entry, one exit is a sound principle and keeps control flow readable. However, if the method body is very small and complies with guideline AV1500 then multiple return statements may actually improve readability over some central boolean flag that is updated at various points.
One entry, one exit is a sound principle and keeps control flow readable. However, if the method body is very small and complies with guideline [AV1500](#av1500) then multiple return statements may actually improve readability over some central boolean flag that is updated at various points.

### <a name="av1545"></a> Don't use an `if`-`else` construct instead of a simple (conditional) assignment (AV1545) ![](/assets/images/2.png)
Express your intentions directly. For example, rather than:
Expand Down Expand Up @@ -367,15 +367,15 @@ The class `MyString` provides three overloads for the `IndexOf` method, but two
**Important:** If you also want to allow derived classes to override these methods, define the most complete overload as a non-private `virtual` method that is called by all overloads.

### <a name="av1553"></a> Only use optional arguments to replace overloads (AV1553) ![](/assets/images/1.png)
The only valid reason for using C# 4.0's optional arguments is to replace the example from rule AV1551 with a single method like:
The only valid reason for using C# 4.0's optional arguments is to replace the example from rule [AV1551](#av1551) with a single method like:

public virtual int IndexOf(string phrase, int startIndex = 0, int count = -1)
{
int length = (count == -1) ? (someText.Length - startIndex) : count;
return someText.IndexOf(phrase, startIndex, length);
}

If the optional parameter is a reference type then it can only have a default value of `null`. But since strings, lists and collections should never be `null` according to rule AV1135, you must use overloaded methods instead.
If the optional parameter is a reference type then it can only have a default value of `null`. But since strings, lists and collections should never be `null` according to rule [AV1135](/member-design-guidelines#av1135), you must use overloaded methods instead.

**Note:** The default values of the optional parameters are stored at the caller side. As such, changing the default value without recompiling the calling code will not apply the new default value.

Expand Down
4 changes: 2 additions & 2 deletions _pages/1700_NamingGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ For example, use `ButtonOnClick` rather than `BtnOnClick`. Avoid single characte
For example, the name IComponent uses a descriptive noun, ICustomAttributeProvider uses a noun phrase and IPersistable uses an adjective.
Bad examples include `SearchExamination` (a page to search for examinations), `Common` (does not end with a noun, and does not explain its purpose) and `SiteSecurity` (although the name is technically okay, it does not say anything about its purpose).

Don't include terms like `Utility` or `Helper` in classes. Classes with names like that are usually static classes and are introduced without considering object-oriented principles (see also AV1008).
Don't include terms like `Utility` or `Helper` in classes. Classes with names like that are usually static classes and are introduced without considering object-oriented principles (see also [AV1008](/member-design-guidelines#av1008)).

### <a name="av1709"></a> Name generic type parameters with descriptive names (AV1709) ![](/assets/images/2.png)
- Always prefix type parameter names with the letter `T`.
Expand Down Expand Up @@ -104,7 +104,7 @@ Although technically correct, statements like the following can be confusing:
### <a name="av1720"></a> Name methods and local functions using verbs or verb-object pairs (AV1720) ![](/assets/images/2.png)
Name a method or local function using a verb like `Show` or a verb-object pair such as `ShowDialog`. A good name should give a hint on the *what* of a member, and if possible, the *why*.

Also, don't include `And` in the name of a method or local function. That implies that it is doing more than one thing, which violates the Single Responsibility Principle explained in AV1115.
Also, don't include `And` in the name of a method or local function. That implies that it is doing more than one thing, which violates the Single Responsibility Principle explained in [AV1115](/member-design-guidelines#av1115).

### <a name="av1725"></a> Name namespaces using names, layers, verbs and features (AV1725) ![](/assets/images/3.png)
For instance, the following namespaces are good examples of that guideline.
Expand Down
4 changes: 2 additions & 2 deletions _pages/1800_PerformanceGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
### <a name="av1800"></a> Consider using `Any()` to determine whether an `IEnumerable<T>` is empty (AV1800) ![](/assets/images/3.png)
When a member or local function returns an `IEnumerable<T>` or other collection class that does not expose a `Count` property, use the `Any()` extension method rather than `Count()` to determine whether the collection contains items. If you do use `Count()`, you risk that iterating over the entire collection might have a significant impact (such as when it really is an `IQueryable<T>` to a persistent store).

**Note:** If you return an `IEnumerable<T>` to prevent changes from calling code as explained in AV1130, and you're developing in .NET 4.5 or higher, consider the new read-only classes.
**Note:** If you return an `IEnumerable<T>` to prevent changes from calling code as explained in [AV1130](/member-design-guidelines#av1130), and you're developing in .NET 4.5 or higher, consider the new read-only classes.

### <a name="av1820"></a> Only use `async` for low-intensive long-running activities (AV1820) ![](/assets/images/1.png)
The usage of `async` won't automagically run something on a worker thread like `Task.Run` does. It just adds the necessary logic to allow releasing the current thread, and marshal the result back on that same thread if a long-running asynchronous operation has completed. In other words, use `async` only for I/O bound operations.
Expand All @@ -19,7 +19,7 @@ The usage of `async` won't automagically run something on a worker thread like `
If you do need to execute a CPU bound operation, use `Task.Run` to offload the work to a thread from the Thread Pool. Remember that you have to marshal the result back to your main thread manually.

### <a name="av1830"></a> Beware of mixing up `async`/`await` with `Task.Wait` (AV1830) ![](/assets/images/1.png)
`await` does not block the current thread but simply instructs the compiler to generate a state-machine. However, `Task.Wait` blocks the thread and may even cause deadlocks (see AV1835).
`await` does not block the current thread but simply instructs the compiler to generate a state-machine. However, `Task.Wait` blocks the thread and may even cause deadlocks (see [AV1835](#av1835)).

### <a name="av1835"></a> Beware of `async`/`await` deadlocks in single-threaded environments (AV1835) ![](/assets/images/1.png)
Consider the following asynchronous method:
Expand Down
Loading

0 comments on commit 7a66f74

Please sign in to comment.