It's dangerous to code alone! Take this.

Capitalization Conventions

Published on 19 Feb 2022.

In the Discord server, people post their solutions for feedback. One of the most common types of feedback is either:

Your capitalization is inconsistent.

Or:

Your capitalization is not what most C# programmers do.

You can use whatever capitalization you want–it’s your code–but there are definitely certain patterns in naming and capitalization conventions among C# programmers.

As a general rule, you should follow the capitalization (and other) conventions of the programmers who usually use the language. As the saying goes, “When in Rome, do as the Romans do.” Likewise, when programming in C#, do as the C# programmers do.

On the other hand, if you simply don’t want to follow those rules, then at a minimum, you must:

  1. Be consistent. Make a choice about what you’re doing, don’t just wing it every time.
  2. Be aware of where your choice is different from the normal conventions.

Either way, it is worth knowing what those conventions are in C#.

Capitalization Schemes

C# tends to stick to one of the following flavors of capitalization schemes.

  1. lowerCamelCase: All the words are squished together with no separator, but each new word starts with a capital letter, except the first, which starts with a lowercase letter. This is also called plain old camelCase or dromedaryCase. (Dromedaries are a type of one-humped camel.) However, the phrase “camel case” is not always clear, because sometimes it refers, instead, to UpperCamelCase, below, or to both as a set.
  2. UpperCamelCase: All the words are squished together with no separator, but each word, including the first, starts with a capital letter. This is also called PascalCase (it was popularized by the Pascal programming language) or StudlyCase (though sometimes, StudlyCase refers to AlTeRnAtInG cAsE).
  3. _underscorePrefixedLowerCamelCase: The same as lowerCamelCase, but starting with an underscore.
  4. UNDERSCORE_SEPARATED_ALL_CAPS: Everything is capitalized, and words are separated by underscores. This is also sometimes called SCREAMING_CASE.

C# Capitalization Conventions

I’m going to do this by way of example and comments. I’m trying to do this in the order things are introduced in the book:

// Local variables use lowerCamelCase.
int coolVariable = 3;

// Methods, including local functions, use UpperCamelCase.
void CoolerMethod(int aParameter) // Parameters use lowerCamelCase.
{
    // Just another local variable.
    char warmVariable = 'z';

    // If you name tuple members, use UpperCamelCase.
    // But the tuple variable itself is just another variable.
    (float XCoordinate, float YCoordinate) tupleVariable = (2.0f, 6.0f);

    // lowerCamelCase is less common, but not uncommon.
    (float xCoordinate, float yCoordinate) tupleVariable2 = (2.0f, 6.0f);
}

// Most type names, including enumerations, use UpperCamelCase.
// Enumeration member names use UpperCamelCase.
enum RoomType { Empty, PortalToOblivion, Cavern }

// Most type names, including classes, use UpperCamelCase.
class Point
{
    // Private instance fields are usually _underscorePrefixedLowerCamelCase.
    private float _x;
    private float _y;

    // Methods use UpperCamelCase
    public void Length() => Math.Sqrt(_x * _x + _y * _y);

    // Constructors use the same conventions as methods.
    public Point(float x, float y) { _x = x; _y = y; }

    // Properties use UpperCamelCase. (They're a form of method, after all.)
    // It doesn't matter if the property is an auto-property,
    // get-only, has a private setter, etc. All flavors of properties are
    // UpperCamelCase.
    public float LengthSquared => _x * _x + _y * _y;

    // In general, you shouldn't be making public or protected instance fields.
    // If you must, they should generally be readonly.
    // In the rare cases where you do, they're usually UpperCamelCase.
    public readonly float Z;
    protected readonly float W;

    // Internal instance fields don't happen often, so there's not a lot of
    // samples on how to do it, but they often match private field naming:
    internal float _m;

    // Static members don't generally change the naming conventions:
    public static void DoThing() { Console.WriteLine("Did thing."); }
    private static int _counter = 0;
}

// Like other types, interfaces use UpperCamelCase, but start with an I.
interface IKingMaker
{
    // Members in an interface generally follow the same conventions as a class.
    King MakeKing();
}

// Like other types, structs use UpperCamelCase.
struct King
{
    // Members of structs follow the same rules as for a class.
    public string Country { get; }
    public string House { get; }
}

// Like other types, records use UpperCamelCase for their name.
// They also use UpperCamelCase for positional properties, because they are made
// into properties.
record EngineModel(string Name, float Power, float Weight);

// Generic type parameters use UpperCamelCase.
// However, if you have a single generic type parameter, it is nearly always `T`.
// With multiple, the convention is either single-letter names or `T`-prefixed
// longer names.
public class Generic<T> { }
public class Generic<U, V> { }
public class Generic<TFirst, TSecond, TThird> { }

// Like other types, delegate types use UpperCamelCase.
// Parameter names follow the same rules as any parameter, and so are lowerCamelCase.
delegate int NumberCombiner(int a, int b);

class EventHaver
{
    // Event names use UpperCamelCase.
    public Action<int>? EventHappened;

    public void DoSomething()
    {
        int[] numbers = new int[] { 1, 2, 3 };

        // Lambdas use lowerCamelCase for parameter names, but also often use
        // a single letter.
        Console.WriteLine(numbers.Count(n => n % 2 == 0));
    }
}

Let me know if I missed anything.