|
1 | | -author: Jason |
2 | | - |
3 | | -> file encodings! |
4 | | -> performance standards |
5 | | -> platform support |
6 | | -> how to write portable code, tests, UI across platforms |
7 | | -> #ifdef |
8 | | -> note about internal APIs? |
9 | | -> avoid take dependency on code via reflection |
| 1 | + |
| 2 | +# C# Coding Style |
| 3 | + |
| 4 | +## Coding Conventions |
| 5 | + |
| 6 | +As a general rule, our coding convention is to follow the style of the surrounding code. |
| 7 | +Avoid reformatting any code when submitting a PR as it obscures the functional changes of your change. |
| 8 | +We run the [.NET code formatter tool](https://github.com/dotnet/codeformatter) regularly help keep consistent formatting. |
| 9 | + |
| 10 | +A basic rule of formatting is to use "Visual Studio defaults". |
| 11 | +Here are some general guidelines |
| 12 | + |
| 13 | +* No tabs, indent 4 spaces. |
| 14 | +* Braces usually go on their own line, |
| 15 | + with the exception of single line statements that are properly indented. |
| 16 | +* Use `_camelCase` for instance fields, |
| 17 | + use `readonly` where possible. |
| 18 | +* Use of `this` is neither encouraged nor discouraged. |
| 19 | +* Avoid more than one blank empty line. |
| 20 | +* Public members should use [doc comments](https://msdn.microsoft.com/en-us/library/b2s063f7.aspx), |
| 21 | + internal members may use doc comments but it is not enouraged. |
| 22 | +* Public members in a namespace that ends with `Internal`, |
| 23 | + for example `System.Management.Automation.Internal` are not considered a supported public API. |
| 24 | + Such members are necessarily public as implementation details in code shared between C# and PowerShell script, |
| 25 | + or must be available publically by generated code. |
| 26 | +* File encoding should be ASCII (preferred) |
| 27 | + or UTF8 (with BOM) if absolutely necessary. |
| 28 | + |
| 29 | +## Preprocessor defines |
| 30 | + |
| 31 | +There are 3 primary preprocessor macros we define during builds: |
| 32 | + |
| 33 | +* DEBUG - guard code that should not be included in release builds |
| 34 | +* CORECLR - guard code that differs between Full CLR and CoreCLR |
| 35 | +* UNIX - guard code that is specific to Unix (Linux and Mac OS X) |
| 36 | + |
| 37 | +Any other preprocessor defines found in the source are used for one-off custom builds, |
| 38 | +typically to help debug specific scenarios. |
| 39 | + |
| 40 | +### Runtimes |
| 41 | + |
| 42 | +The PowerShell repo is used to build PowerShell targeting CoreCLR as well as CLR 4.5. |
| 43 | + |
| 44 | +Code under !CORECLR must build against CLR 4.5. |
| 45 | +We will not accept changes that require a later version of the full CLR. |
| 46 | +In extremely rare cases, we may use reflection to use an API in a later version of the CLR, |
| 47 | +but the feature must robustly handle running with CLR 4.5. |
| 48 | + |
| 49 | +We may reject code under !CORECLR without explanation because |
| 50 | +we do not support installation or testing of such code in this repo. |
| 51 | +All new features should support CoreCLR. |
| 52 | + |
| 53 | +## Performance considerations |
| 54 | + |
| 55 | +PowerShell has a lot of performance sensitive code as well as a lot of inefficient code. |
| 56 | +We have some guidelines that we typically apply widely even in less important code |
| 57 | +because code and patterns are copied we want certain inefficient code to stay out of the performance critical code. |
| 58 | + |
| 59 | +Some general guidelines: |
| 60 | + |
| 61 | +* Avoid LINQ - it can create lots of avoidable garbage |
| 62 | +* Prefer `for` and `foreach`, |
| 63 | + with a slight preference towards `for` when you're uncertain if `foreach` allocates an iterator. |
| 64 | +* Avoid `params` arrays, prefer adding overloads with 1, 2, 3, and maybe more parameters. |
| 65 | +* Be aware of APIs such as `String.Split(params char[])` that do not provide overloads to avoid array allocation. |
| 66 | + When calling such APIs, reuse a static array when possible. |
| 67 | +* Avoid unnecessary memory allocation in a loop. |
| 68 | + Move the memory allocation outside the loop if possible. |
| 69 | + |
| 70 | +## Portable code |
| 71 | + |
| 72 | +The PowerShell code base started on Windows and depends on many Win32 APIs through P/Invoke. |
| 73 | +Going forward, we try to depend on CoreCLR to handle platform differences, |
| 74 | +so avoid adding new P/Invoke calls where a suitable alternative exists in .NET. |
| 75 | + |
| 76 | +Try to minimize the use of `#if UNIX` and `#if CORECLR`. |
| 77 | +When absolutely necessary, avoid duplicating more code than necessary, |
| 78 | +and instead prefer introducing helper functions to minimize the platform differences. |
| 79 | + |
| 80 | +When adding platform dependent code, prefer preprocessor directives |
| 81 | +over runtime checks. |
0 commit comments