Table of Contents

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?

  1. In jeder Überschrift wird die Regel benannt und auch angegeben, ob es eine von Microsoft definierte Regel ist.
  2. 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.
  3. Es folgen die Regeln aus der .editorconfig.
  4. 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)

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 = all
  • csharp_new_line_between_query_expression_clauses = true
  • csharp_preserve_single_line_* = false
  • csharp_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 readonly in PascalCase (z. B. DefaultWindow).