|
| 1 | +# Overview |
| 2 | +This document provides guidelines for using GitHub Copilot to contribute to the .NET MAUI Community Toolkit. It includes instructions on setting up your environment, writing code, and following best practices specific to .NET MAUI. |
| 3 | + |
| 4 | +## Prerequisites |
| 5 | +1. Install the latest stable (.NET SDK)[https://dotnet.microsoft.com/en-us/download]. |
| 6 | +2. Install .NET MAUI workloads (we recommend using Visual Studio installer). |
| 7 | + |
| 8 | +## Setting Up GitHub Copilot |
| 9 | +1. Ensure you have GitHub Copilot installed and enabled in Visual Studio. |
| 10 | +2. Familiarize yourself with the basic usage of GitHub Copilot by reviewing the (official documentation)[https://docs.github.com/en/copilot]. |
| 11 | + |
| 12 | +## Writing Code with GitHub Copilot |
| 13 | +### General Guidelines |
| 14 | +* Use GitHub Copilot to assist with code completion, documentation, and generating boilerplate code. |
| 15 | +* Always review and test the code suggested by GitHub Copilot to ensure it meets the project's standards and requirements. |
| 16 | + |
| 17 | +### Specific to .NET MAUI |
| 18 | +* Ensure that any UI components or controls are compatible with .NET MAUI. |
| 19 | +* Avoid using Xamarin.Forms-specific code unless there is a direct .NET MAUI equivalent. |
| 20 | +* Follow the project's coding style and best practices as outlined in the (contributing)[https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md] document. |
| 21 | + |
| 22 | +## Best Practices |
| 23 | +* Use **Trace.WriteLine()** for debug logging instead of **Debug.WriteLine()**. |
| 24 | +* Include a **CancellationToken** as a parameter for methods returning **Task** or **ValueTask**. |
| 25 | +* Use **is** for null checking and type checking. |
| 26 | +* Use file-scoped namespaces to reduce code verbosity. |
| 27 | +* Avoid using the **!** null forgiving operator. |
| 28 | +** Follow naming conventions for enums and property names. |
| 29 | + |
| 30 | +### Debug Logging |
| 31 | +* Always use `Trace.WriteLine()` instead of `Debug.WriteLine` for debug logging because `Debug.WriteLine` is removed by the compiler in Release builds |
| 32 | + |
| 33 | +### Methods Returning Task and ValueTask |
| 34 | +* Always include a `CancellationToken` as a parameter to every method returning `Task` or `ValueTask` |
| 35 | +* If the method is public, provide a the default value for the `CancellationToken` (e.g. `CancellationToken token = default`) |
| 36 | +* If the method is not public, do not provide a default value for the `CancellationToken` |
| 37 | +* If the method is used outside of a .net MAUI control, Use `CancellationToken.ThrowIfCancellationRequested()` to verify the `CancellationToken`, as it is not possible to catch exceptions in XAML. |
| 38 | + |
| 39 | +### Enums |
| 40 | +* Always use `Unknown` at index 0 for return types that may have a value that is not known |
| 41 | +* Always use `Default` at index 0 for option types that can use the system default option |
| 42 | +* Follow naming guidelines for tense... `SensorSpeed` not `SensorSpeeds` |
| 43 | +* Assign values (0,1,2,3) for all enums, if not marked with a `Flags` attribute. This is to ensure that the enum can be serialized and deserialized correctly across platforms. |
| 44 | + |
| 45 | +### Property Names |
| 46 | +* Include units only if one of the platforms includes it in their implementation. For instance HeadingMagneticNorth implies degrees on all platforms, but PressureInHectopascals is needed since platforms don't provide a consistent API for this. |
| 47 | + |
| 48 | +### Units |
| 49 | +* Use the standard units and most well accepted units when possible. For instance Hectopascals are used on UWP/Android and iOS uses Kilopascals so we have chosen Hectopascals. |
| 50 | + |
| 51 | +### Pattern matching |
| 52 | +#### Null checking |
| 53 | +* Prefer using `is` when checking for null instead of `==`. |
| 54 | + |
| 55 | +e.g. |
| 56 | + |
| 57 | +```csharp |
| 58 | +// null |
| 59 | +if (something is null) |
| 60 | +{ |
| 61 | + |
| 62 | +} |
| 63 | + |
| 64 | +// or not null |
| 65 | +if (something is not null) |
| 66 | +{ |
| 67 | + |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +* Avoid using the `!` [null forgiving operator](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-forgiving) to avoid the unintended introduction of bugs. |
| 72 | + |
| 73 | +#### Type checking |
| 74 | +* Prefer `is` when checking for types instead of casting. |
| 75 | + |
| 76 | +e.g. |
| 77 | + |
| 78 | +```csharp |
| 79 | +if (something is Bucket bucket) |
| 80 | +{ |
| 81 | + bucket.Empty(); |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +### File Scoped Namespaces |
| 86 | +* Use [file scoped namespaces](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/file-scoped-namespaces) to help reduce code verbosity. |
| 87 | + |
| 88 | +e.g. |
| 89 | + |
| 90 | +```csharp |
| 91 | +namespace CommunityToolkit.Maui.Converters; |
| 92 | + |
| 93 | +using System; |
| 94 | + |
| 95 | +class BoolToObjectConverter |
| 96 | +{ |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +### Braces |
| 101 | +Please use `{ }` after `if`, `for`, `foreach`, `do`, `while`, etc. |
| 102 | + |
| 103 | +e.g. |
| 104 | + |
| 105 | +```csharp |
| 106 | +if (something is not null) |
| 107 | +{ |
| 108 | + ActOnIt(); |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +### `NotImplementedException` |
| 113 | +* Please avoid adding new code that throws a `NotImplementedException`. According to the [Microsoft Docs](https://docs.microsoft.com/dotnet/api/system.notimplementedexception), we should only "throw a `NotImplementedException` exception in properties or methods in your own types when that member is still in development and will only later be implemented in production code. In other words, a NotImplementedException exception should be synonymous with 'still in development.'" |
| 114 | +In other words, `NotImplementedException` implies that a feature is still in development, indicating that the Pull Request is incomplete. |
| 115 | + |
| 116 | +### Bug Fixes |
| 117 | +If you're looking for something to fix, please browse [open issues](https://github.com/CommunityToolkit/Maui/issues). |
| 118 | + |
| 119 | +Follow the style used by the [.NET Foundation](https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/coding-style.md), with two primary exceptions: |
| 120 | + |
| 121 | +* We do **not** use the `private` keyword as it is the default accessibility level in C#. |
| 122 | +* We will **not** use `_` or `s_` as a prefix for internal or private field names |
| 123 | +* We will use `camelCaseFieldName` for naming internal or private fields in both instance and static implementations |
| 124 | + |
| 125 | +Read and follow our [Pull Request template](https://github.com/CommunityToolkit/Maui/blob/main/.github/PULL_REQUEST_TEMPLATE.md) |
| 126 | + |
| 127 | +## Submitting Contributions |
| 128 | +1. Fork the repository and create a new branch for your changes. |
| 129 | +2. Implement your changes using GitHub Copilot as needed. |
| 130 | +3. Ensure your changes include tests, samples, and documentation. |
| 131 | +4. Open a pull request and follow the [Pull Request template](https://github.com/CommunityToolkit/Maui/blob/main/.github/PULL_REQUEST_TEMPLATE.md). |
| 132 | + |
| 133 | +## Additional Resources |
| 134 | +- (GitHub Copilot Documentation)[https://docs.github.com/en/copilot] |
| 135 | +- (.NET MAUI Documentation)[https://learn.microsoft.com/en-us/dotnet/maui/] |
| 136 | + |
| 137 | +By following these guidelines, you can effectively use GitHub Copilot to contribute to the .NET MAUI Community Toolkit. Thank you for your contributions! |
0 commit comments