Skip to content

Commit f73e0e4

Browse files
committed
Final edit pass
I also caught a couple sample bits that I'd neglected in the previous commit.
1 parent f344c7a commit f73e0e4

File tree

5 files changed

+63
-49
lines changed

5 files changed

+63
-49
lines changed

docs/csharp/fundamentals/coding-style/coding-conventions.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ We chose our conventions based on the following goals:
1919
1. *Adoption*: We aggressively update our samples to use new language features. That practice raises awareness of new features, and makes them more familiar to all C# developers.
2020

2121
> [!IMPORTANT]
22-
> These guidelines are used by Microsoft to develop samples and documentation. They were adopted from the [.NET Runtime, C# Coding Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) and [C# compiler (roslyn)](https://github.com/dotnet/roslyn/blob/main/CONTRIBUTING.md#csharp) guidelines. We chose those guidelines because they have been tested over several years of Open Source development. They've helped community members participate in the runtime and compiler projects. They are meant to be an example of common C# conventions, and not an authoritative list (see [Framework Design Guidelines](../../../standard/design-guidelines/index.md) for that).
22+
> These guidelines are used by Microsoft to develop samples and documentation. They were adopted from the [.NET Runtime, C# Coding Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) and [C# compiler (roslyn)](https://github.com/dotnet/roslyn/blob/main/CONTRIBUTING.md#csharp) guidelines. We chose those guidelines because of their adoption over several years of Open Source development. These guidelines help community members participate in the runtime and compiler projects. They're meant to be an example of common C# conventions, and not an authoritative list (see [Framework Design Guidelines](../../../standard/design-guidelines/index.md) for detailed guidelines).
2323
>
2424
> The *teaching* and *adoption* goals are why the docs coding convention differs from the runtime and compiler conventions. Both the runtime and compiler have strict performance metrics for hot paths. Many other applications don't. Our *teaching* goal mandates that we don't prohibit any construct. Instead, samples show when constructs should be used. We update samples more aggressively than most production applications do. Our *adoption* goal mandates that we show code you should write today, even when code written last year doesn't need changes.
2525
26-
This article explains our guidelines. The guidelines have evolved over time, and you'll find samples that don't follow our guidelines. We welcome PRs that bring those samples into compliance, or issues that draw our attention to samples we should update. Our guidelines are Open Source and we welcome PRs and issues. However, if your submission would change these recommendations, open an issue for discussion first. You're welcome to use our guidelines, or adapt them to your needs.
26+
This article explains our guidelines. The guidelines evolve over time, and you'll find samples that don't follow our guidelines. We welcome PRs that bring those samples into compliance, or issues that draw our attention to samples we should update. Our guidelines are Open Source and we welcome PRs and issues. However, if your submission would change these recommendations, open an issue for discussion first. You're welcome to use our guidelines, or adapt them to your needs.
2727

2828
## Tools and analyzers
2929

30-
Tools can help your team enforce your conventions. You can enable [code analysis](../../../fundamentals/code-analysis/overview.md) to enforce the rules you prefer. You can also create an [editorconfig](/visualstudio/ide/create-portable-custom-editor-options) so that Visual Studio automatically enforces your style guidelines. As a starting point, you can copy the [dotnet/docs repo's file](https://github.com/dotnet/docs/blob/main/.editorconfig) to use our style.
30+
Tools can help your team enforce your conventions. You can enable [code analysis](../../../fundamentals/code-analysis/overview.md) to enforce the rules you prefer. You can also create an [editorconfig](/visualstudio/ide/create-portable-custom-editor-options) so that Visual Studio automatically enforces your style guidelines. As a starting point, you can copy the [`dotnet/docs` *.editorconfig*](https://github.com/dotnet/docs/blob/main/.editorconfig) to use our style.
3131

32-
These tools make it easier for your team to adopt your preferred guidelines. Visual Studio applies the rules in all `.editorconfig` files in scope to format your code. You can use multiple configurations to enforce corporate-wide conventions, team conventions, and even granular project conventions.
32+
These tools make it easier for your team to adopt your preferred guidelines. Visual Studio applies the rules in all *.editorconfig* files in scope to format your code. You can use multiple configurations to enforce corporate-wide conventions, team conventions, and even granular project conventions.
3333

34-
Code analysis produces warnings and diagnostics when the enabled rules are violated. You configure the rules you want applied to your project. Then, each CI build notifies developers when they violate any of the rules.
34+
Code analysis produces warnings and diagnostics when it detects rule are violations. You configure the rules you want applied to your project. Then, each CI build notifies developers when they violate any of the rules.
3535

3636
### Diagnostic IDs
3737

@@ -43,12 +43,12 @@ The following sections describe practices that the .NET docs team follows to pre
4343

4444
- Utilize modern language features and C# versions whenever possible.
4545
- Avoid outdated language constructs.
46-
- Only catch exceptions that can be properly handled; avoid catching general exceptions. For example, sample code should not catch the <xref:System.Exception?displayProperty=fullName> type without an exception filter.
46+
- Only catch exceptions that can be properly handled; avoid catching general exceptions. For example, sample code shouldn't catch the <xref:System.Exception?displayProperty=fullName> type without an exception filter.
4747
- Use specific exception types to provide meaningful error messages.
4848
- Use LINQ queries and methods for collection manipulation to improve code readability.
4949
- Use asynchronous programming with async and await for I/O-bound operations.
5050
- Be cautious of deadlocks and use <xref:System.Threading.Tasks.Task.ConfigureAwait%2A?DisplayProperty=nameWithType> when appropriate.
51-
- Use the language keywords for data types instead of the runtime types. For example, use `string` instead of <xref:System.String?DisplayProperty=fullName>, or `int` instead of <xref:System.Int32?displayProperty=fullName>. This includes using the types `nint` and `nuint`.
51+
- Use the language keywords for data types instead of the runtime types. For example, use `string` instead of <xref:System.String?DisplayProperty=fullName>, or `int` instead of <xref:System.Int32?displayProperty=fullName>. This recommendation includes using the types `nint` and `nuint`.
5252
- Use `int` rather than unsigned types. The use of `int` is common throughout C#, and it's easier to interact with other libraries when you use `int`. Exceptions are for documentation specific to unsigned data types.
5353
- Use `var` only when a reader can infer the type from the expression. Readers view our samples on the docs platform. They don't have hover or tool tips that display the type of variables.
5454
- Write code with clarity and simplicity in mind.
@@ -67,16 +67,21 @@ More specific guidelines follow.
6767
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet7":::
6868

6969
- Prefer raw string literals to escape sequences or verbatim strings.
70+
71+
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="rawStringLiterals":::
72+
7073
- Use the expression based string interpolation rather than positional string interpolation.
7174

75+
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="interpolatedStrings":::
76+
7277
### Constructors and initialization
7378

7479
- Use Pascal case for primary constructor parameters on record types:
7580

7681
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="PrimaryRecord":::
7782

7883
- Use camel case for primary constructor parameters on class and struct types:
79-
- Prefer required `init` properties to constructors to initialize fields.
84+
- Use `required` properties instead of constructors to force initialization of property values.
8085

8186
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="PrimaryClass":::
8287

@@ -170,7 +175,7 @@ The lambda expression shortens the following traditional definition.
170175

171176
### Static members
172177

173-
Call [static](../../language-reference/keywords/static.md) members by using the class name: *ClassName.StaticMember*. This practice makes code more readable by making static access clear. Don't qualify a static member defined in a base class with the name of a derived class. While that code compiles, the code readability is misleading, and the code may break in the future if you add a static member with the same name to the derived class.
178+
Call [static](../../language-reference/keywords/static.md) members by using the class name: *ClassName.StaticMember*. This practice makes code more readable by making static access clear. Don't qualify a static member defined in a base class with the name of a derived class. While that code compiles, the code readability is misleading, and the code might break in the future if you add a static member with the same name to the derived class.
174179

175180
### LINQ queries
176181

@@ -196,7 +201,7 @@ Call [static](../../language-reference/keywords/static.md) members by using the
196201

197202
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet29":::
198203

199-
- Use multiple `from` clauses instead of a [`join`](../../language-reference/keywords/join-clause.md) clause to access inner collections. For example, a collection of `Student` objects might each contain a collection of test scores. When the following query is executed, it returns each score that is over 90, along with the last name of the student who received the score.
204+
- Access inner collections with multiple `from` clauses instead of a [`join`](../../language-reference/keywords/join-clause.md) clause. For example, a collection of `Student` objects might each contain a collection of test scores. When the following query is executed, it returns each score that is over 90, along with the family name of the student who received the score.
200205

201206
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet30":::
202207

@@ -206,7 +211,7 @@ Call [static](../../language-reference/keywords/static.md) members by using the
206211

207212
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet8":::
208213

209-
- Don't use [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) when the type isn't apparent from the right side of the assignment. Don't assume the type is clear from a method name. A variable type is considered clear if it's a `new` operator, an explicit cast or assignment to a literal value.
214+
- Don't use [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) when the type isn't apparent from the right side of the assignment. Don't assume the type is clear from a method name. A variable type is considered clear if it's a `new` operator, an explicit cast, or assignment to a literal value.
210215

211216
:::code language="csharp" source="./snippets/coding-conventions/program.cs" id="Snippet9":::
212217

@@ -231,10 +236,18 @@ Call [static](../../language-reference/keywords/static.md) members by using the
231236
- use implicit type for the result sequences in LINQ queries. The section on [LINQ](#linq-queries) explains that many LINQ queries result in anonymous types where implicit types must be used. Other queries result in nested generic types where `var` is more readable.
232237

233238
> [!NOTE]
234-
> Be careful not to accidentally change a type of an element of the iterable collection. For example, it is easy to switch from <xref:System.Linq.IQueryable?displayProperty=nameWithType> to <xref:System.Collections.IEnumerable?displayProperty=nameWithType> in a `foreach` statement, which changes the execution of a query.
239+
> Be careful not to accidentally change a type of an element of the iterable collection. For example, it's easy to switch from <xref:System.Linq.IQueryable?displayProperty=nameWithType> to <xref:System.Collections.IEnumerable?displayProperty=nameWithType> in a `foreach` statement, which changes the execution of a query.
235240
236241
Some of our samples explain the *natural type* of an expression. Those samples must use `var` so that the compiler picks the natural type. Even though those examples are less obvious, the use of `var` is required for the sample. The text should explain the behavior.
237242

243+
### File scoped namespace declarations
244+
245+
Most code files declare a single namespace. Therefore, our examples should use the file scoped namespace declarations:
246+
247+
```csharp
248+
namespace MySampleCode;
249+
```
250+
238251
### Place the using directives outside the namespace declaration
239252

240253
When a `using` directive is outside a namespace declaration, that imported namespace is its fully qualified name. The fully qualified name is clearer. When the `using` directive is inside the namespace, it could be either relative to that namespace, or its fully qualified name.
@@ -282,7 +295,7 @@ And it compiles today. And tomorrow. But then sometime next week the preceding (
282295
- error CS0103: The name 'WaitUntil' does not exist in the current context
283296
```
284297

285-
One of the dependencies has introduced this class in a namespace then ends with `.Azure`:
298+
One of the dependencies introduced this class in a namespace then ends with `.Azure`:
286299

287300
```csharp
288301
namespace CoolStuff.Azure
@@ -325,14 +338,14 @@ In general, use the following format for code samples:
325338
- Use four spaces for indentation. Don't use tabs.
326339
- Align code consistently to improve readability.
327340
- Limit lines to 65 characters to enhance code readability on docs, especially on mobile screens.
328-
- Break long statements into multiple lines to improve clarity.
341+
- Improve clarity and user experience by breaking long statements into multiple lines.
329342
- Use the "Allman" style for braces: open and closing brace its own new line. Braces line up with current indentation level.
330343
- Line breaks should occur before binary operators, if necessary.
331344

332345
### Comment style
333346

334347
- Use single-line comments (`//`) for brief explanations.
335-
- Avoid multi-line comments (`/* */`) for longer explanations.<br/>Comments in the code samples aren't localized. That means explanations embedded in the code will not be translated. Longer, explanatory text should be placed in the companion article, so that it can be localized.
348+
- Avoid multi-line comments (`/* */`) for longer explanations.<br/>Comments in the code samples aren't localized. That means explanations embedded in the code aren't translated. Longer, explanatory text should be placed in the companion article, so that it can be localized.
336349
- For describing methods, classes, fields, and all public members use [XML comments](../../language-reference/xmldoc/index.md).
337350
- Place the comment on a separate line, not at the end of a line of code.
338351
- Begin comment text with an uppercase letter.

docs/csharp/fundamentals/coding-style/snippets/coding-conventions/program.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,22 @@ where score > 90
374374
select new { Last = student.LastName, score };
375375
//</snippet30>
376376

377+
// <interpolatedStrings>
377378
// Execute the queries.
378379
Console.WriteLine("scoreQuery:");
379380
foreach (var student in scoreQuery)
380381
{
381382
Console.WriteLine($"{student.Last} Score: {student.score}");
382383
}
384+
// </interpolatedStrings>
385+
386+
// <rawStringLiterals>
387+
var message = """
388+
This is a long message that spans across multiple lines.
389+
It uses raw string literals. This means we can
390+
also include characters like \n and \t without escaping them.
391+
""";
392+
// </rawStringLiterals>
383393
}
384394
}
385395
}

0 commit comments

Comments
 (0)