Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
coding-guidelines.md234 linesDownload Raw Back to dev-process
1# C# Coding Guidelines2 3## Coding Conventions4 5As a general rule, our coding convention is to follow the style of the surrounding code.6So if a file happens to differ in style from conventions defined here7(e.g. private members are named `m_member` rather than `_member`),8the existing style in that file takes precedence.9 10When making changes, you may find some existing code goes against the conventions defined here.11In such cases, please avoid reformatting any existing code when submitting a PR as it obscures the functional changes of the PR.12A separate PR should be submitted for style-only changes.13We also run the [.NET code formatter tool](https://github.com/dotnet/codeformatter) regularly to keep consistent formatting.14 15### Naming Conventions16 17* Use meaningful, descriptive words for names.18  For method names, it's encouraged to use `VerbObject` pair such as **`LoadModule`**.19 20* Use `_camelCase` to name internal and private fields and use `readonly` where possible.21  Prefix instance fields with `_`, static fields with `s_` and thread static fields with `t_`.22  When used on static fields, `readonly` should come after `static` (i.e. `static readonly` not `readonly static`).23 24* Use `camelCase` to name non-constant local variables.25 26* Use `PascalCase` to name constant local variables and fields.27  The only exception is for interop code where the constant should exactly match the name and value of the code you are calling via interop (e.g. `const int ERROR_SUCCESS = 0`).28 29* Use `PascalCase` to name types and all other type members.30 31### Layout Conventions32 33* Use four spaces of indentation (no tabs).34 35* Avoid more than one blank empty line at any time.36 37* Avoid trailing spaces at the end of a line.38 39* Braces usually go on their own lines,40  with the exception of single line statements that are properly indented.41 42* Namespace imports should be specified at the top of the file,43  outside of `namespace` declarations.44 45* Fields should be specified at the top within type declarations.46  For those that serve as backing fields for properties,47  they should be specified next to the corresponding properties.48 49* Preprocessor directives like `#if` and `#endif` should be placed at the beginning of a line,50  without any leading spaces.51 52* File encoding should be `ASCII`.53  All `BOM` encodings should be avoided.54  Tests that need a `BOM` encoding file should generate the file on the fly.55 56### Member Conventions57 58* Use of `this` is neither encouraged nor discouraged.59 60* Use `nameof(<member-name>)` instead of `"<member-name>"` whenever possible and relevant.61  The motivation is to easily and more accurately find references.62 63* Always specify the visibility, even if it's the default (i.e. `private string _foo` not `string _foo`).64  Visibility should be the first modifier (i.e. `public abstract` not `abstract public`).65 66* Make members private where possible.67  Avoid declaring public members unless it's absolutely necessary.68 69* Public members in a namespace that ends with `Internal`,70  for example `System.Management.Automation.Internal` are not considered a supported public API.71  Such members are necessarily public as implementation details in code shared between C# and PowerShell script,72  or must be available publicly by generated code.73 74### Commenting Conventions75 76* Place the comment on a separate line, not at the end of a line of code.77 78* Begin comment text with an uppercase letter.79  It's recommended to end comment text with a period but not required.80 81* Add comments where the code is not trivial or could be confusing.82 83* Add comments where a reviewer needs help to understand the code.84 85* Update/remove existing comments when you are changing the corresponding code.86 87* Make sure the added/updated comments are meaningful, accurate and easy to understand.88 89### Documentation comments90 91* Create documentation using [XML documentation comments](https://learn.microsoft.com/dotnet/csharp/language-reference/xmldoc/) so that Visual Studio and other IDEs can use IntelliSense to show quick information about types or members.92 93* Publicly visible types and their members must be documented.94  Internal and private members may use doc comments but it is not required.95 96* Documentation text should be written using complete sentences ending with full stops.97 98## Performance Considerations99 100PowerShell has a lot of performance sensitive code as well as a lot of inefficient code.101We have some guidelines that we typically apply widely even in less important code because code and patterns are copied,102and we want certain inefficient code to stay out of the performance critical code.103 104Some general guidelines:105 106* Avoid LINQ - it can create lots of avoidable garbage.107  Instead, iterate through a collection directly using `for` or `foreach` loop.108 109* Between `for` and `foreach`,110  `for` is slightly preferred when you're uncertain if `foreach` allocates an iterator.111 112* Avoid `params` arrays, prefer adding overloads with 1, 2, 3, and maybe more parameters.113 114* Be aware of APIs such as `String.Split(params char[])` that do not provide overloads to avoid array allocation.115  When calling such APIs, reuse a static array when possible (e.g. `Utils.Separators.Colon`).116 117* Avoid using string interpolations and overloads with implicit parameters such as `Culture` and `StringComparison`.118  Instead, use overloads with more explicit parameters such as `String.Format(IFormatProvider, String, Object[])` and `Equals(String, String, StringComparison)`.119 120* Avoid unnecessary memory allocation in a loop.121  Move the memory allocation outside the loop if possible.122 123* Avoid gratuitous exceptions as much as possible.124  Exception handling can be expensive due to cache misses and page faults when accessing the handling code and data.125  Finding and designing away exception-heavy code can result in a decent performance win.126  For example, you should stay away from things like using exceptions for control flow.127 128* Avoid `if (obj is Example) { example = (Example)obj }` when casting an object to a type.129  Instead, use `var example = obj as Example` or the C# 7 syntax `if (obj is Example example) {...}` as appropriate.130  In this way you can avoid converting to the type twice.131 132* Use generic collections instead of the non-generic ones such as `ArrayList` and `Hashtable` to avoid type casting and unnecessary boxing whenever possible.133 134* Use collection constructor overloads that take an initial capacity for collection types that have them.135  Internally, `List<T>`, `Dictionary<TKey, TValue>`,136  and the other generic collections use one or more arrays to hold valid data.137  Whenever resizing is needed,138  one or more new arrays double the size of existing arrays are created and items from the existing arrays are copied.139  Setting an approximate initial capacity will reduce the number of resizing operations.140 141* Use `dict.TryGetValue` instead of `dict.Contains` and `dict[..]` when retrieving value from a `Dictionary`.142  In this way you can avoid hashing the key twice.143 144* It's OK to use the `+` operator to concatenate one-off short strings.145  But when dealing with strings in loops or large amounts of text,146  use a `StringBuilder` object.147 148## Security Considerations149 150Security is an important aspect of PowerShell and we need to be very careful about changes that may introduce security risks,151such as code injection caused by the lack of input validation,152privilege escalation due to the misuse of impersonation,153or data privacy breach with a plain text password.154 155Reviewers of a PR should be sensitive to changes that may affect security.156Some security related keywords may serve as good indicators,157such as `password`, `crypto`, `encryption`, `decryption`, `certificate`, `authenticate`, `ssl/tls` and `protected data`.158 159When facing a PR with such changes,160the reviewers should request a designated security Subject Matter Expert (SME) to review the PR.161Currently, [@PaulHigin](https://github.com/PaulHigin) and [@TravisEz13](https://github.com/TravisEz13) are our security SMEs.162See [CODEOWNERS](../../.github/CODEOWNERS) for more information about the area experts.163 164## Best Practices165 166* Avoid hard-coding anything unless it's absolutely necessary.167 168* Avoid a method that is too long and complex.169  In such case, separate it to multiple methods or even a nested class as you see fit.170 171* Use the `using` statement instead of `try/finally` if the only code in the `finally` block is to call the `Dispose` method.172 173* Use of object initializers (e.g. `new Example { Name = "Name", ID = 1 }`) is encouraged for better readability,174  but not required.175 176* Stick to the `DRY` principle -- Don't Repeat Yourself.177    * Wrap the commonly used code in methods,178      or even put it in a utility class if that makes sense,179      so that the same code can be reused (e.g. `StringToBase64Converter.Base64ToString(string)`).180    * Check if the code for the same purpose already exists in the code base before inventing your own wheel.181    * Avoid repeating literal strings in code. Instead, use `const` variable to hold the string.182    * Resource strings used for errors or UI should be put in resource files (`.resx`) so that they can be localized later.183 184* Use of new C# language syntax is encouraged.185  But avoid refactoring any existing code using new language syntax when submitting a PR186  as it obscures the functional changes of the PR.187  A separate PR should be submitted for such refactoring without any functional changes.188 189* Consider using the `Interlocked` class instead of the `lock` statement to atomically change simple states. The `Interlocked` class provides better performance for updates that must be atomic.190 191* Here are some useful links for your reference:192  * [Framework Design Guidelines](https://learn.microsoft.com/dotnet/standard/design-guidelines/index) - Naming, Design and Usage guidelines including:193    * [Arrays](https://learn.microsoft.com/dotnet/standard/design-guidelines/arrays)194    * [Collections](https://learn.microsoft.com/dotnet/standard/design-guidelines/guidelines-for-collections)195    * [Exceptions](https://learn.microsoft.com/dotnet/standard/design-guidelines/exceptions)196  * [Best Practices for Developing World-Ready Applications](https://learn.microsoft.com/dotnet/core/extensions/best-practices-for-developing-world-ready-apps) - Unicode, Culture, Encoding and Localization.197  * [Best Practices for Exceptions](https://learn.microsoft.com/dotnet/standard/exceptions/best-practices-for-exceptions)198  * [Best Practices for Using Strings in .NET](https://learn.microsoft.com/dotnet/standard/base-types/best-practices-strings)199  * [Best Practices for Regular Expressions in .NET](https://learn.microsoft.com/dotnet/standard/base-types/best-practices)200  * [Serialization Guidelines](https://learn.microsoft.com/dotnet/standard/serialization/serialization-guidelines)201  * [Managed Threading Best Practices](https://learn.microsoft.com/dotnet/standard/threading/managed-threading-best-practices)202 203## Portable Code204 205There are 3 primary preprocessor macros we use during builds:206 207* `DEBUG` - guard code that should not be included in release builds208* `CORECLR` - guard code that differs between Full CLR and CoreCLR209* `UNIX` - guard code that is specific to Unix (Linux and macOS)210 211Any other preprocessor defines found in the source are used for one-off custom builds,212typically to help debug specific scenarios.213 214Here are some general guidelines for writing portable code:215 216* We are in the process of cleaning up Full CLR specific code (code enclosed in `!CORECLR`),217  so do not use `CORECLR` or `!CORECLR` in new code.218  PowerShell Core targets .NET Core only and all new changes should support .NET Core only.219 220* The PowerShell code base started on Windows and depends on many Win32 APIs through P/Invoke.221  Going forward, we try to depend on .NET Core to handle platform differences,222  so avoid adding new P/Invoke calls where a suitable alternative exists in .NET Core.223 224* Try to minimize the use of `#if UNIX`.225  When absolutely necessary, avoid duplicating more code than necessary,226  and instead prefer introducing helper functions to minimize the platform differences.227 228* When adding platform dependent code (`Windows` vs. `UNIX`), prefer preprocessor directives over runtime checks.229  However, runtime checks are acceptable if it would greatly improve readability230  without causing performance concerns in performance-sensitive code.231 232* We produce a single binary for all UNIX variants,233  so runtime checks are currently necessary for some of them (e.g. macOS vs. Linux).234