Codebeispiele zu den Regeln aus der .editorconfig
In der .editorconfig sind Regeln definiert, um den Code aller Add-ons im selben Stil zu erzwingen. Diese Richtlinien stellen sicher, dass der Quellcode unabhängig vom Entwickler einheitlich, gut lesbar und leicht wartbar bleibt. Sie folgen den Prinzipien von Clean Code (Lesbarkeit vor Kürze, klare Struktur, minimale Überraschungen) und unterstützen automatisierte Codeanalyse-Tools dabei, formale Verstöße frühzeitig zu erkennen. Dadurch bleibt der Code über die Add-on-Repositories hinaus konsistent, wartbar und leichter zu reviewen.
Wie lese ich dieses Dokument?
- In jeder Überschrift wird die Regel benannt und auch angegeben, ob es eine von Microsoft definierte Regel ist.
- Zusätzlich folgen Klammern mit dem Hinweis, ob die Regel ein Warning durch den Compiler erzeugt oder nur als Anmerkung von der IDE im Code angezeigt wird.
- Es folgen die Regeln aus der .editorconfig.
- Als Abschluss folgt ein Beispiel, wie der Code-Stil aussehen muss oder sollte.
TBD Regeln nochmal prüfen
1) Klammern setzen (IDE0047/IDE0048, warning)
Regeln: IDE0047, IDE0048 → konsequente Leerzeichen/Klammern.
✅ Do
if (isReady)
{
DoWork();
}
for (int i = 0; i < n; i++)
{
Sum += i;
}
❌ Don't
if(isReady){
DoWork(); }
for(int i=0;i<n;i++){ Sum+=i; }
2) Modifier-Reihenfolge (IDE0036, warning)
Regel: csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async
✅ Do
public sealed class MailSender { }
private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);
public override async Task SendAsync() { /* ... */ }
❌ Don't
sealed public class MailSender { }
static private readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);
async override public Task SendAsync() { /* ... */ }
3) this.-Qualifikation vermeiden (warning)
Regeln: dotnet_style_qualification_for_* = false
✅ Do
class Counter
{
private int _value;
public int Value => _value;
public void Inc() { _value++; }
}
❌ Don't
class Counter
{
private int _value;
public int Value => this._value;
public void Inc() { this._value++; }
}
4) var-Präferenz (suggestion)
Regeln: csharp_style_var_* = true
✅ Do
var count = 0; // built-in type
var dict = new Dictionary<string, int>(); // Typ aus RHS ersichtlich
❌ Don't
int count = 0;
Dictionary<string, int> dict = new Dictionary<string, int>();
5) Vordefinierte Typen verwenden (suggestion)
Regeln: dotnet_style_predefined_type_for_* = true
✅ Do
int n = 5;
string s = DateTime.Now.ToString();
❌ Don't
Int32 n = 5;
String s = DateTime.Now.ToString();
6) Zugriffsmodifizierer angeben (suggestion)
Regel: dotnet_style_require_accessibility_modifiers = for_non_interface_members
✅ Do
public class Foo
{
public void Do() { }
private void Helper() { }
}
❌ Don't
public class Foo
{
void Do() { } // implizit 'private' → unklar
void Helper() { }
}
7) Klammer-Präferenzen (nur Stil, none)
Regeln: dotnet_style_parentheses_in_*
✅ Do
var x = a + b * c; // keine unnötigen Klammern
var y = (high && low) || ok; // bei Bedarf zur Klarheit
❌ Don't
var x = (a + (b * c));
var y = ((high && low) || ok);
8) Ausdruckskörper nur, wenn einzeilig (suggestion)
suggestion)Regeln: csharp_style_expression_bodied_* = when_on_single_line, IDE0022 = none
✅ Do
public string FullName => $"{First} {Last}";
public override string ToString() => $"{Id}:{Name}";
❌ Don't
public string FullName
=> $"{First} {Last}"
// mehrzeilig – hier besser Block verwenden
;
9) Pattern Matching & is not (suggestion)
Regeln: csharp_style_pattern_matching_over_as_with_null_check = true, csharp_style_prefer_not_pattern = true
✅ Do
if (obj is Customer c && c.IsActive)
{
Process(c);
}
if (item is not null)
{
Use(item);
}
❌ Don't
var c = obj as Customer;
if (c != null && c.IsActive) { Process(c); }
if (!(item is null)) { Use(item); }
10) switch-Expression bevorzugen (suggestion)
Regel: csharp_style_prefer_switch_expression = true
✅ Do
string Map(int code) => code switch
{
200 => "OK",
404 => "NotFound",
_ => "Other"
};
❌ Don't
string Map(int code)
{
switch (code)
{
case 200: return "OK";
case 404: return "NotFound";
default: return "Other";
}
}
11) Objekt-/Collection-Initialisierer (suggestion)
Regeln: dotnet_style_object_initializer = true, dotnet_style_collection_initializer = true
✅ Do
var person = new Person { FirstName = "Ada", LastName = "Lovelace" };
var list = new List<int> { 1, 2, 3 };
❌ Don't
var person = new Person();
person.FirstName = "Ada";
person.LastName = "Lovelace";
var list = new List<int>();
list.Add(1); list.Add(2); list.Add(3);
12) readonly dort, wo möglich (warning)
Regel: dotnet_style_readonly_field = true
✅ Do
public class Repo
{
private readonly IClock _clock;
public Repo(IClock clock) => _clock = clock;
}
❌ Don't
public class Repo
{
private IClock _clock; // könnte readonly sein
public Repo(IClock clock) => _clock = clock;
}
13) Using-Sortierung & Platzierung (IDE0065, warning)
Regeln: dotnet_sort_system_directives_first = true, csharp_using_directive_placement = outside_namespace
✅ Do
using System;
using System.Collections.Generic;
namespace MyCompany.Tools
{
public class X { }
}
❌ Don't
namespace MyCompany.Tools
{
using System;
using System.Collections.Generic;
public class X { }
}
14) Newlines & Braces (SA15xx-Ersatz, IDE0011 warning)
Regeln:
csharp_new_line_before_open_brace = allcsharp_new_line_between_query_expression_clauses = truecsharp_preserve_single_line_* = falsecsharp_prefer_braces = true/IDE0011 = warning
✅ Do
if (ok)
{
var q =
from x in items
where x > 0
select x;
}
❌ Don't
if (ok) var q = from x in items where x > 0 select x; // einzeilig & ohne Braces
15) Objekt-Initialisierer: keine Leerzeile zwischen Membern
Regel: csharp_new_line_before_members_in_object_initializers = false
✅ Do
var cfg = new Config
{
Url = "https://example",
Timeout = 30
};
❌ Don't
var cfg = new Config
{
Url = "https://example",
Timeout = 30
};
16) Naming: const → PascalCase (warning)
Regeln: const_fields → pascal_case
✅ Do
public const int DefaultPort = 443;
private const string CompanyName = "Contoso";
❌ Don't
public const int DEFAULT_PORT = 443;
private const string company_name = "Contoso";
17) Naming: private Felder _camelCase (warning)
Regeln: private_fields → camel_with_underscore
✅ Do
public class Service
{
private readonly IRepository _repo;
private int _counter;
public Service(IRepository repo) => _repo = repo;
}
❌ Don't
public class Service
{
private readonly IRepository repository;
private int Counter;
}
18) Naming: static readonly → PascalCase (Ausnahme, warning)
Regeln: static readonly fields → pascal_case
✅ Do
public class RateLimiter
{
public static readonly TimeSpan DefaultWindow = TimeSpan.FromSeconds(10);
}
❌ Don't
public class RateLimiter
{
public static readonly TimeSpan _defaultWindow = TimeSpan.FromSeconds(10);
}
19) Editor-/Whitespace-Defaults (projektweit)
Regeln (Auszug): end_of_line = crlf, indent_style = space, indent_size = 4, trim_trailing_whitespace = true, insert_final_newline = false
➡️ Wirkung: Konsistente Einrückung/Zeilenenden; keine Leerraumreste; keine finale Leerzeile erzwingen. Kein Codebeispiel erforderlich.
20) Formats für XML/MD/YML/Projektdateien
Regeln: spezifische indent_size (2) für *.xml/*.config/*.csproj/*.md/*.yml etc.
➡️ Wirkung: Dateityp-spezifische Einrückung; Codebeispiele nicht relevant.
21) Roslynator & ReSharper-Flags
RCS1194 = none→ Meldung deaktiviert.- Diverse
resharper_*Formatierungspräferenzen (Zeilenumbrüche, Wrap-Stile).
➡️ Wirkung: IDE-Formatierung/Inspektionen; keine C#-Semantik – Codebeispiel entbehrlich.
Kurznotizen für Reviewer
- Konsistenz ist wichtiger als persönlicher Geschmack:
var, Braces, Using-Platzierung und Naming sind verbindlich. - C#-Features: Switch-Expression & Pattern-Matching sind erlaubt; Ausdruckskörper nur einzeilig.
- Naming-Ausnahme bewusst:
static readonlyin PascalCase (z. B.DefaultWindow).