Project: Avro (Orchestration & Management / Remote Procedure Call)
File: STYLING.md

<!-- /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * https://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ --> The following rules are currently used within the .editorconfig of the Avro solution. Any changes to this documentation should be reflected in the .editorconfig file and vice versa. Notes The examples shown are based on the current settings in .editorconfig :exclamation: Not defined :exclamation: means we have not set a preference There are cases where it is not explicitly defined in the .editorconfig, but there is a default option The project currently targets a framework that uses C# 7.3 When violating a formatting rule it may show up as an IDE0055 Fix formatting violation. This rule concerns whether an open brace { should be placed on the same line as the preceding code, or on a new line. Example ``` void MyMethod() { if (...) { ... } } ``` Example ``` if (...) { ... } else { ... } ``` Example ``` try { ... } catch (Exception e) { ... } ``` Example ``` try { ... } catch (Exception e) { ... } finally { ... } ``` Example ``` var z = new B() { A = 3, B = 4 } ``` Example ``` var z = new { A = 3, B = 4 } ``` Example ``` var q = from a in e from b in e select a * b; ``` Example ``` switch(c) { case Color.Red: Console.WriteLine("The color is red"); break; case Color.Blue: Console.WriteLine("The color is blue"); break; default: Console.WriteLine("The color is unknown."); break; } ``` Example ``` switch(c) { case Color.Red: Console.WriteLine("The color is red"); break; case Color.Blue: Console.WriteLine("The color is blue"); break; default: Console.WriteLine("The color is unknown."); break; } ``` Labels are placed at one less indent to the current context Example ``` class C { private string MyMethod(...) { if (...) { goto error; } error: throw new Exception(...); } } ``` Example ``` static void Hello() { Console.WriteLine("Hello"); } ``` Example ``` static void Hello() { Console.WriteLine("Hello"); } ``` Example ``` case 0: { Console.WriteLine("Hello"); break; } ``` Example ``` int y = (int)x; ``` Example ``` for (int i;i<x;i++) { ... } ``` No additional spacing between parentheses Example ``` for (int i;i<x;i++) { ... } ``` Example ``` interface I { } class C : I { } ``` Example ``` interface I { } class C : I { } ``` Insert space before and after the binary operator Example ``` return x * (x - y); ``` Remove space characters after the opening parenthesis and before the closing parenthesis of a method declaration parameter list Example ``` void Bark(int x) {

} ``` Remove space within empty parameter list parentheses for a method declaration Example ``` void Goo() { Goo(1); } void Goo(int x) { Goo(); } ``` Remove space characters between the method name and opening parenthesis in the method declaration Example ``` void M() { } ``` Remove space characters after the opening parenthesis and before the closing parenthesis of a method call Example ``` MyMethod(argument); ``` Remove space within empty argument list parentheses Example ``` void Goo() { Goo(1); } void Goo(int x) { Goo(); } ``` Remove space between method call name and opening parenthesis Example ``` void Goo() { Goo(1); } void Goo(int x) { Goo(); } ``` Insert space before a comma Example ``` int[] x = new int[] { 1 , 2 , 3 , 4 , 5 }; ``` Remove space before a dot Example ``` this.Goo(); ``` Insert space after each semicolon in a for statement Example ``` for (int i = 0; i < x.Length; i++) ``` Remove space before each semicolon in a for statement Example ``` for (int i = 0; i < x.Length; i++) ``` Remove extra space characters in declaration statements Example ``` int x = 0; ``` Remove space before opening square brackets [ Example ``` int[] numbers = new int[] { 1, 2, 3, 4, 5 }; ``` Remove space between empty square brackets [] Example ``` int[] numbers = new int[] { 1, 2, 3, 4, 5 }; ``` Remove space characters in non-empty square brackets [0] Example ``` int index = numbers[0]; ``` Leave statements and member declarations on different lines Example ``` int i = 0; string name = "John"; ``` Leave code block on single line Example ``` public int Foo { get; set; } ``` Prefer using directives to be placed outside the namespace Example ``` using System; namespace Conventions { } ``` :exclamation: Not defined :exclamation: Example ``` // csharpstylenamespacedeclarations = blockscoped using System; namespace Convention { class C { } } // csharpstylenamespacedeclarations = filescoped using System; namespace Convention; class C { } ``` Prefer fields not to be prefaced with this. or Me. Example ``` capacity = 0; ``` Prefer properties not to be prefaced with this. or Me. Example ``` ID = 0; ``` Prefer methods not to be prefaced with this. or Me. Example ``` Display(); ``` Prefer events not to be prefaced with this. or Me. Example ``` Elapsed += Handler; ``` Prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them Example ``` private int _member; ``` public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion Example ``` class MyClass { private static readonly int _daysInYear = 365; } ``` Prefer accessibility modifiers to be declared except for public interface members. default is fornoninterface_members Example ``` class MyClass { private const string thisFieldIsConst = "constant"; } ``` Prefer that private fields should be marked with readonly (C#) or ReadOnly (Visual Basic) if they are only ever assigned inline, or inside of a constructor Example ``` class MyClass { private readonly int _daysInYear = 365; } ``` Prefer local functions to be marked static Example ``` void M() { Hello(); static void Hello() {

} } ``` Prefer parentheses to clarify arithmetic operator (*, /, %, +, -, <<, >>, &, ^, |) precedence Default is alwaysforclarity Example ``` var v = a + (b * c); ``` Prefer parentheses to clarify relational operator (>, <, <=, >=, is, as, ==, !=) precedence Default is alwaysforclarity Example ``` var v = (a < b) == (c > d); ``` Prefer parentheses to clarify other binary operator (&&, ||, ??) precedence Default is alwaysforclarity Example ``` var v = a || (b && c); ``` Prefer to not have parentheses when operator precedence is obvious Default is neverifunnecessary Example ``` var v = a.b.Length; ``` Prefer objects to be initialized using object initializers when possible default is true Example ``` var c = new Customer() { Age = 21 }; ``` Prefer out variables to be declared inline in the argument list of a method call when possible Example ``` if (int.TryParse(value, out int i) {...} ``` Prefer collections to be initialized using collection initializers when possible Example ``` var list = new List<int> { 1, 2, 3 }; ``` Prefer auto properties over properties with private backing fields Example ``` private int Age { get; } ``` Prefer tuple names to ItemX properties Example ``` (string name, int age) customer = GetCustomer(); var name = customer.name; ``` Prefer default over default(T) Example ``` void DoWork(CancellationToken cancellationToken = default) { ... } ``` Prefer inferred tuple element names Example ``` var tuple = (age, name); ``` Prefer inferred anonymous type member names Example ``` var anon = new { age, name }; ``` Prefer anonymous functions over local functions Example ``` Func<int, int> fibonacci = null; fibonacci = (int n) => { return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); }; ``` Prefer deconstructed variable declaration default is true Example ``` var (name, age) = GetPersonTuple(); Console.WriteLine($"{name} {age}"); (int x, int y) = GetPointTuple(); Console.WriteLine($"{x} {y}"); ``` Prefer assignments with a ternary conditional over an if-else statement Example ``` string s = expr ? "hello" : "world"; ``` Prefer return statements to use a ternary conditional over an if-else statement Example ``` return expr ? "hello" : "world" ``` Prefer compound assignment expressions default is true Example ``` x += 1; ``` Prefer simplified conditional expressions default is true Example ``` var result1 = M1() && M2(); var result2 = M1() || M2(); ``` Prefer target-typed new expressions when created type is apparent default is true Example ``` C c = new(); C c2 = new() { Field = 0 }; ``` Prefer to use throw expressions instead of throw statements Example ``` _s = s ?? throw new ArgumentNullException(nameof(s)); ``` Prefer null coalescing expressions to ternary operator checking Example ``` var v = x ?? y; ``` Prefer to use null-conditional operator when possible Example ``` string v = o?.ToString(); ``` Prefer is null check over reference equality method Example ``` if (value is null) return; ``` Prefer to use the conditional coalescing operator (?.) when invoking a lambda expression, instead of performing a null check Example ``` func?.Invoke(args); ``` Prefer explicit type over var to declare variables with built-in system types such as int Example ``` int x = 5; ``` Prefer explicit type over var when the type is already mentioned on the right-hand side of a declaration expression Example ``` Customer obj = new Customer(); ``` Prefer explicit type over var in all cases, unless overridden by another code style rule Example ``` bool f = this.Init(); ``` Prefer expression bodies for constructors Example ``` public Customer(int age) => Age = age; ``` Prefer expression bodies for methods Example ``` public int GetAge() => this.Age; ``` Prefer expression bodies for operators Example ``` public static ComplexNumber operator + (ComplexNumber c1, ComplexNumber c2) => new

+ c2.Real, c1.Imaginary + c2.Imaginary); ``` Prefer expression bodies for properties Example ``` public int Age => _age; ``` Prefer expression bodies for indexers Example ``` public T this[int i] => _values[i]; ``` Prefer expression bodies for accessors Example ``` public int Age { get => age; set => age = value; } ``` Prefer expression bodies for lambdas Example ``` Func<int, int> square = x => x * x; ``` Prefer expression bodies for local functions Example ``` void M() { Hello(); void Hello() => Console.WriteLine("Hello"); } ``` Prefer pattern matching instead of as expressions with null checks to determine if something is of a particular type Example ``` if (o is string s) {...} ``` Prefer pattern matching instead of is expressions with type casts Example ``` if (o is int i) {...} ``` Prefer to use a switch expression (introduced with C# 8.0) Example ``` return x switch { 1 => 1 * 1, 2 => 2 * 2, _ => 0, }; ``` Prefer to use 'not' pattern, when possible (introduced with C# 9.0) Default is true Example ``` var y = o is not C c; ``` Prefer curly braces even for one line of code Example ``` if (test) { this.Display(); } ``` Don't prefer to use a simple using statement Example ``` using (var a = b) { } ``` unset or empty string - Do not require file header. Default is unset Example ``` namespace N2 { class C2 { } } ``` Example ``` public static MyString = "value"; protected static MyString = "value"; internal static MyString = "value"; protected_internal static MyString = "value"; private_protected static MyString = "value";; ``` Example ``` public const string MyConstant = "value"; ``` Example ``` private static int s_myInt; ``` Example ``` private int _myInt; internal string _myString; ``` Example ``` private static string GetText(string path, string filename) { var reader = File.OpenText($"{AppendPathSeparator(path)}{filename}"); var text = reader.ReadToEnd(); return text; string AppendPathSeparator(string filepath) { return filepath.EndsWith(@"\") ? filepath : filepath + @"\"; } } ``` Example ``` private static string GetText(string path, string filename) { var reader = File.OpenText($"{AppendPathSeparator(path)}{filename}"); var text = reader.ReadToEnd(); return text; string AppendPathSeparator(string filepath) { return filepath.EndsWith(@"\") ? filepath : filepath + @"\"; } } ``` Example ``` public void MyMethod() { }; ``` Sort System.* using directives alphabetically, and place them before other using directives. Example ``` using System.Collections.Generic; using System.Threading.Tasks; using Avro; ``` :exclamation: Not defined :exclamation: Example ``` // dotnetseparateimportdirectivegroups = true using System.Collections.Generic; using System.Threading.Tasks; using Avro; // dotnetseparateimportdirectivegroups = false using System.Collections.Generic; using System.Threading.Tasks; using Avro; ``` :exclamation: Not defined :exclamation: Example ``` // dotnetstylenamespacematchfolder = true // file path: Example/Convention/C.cs using System; namespace Example.Convention { class C { } } // dotnetstylenamespacematchfolder = false // file path: Example/Convention/C.cs using System; namespace Example { class C { } } ``` Example ``` using System.IO; class C { // IDE0001: 'System.IO.FileInfo' can be simplified to 'FileInfo' System.IO.FileInfo file; // Fixed code FileInfo file; } ``` Example ``` static void M1() { } static void M2() { // IDE0002: 'C.M1' can be simplified to 'M1' C.M1(); // Fixed code M1(); } ``` Example ``` // Code with violations int v = (int)0; // Fixed code int v = 0; ``` Example ``` // Code with violations using System; using System.IO; // IDE0005: Using directive is unnecessary class C { public static void M() {

} } // Fixed code using System; class C { public static void M() { Console.WriteLine("Hello"); } } ``` Example ``` // Code with violations void M() { throw new System.Exception(); // IDE0035: Remove unreachable code int v = 0; } // Fixed code void M() { throw new System.Exception(); } ``` Example ``` // Code with violations class C { // IDE0051: Remove unused private members private readonly int _fieldPrivate; private int PropertyPrivate => 1; private int GetNumPrivate() => 1; // No IDE0051 internal readonly int FieldInternal; private readonly int _fieldPrivateUsed; public int PropertyPublic => _fieldPrivateUsed; private int GetNumPrivateUsed() => 1; internal int GetNumInternal() => GetNumPrivateUsed(); public int GetNumPublic() => GetNumPrivateUsed(); } // Fixed code class C { // No IDE0051 internal readonly int FieldInternal; private readonly int _fieldPrivateUsed; public int PropertyPublic => _fieldPrivateUsed; private int GetNumPrivateUsed() => 1; internal int GetNumInternal() => GetNumPrivateUsed(); public int GetNumPublic() => GetNumPrivateUsed(); } ``` Example ``` class C { // IDE0052: Remove unread private members private readonly int _field1; private int _field2; private int Property { get; set; } public C() { _field1 = 0; } public void SetMethod() { _field2 = 0; Property = 0; } } // Fixed code class C { public C() { } public void SetMethod() { } } ``` Prefer to assign an unused expression to a discard Default is discard_variable Example ``` _ = System.Convert.ToInt32("35"); ``` Prefer to use a discard when assigning a value that's not used Default is discard_variable Example ``` int GetCount(Dictionary<string, int> wordCount, string searchWord) { _ = wordCount.TryGetValue(searchWord, out var count); return count; } ``` Flag methods with any accessibility that contain unused parameters Default is all Example ``` public int GetNum1(int unusedParam) { return 1; } internal int GetNum2(int unusedParam) { return 1; } private int GetNum3(int unusedParam) { return 1; } ``` enables the rule for all rule IDs and rule categories Default is none Example ``` using System.Diagnostics.CodeAnalysis; class C1 { // 'dotnetremoveunnecessarysuppressionexclusions = IDE0051' // Unnecessary pragma suppression, but not flagged by IDE0079 private int UsedMethod() => 0; public int PublicMethod() => UsedMethod(); } ``` Example ``` // Code with violations if (o !is string) { } // Potential fixes: // 1. if (o is not string) { } // 2. if (!(o is string)) { } // 3. if (o is string) { } ``` Example ``` // Code with violations if (x == true) { } if (M() != false) { } // Fixed code if (x) { } if (M()) { } ``` Example ``` // Code with violations switch (o) { case int _: Console.WriteLine("Value was an int"); break; case string _: Console.WriteLine("Value was a string"); break; } // Fixed code switch (o) { case int: Console.WriteLine("Value was an int"); break; case string: Console.WriteLine("Value was a string"); break; } ``` Example ``` // IDE0076: Invalid target '~F:N.C.F2' - no matching field named 'F2' [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "member", Target = "~F:N.C.F2")] // IDE0076: Invalid scope 'property' [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "property", Target = "~P:N.C.P")] // Fixed code [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "member", Target = "~F:N.C.F")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "member", Target = "~P:N.C.P")] namespace N { class C { public int F; public int P { get; } } } ``` Example ``` // IDE0077: Legacy format target 'N.C.#F' [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "member", Target = "N.C.#F")] // Fixed code [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "member", Target = "~F:N.C.F")] namespace N { class C { public int F; } } ```