diff --git a/README.md b/README.md
index f7e755f..90e3958 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,8 @@ style guidelines we use for Google code. If you are modifying a project that
originated at Google, you may be pointed to this page to see the style guides
that apply to that project.
-This project holds the [C++ Style Guide][cpp], [Swift Style Guide][swift], [Objective-C Style Guide][objc],
+This project holds the [C++ Style Guide][cpp], [C# Style Guide][csharp],
+[Swift Style Guide][swift], [Objective-C Style Guide][objc],
[Java Style Guide][java], [Python Style Guide][py], [R Style Guide][r],
[Shell Style Guide][sh], [HTML/CSS Style Guide][htmlcss],
[JavaScript Style Guide][js], [AngularJS Style Guide][angular],
@@ -36,6 +37,7 @@ The following Google style guides live outside of this project:
[cpp]: https://google.github.io/styleguide/cppguide.html
+[csharp]: https://google.github.io/styleguide/csharp-style.html
[swift]: https://google.github.io/swift/
[objc]: objcguide.md
[java]: https://google.github.io/styleguide/javaguide.html
diff --git a/csharp-style.md b/csharp-style.md
new file mode 100644
index 0000000..d7438c7
--- /dev/null
+++ b/csharp-style.md
@@ -0,0 +1,477 @@
+# C# at Google Style Guide
+
+This style guide is for C# code developed internally at Google, and is the
+default style for C# code at Google. It makes stylistic choices that conform to
+other languages at Google, such as Google C++ style and Google Java style.
+
+## Formatting guidelines
+
+### Naming rules
+
+Naming rules follow
+[Microsoft's C# naming guidelines](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines).
+Where Microsoft's naming guidelines are unspecified (e.g. private and local
+variables), rules are taken from the
+[CoreFX C# coding guidelines](https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/coding-style.md)
+
+Rule summary:
+
+#### Code
+
+* Names of classes, methods, enumerations, public fields, public properties,
+ namespaces: `PascalCase`.
+* Names of local variables, parameters: `camelCase`.
+* Names of private, protected, internal and protected internal fields and
+ properties: `_camelCase`.
+* Naming convention is unaffected by modifiers such as const, static,
+ readonly, etc.
+* For casing, a "word" is anything written without internal spaces, including
+ acronyms. For example, `MyRpc` instead of ~~`MyRPC`~~.
+* Names of interfaces start with `I`, e.g. `IInterface`.
+
+#### Files
+
+* Filenames and directory names are `PascalCase`, e.g. `MyFile.cs`.
+* Where possible the file name should be the same as the name of the main
+ class in the file, e.g. `MyClass.cs`.
+* In general, prefer one core class per file.
+
+### Organization
+
+* Modifiers occur in the following order: `public protected internal private
+ new abstract virtual override sealed static readonly extern unsafe volatile
+ async`.
+* Namespace `using` declarations go at the top, before any namespaces. `using`
+ import order is alphabetical, apart from `System` imports which always go
+ first.
+* Class member ordering:
+ * Group class members in the following order:
+ * Nested classes, enums, delegates and events.
+ * Static, const and readonly fields.
+ * Fields and properties.
+ * Constructors and finalizers.
+ * Methods.
+ * Within each group, elements should be in the following order:
+ * Public.
+ * Internal.
+ * Protected internal.
+ * Protected.
+ * Private.
+ * Where possible, group interface implementations together.
+
+### Whitespace rules
+
+Developed from Google Java style.
+
+* A maximum of one statement per line.
+* A maximum of one assignment per statement.
+* Indentation of 2 spaces, no tabs.
+* Column limit: 100.
+* No line break before opening brace.
+* No line break between closing brace and `else`.
+* Braces used even when optional.
+* Space after `if`/`for`/`while` etc., and after commas.
+* No space after an opening parenthesis or before a closing parenthesis.
+* No space between a unary operator and its operand. One space between the
+ operator and each operand of all other operators.
+* Line wrapping developed from Google C++ style guidelines, with minor
+ modifications for compatibility with Microsoft's C# formatting tools:
+ * In general, line continuations are indented 4 spaces.
+ * Line breaks with braces (e.g. list initializers, lambdas, object
+ initializers, etc) do not count as continuations.
+ * For function definitions and calls, if the arguments do not all fit on
+ one line they should be broken up onto multiple lines, with each
+ subsequent line aligned with the first argument. If there is not enough
+ room for this, arguments may instead be placed on subsequent lines with
+ a four space indent. The code example below illustrates this.
+
+### Example
+
+```c#
+using System; // `using` goes at the top, outside the
+ // namespace.
+
+namespace MyNamespace { // Namespaces are PascalCase.
+ // Indent after namespace.
+ public interface IMyInterface { // Interfaces start with 'I'
+ public int Calculate(float value, float exp); // Methods are PascalCase
+ // ...and space after comma.
+ }
+
+ public enum MyEnum { // Enumerations are PascalCase.
+ Yes, // Enumerators are PascalCase.
+ No,
+ }
+
+ public class MyClass { // Classes are PascalCase.
+ public int Foo = 0; // Public member variables are
+ // PascalCase.
+ public bool NoCounting = false; // Field initializers are encouraged.
+ private class Results {
+ public int NumNegativeResults = 0;
+ public int NumPositiveResults = 0;
+ }
+ private Results _results; // Private member variables are
+ // _camelCase.
+ public static int NumTimesCalled = 0;
+ private const int _bar = 100; // const does not affect naming
+ // convention.
+ private int[] _someTable = { // Container initializers use a 2
+ 2, 3, 4, // space indent.
+ }
+
+ public MyClass() {
+ _results = new Results {
+ NumNegativeResults = 1, // Object initializers use a 2 space
+ NumPositiveResults = 1, // indent.
+ };
+ }
+
+ public int CalculateValue(int mulNumber) { // No line break before opening brace.
+ var resultValue = Foo * mulNumber; // Local variables are camelCase.
+ NumTimesCalled++;
+ Foo += _bar;
+
+ if (!NoCounting) { // No space after unary operator and
+ // space after 'if'.
+ if (resultValue < 0) { // Braces used even when optional and
+ // spaces around comparison operator.
+ _results.NumNegativeResults++;
+ } else if (resultValue > 0) { // No newline between brace and else.
+ _results.NumPositiveResults++;
+ }
+ }
+
+ return resultValue;
+ }
+
+ public void ExpressionBodies() {
+ // For simple lambdas, fit on one line if possible, no brackets or braces required.
+ Func increment = x => x + 1;
+
+ // Closing brace aligns with first character on line that includes the opening brace.
+ Func difference1 = (x, y) => {
+ long diff = (long)x - y;
+ return diff >= 0 ? diff : -diff;
+ };
+
+ // If defining after a continuation line break, indent the whole body.
+ Func difference2 =
+ (x, y) => {
+ long diff = (long)x - y;
+ return diff >= 0 ? diff : -diff;
+ };
+
+ // Inline lambda arguments also follow these rules. Prefer a leading newline before
+ // groups of arguments if they include lambdas.
+ CallWithDelegate(
+ (x, y) => {
+ long diff = (long)x - y;
+ return diff >= 0 ? diff : -diff;
+ });
+ }
+
+ void DoNothing() {} // Empty blocks may be concise.
+
+ // If possible, wrap arguments by aligning newlines with the first argument.
+ void AVeryLongFunctionNameThatCausesLineWrappingProblems(int longArgumentName,
+ int p1, int p2) {}
+
+ // If aligning argument lines with the first argument doesn't fit, or is difficult to
+ // read, wrap all arguments on new lines with a 4 space indent.
+ void AnotherLongFunctionNameThatCausesLineWrappingProblems(
+ int longArgumentName, int longArgumentName2, int longArgumentName3) {}
+
+ void CallingLongFunctionName() {
+ int veryLongArgumentName = 1234;
+ int shortArg = 1;
+ // If possible, wrap arguments by aligning newlines with the first argument.
+ AnotherLongFunctionNameThatCausesLineWrappingProblems(shortArg, shortArg,
+ veryLongArgumentName);
+ // If aligning argument lines with the first argument doesn't fit, or is difficult to
+ // read, wrap all arguments on new lines with a 4 space indent.
+ AnotherLongFunctionNameThatCausesLineWrappingProblems(
+ veryLongArgumentName, veryLongArgumentName, veryLongArgumentName);
+ }
+ }
+}
+```
+
+## C# coding guidelines
+
+### Constants
+
+* Variables and fields that can be made `const` should always be made `const`.
+* If `const` isn’t possible, `readonly` can be a suitable alternative.
+* Prefer named constants to magic numbers.
+
+### IEnumerable vs IList vs IReadOnlyList
+
+* For inputs use the most restrictive collection type possible, for example
+ `IReadOnlyCollection` / `IReadOnlyList` / `IEnumerable` as inputs to methods
+ when the inputs should be immutable.
+* For outputs, if passing ownership of the returned container to the owner,
+ prefer `IList` over `IEnumerable`. If not transferring ownership, prefer the
+ most restrictive option.
+
+### Generators vs containers
+
+* Use your best judgement, bearing in mind:
+ * Generator code is often less readable than filling in a container.
+ * Generator code can be more performant if the results are going to be
+ processed lazily, e.g. when not all the results are needed.
+ * Generator code that is directly turned into a container via `ToList()`
+ will be less performant than filling in a container directly.
+ * Generator code that is called multiple times will be considerably slower
+ than iterating over a container multiple times.
+
+### Property styles
+
+* For single line read-only properties, prefer expression body properties
+ (`=>`) when possible.
+* For everything else, use the older `{ get; set; }` syntax.
+
+### Expression body syntax
+
+For example:
+
+```c# {.good}
+int SomeProperty => _someProperty
+```
+
+* Judiciously use expression body syntax in lambdas and properties.
+* Don’t use on method definitions. This will be reviewed when C# 7 is live,
+ which uses this syntax heavily.
+* As with methods and other scoped blocks of code, align the closing with the
+ first character of the line that includes the opening brace. See sample code
+ for examples.
+
+### Structs and classes:
+
+* Structs are very different from classes:
+
+ * Structs are always passed and returned by value.
+ * Assigning a value to a member of a returned struct doesn’t modify the
+ original - e.g. `transform.position.x = 10` doesn’t set the transform’s
+ position.x to 10; `position` here is a property that returns a `Vector3`
+ by value, so this just sets the x parameter of a copy of the original.
+
+* Almost always use a class.
+
+* Consider struct when the type can be treated like other value types - for
+ example, if instances of the type are small and commonly short-lived or are
+ commonly embedded in other objects. Good examples include Vector3,
+ Quaternion and Bounds.
+
+* Note that this guidance may vary from team to team where, for example,
+ performance issues might force the use of structs.
+
+### Lambdas vs named methods
+
+* If a lambda is non-trivial (e.g. more than a couple of statements, excluding
+ declarations), or is reused in multiple places, it should probably be a
+ named method.
+
+### Field initializers
+
+* Field initializers are generally encouraged.
+
+### Extension methods
+
+* Only use an extension method when the source of the original class is not
+ available, or else when changing the source is not feasible.
+* Only use an extension method if the functionality being added is a ‘core’
+ general feature that would be appropriate to add to the source of the
+ original class.
+ * Note - if we have the source to the class being extended, and the
+ maintainer of the original class does not want to add the function,
+ prefer not using an extension method.
+* Only put extension methods into core libraries that are available
+ everywhere - extensions that are only available in some code will become a
+ readability issue.
+* Be aware that using extension methods always obfuscates the code, so err on
+ the side of not adding them.
+
+### ref and out
+
+* Use `out` for returns that are not also inputs.
+* Place `out` parameters after all other parameters in the method definition.
+* `ref` should be used rarely, when mutating an input is necessary.
+* Do not use `ref` as an optimisation for passing structs.
+* Do not use `ref` to pass a modifiable container into a method. `ref` is only
+ required when the supplied container needs be replaced with an entirely
+ different container instance.
+
+### LINQ
+
+* In general, prefer single line LINQ calls and imperative code, rather than
+ long chains of LINQ. Mixing imperative code and heavily chained LINQ is
+ often hard to read.
+* Prefer member extension methods over SQL-style LINQ keywords - e.g. prefer
+ `myList.Where(x)` to `myList where x`.
+* Avoid `Container.ForEach(...)` for anything longer than a single statement.
+
+### Array vs List
+
+* In general, prefer `List<>` over arrays for public variables, properties,
+ and return types (keeping in mind the guidance on `IList` / `IEnumerable` /
+ `IReadOnlyList` above).
+* Prefer `List<>` when the size of the container can change.
+* Prefer arrays when the size of the container is fixed and known at
+ construction time.
+* Prefer array for multidimensional arrays.
+* Note:
+ * array and `List<>` both represent linear, contiguous containers.
+ * Similar to C++ arrays vs `std::vector`, arrays are of fixed capacity,
+ whereas `List<>` can be added to.
+ * In some cases arrays are more performant, but in general `List<>` is
+ more flexible.
+
+### Folders and file locations
+
+* Be consistent with the project.
+* Prefer a flat structure where possible.
+
+### Use of tuple as a return type
+
+* In general, prefer a named class type over `Tuple<>`, particularly when
+ returning complex types.
+
+### String interpolation vs `String.Format()` vs `String.Concat` vs `operator+`
+
+* In general, use whatever is easiest to read, particularly for logging and
+ assert messages.
+* Be aware that chained `operator+` concatenations will be slower and cause
+ significant memory churn.
+* If performance is a concern, `StringBuilder` will be faster for multiple
+ string concatenations.
+
+### `using`
+
+* Generally, don’t alias long typenames with `using`. Often this is a sign
+ that a `Tuple<>` needs to be turned into a class.
+ * e.g. `using RecordList = List>` should probably be a
+ named class instead.
+* Be aware that `using` statements are only file scoped and so of limited use.
+ Type aliases will not be available for external users.
+
+### Object Initializer syntax
+
+For example:
+
+```c# {.good}
+var x = new SomeClass {
+ Property1 = value1,
+ Property2 = value2,
+};
+```
+
+* Object Initializer Syntax is fine for ‘plain old data’ types.
+* Avoid using this syntax for classes or structs with constructors.
+* If splitting across multiple lines, indent one block level.
+
+### Namespace naming
+
+* In general, namespaces should be no more than 2 levels deep.
+* Don't force file/folder layout to match namespaces.
+* For shared library/module code, use namespaces. For leaf 'application' code,
+ such as `unity_app`, namespaces are not necessary.
+* New top-level namespace names must be globally unique and recognizable.
+
+### Default values/null returns for structs
+
+* Prefer returning a ‘success’ boolean value and a struct `out` value.
+* Where performance isn't a concern and the resulting code significantly more
+ readable (e.g. chained null conditional operators vs deeply nested if
+ statements) nullable structs are acceptable.
+* Notes:
+
+ * Nullable structs are convenient, but reinforce the general ‘null is
+ failure’ pattern Google prefers to avoid. We will investigate a
+ `StatusOr` equivalent in the future, if there is enough demand.
+
+### Removing from containers while iterating
+
+C# (like many other languages) does not provide an obvious mechanism for
+removing items from containers while iterating. There are a couple of options:
+
+* If all that is required is to remove items that satisfy some condition,
+ `someList.RemoveAll(somePredicate)` is recommended.
+* If other work needs to be done in the iteration, `RemoveAll` may not be
+ sufficient. A common alternative pattern is to create a new container
+ outside of the loop, insert items to keep in the new container, and swap the
+ original container with the new one at the end of iteration.
+
+### Calling delegates
+
+* When calling a delegate, use `Invoke()` and use the null conditional
+ operator - e.g. `SomeDelegate?.Invoke()`. This clearly marks the call at the
+ callsite as ‘a delegate that is being called’. The null check is concise and
+ robust against threading race conditions.
+
+### The `var` keyword
+
+* Use of `var` is encouraged if it aids readability by avoiding type names
+ that are noisy, obvious, or unimportant.
+* Encouraged:
+
+ * When the type is obvious - e.g. `var apple = new Apple();`, or `var
+ request = Factory.Create();`
+ * For transient variables that are only passed directly to other methods -
+ e.g. `var item = GetItem(); ProcessItem(item);`
+
+* Discouraged:
+
+ * When working with basic types - e.g. `var success = true;`
+ * When working with compiler-resolved built-in numeric types - e.g. `var
+ number = 12 * ReturnsFloat();`
+ * When users would clearly benefit from knowing the type - e.g. `var
+ listOfItems = GetList();`
+
+### Attributes
+
+* Attributes should appear on the line above the field, property, or method
+ they are associated with, separated from the member by a newline.
+* Multiple attributes should be separated by newlines. This allows for easier
+ adding and removing of attributes, and ensures each attribute is easy to
+ search for.
+
+### Argument Naming
+
+Derived from the Google C++ style guide.
+
+When the meaning of a function argument is nonobvious, consider one of the
+following remedies:
+
+* If the argument is a literal constant, and the same constant is used in
+ multiple function calls in a way that tacitly assumes they're the same, use
+ a named constant to make that constraint explicit, and to guarantee that it
+ holds.
+* Consider changing the function signature to replace a `bool` argument with
+ an `enum` argument. This will make the argument values self-describing.
+* Replace large or complex nested expressions with named variables.
+* Consider using
+ [Named Arguments](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments)
+ to clarify argument meanings at the call site.
+* For functions that have several configuration options, consider defining a
+ single class or struct to hold all the options and pass an instance of that.
+ This approach has several advantages. Options are referenced by name at the
+ call site, which clarifies their meaning. It also reduces function argument
+ count, which makes function calls easier to read and write. As an added
+ benefit, call sites don't need to be changed when another option is added.
+
+Consider the following example:
+
+```c# {.bad}
+// What are these arguments?
+DecimalNumber product = CalculateProduct(values, 7, false, null);
+```
+
+versus:
+
+```c# {.good}
+ProductOptions options = new ProductOptions();
+options.PrecisionDecimals = 7;
+options.UseCache = CacheUsage.DontUseCache;
+DecimalNumber product = CalculateProduct(values, options, completionDelegate: null);
+```