C# Overloading Operators and Methods

1. For standard objects, such as strings and numerical values, the standard operators (e.g. +) work perfectly:
    int a = 1;
    int b = 2;
    int c = a + b;   // arithmetic add

    string d = "me";
    string e = "you";
    string f = d + e;  // string concatenation
2. But if you have a custom class:
    class TLA
    {
        public string val;

        public TLA(string tla)
        {
            this.val = tla;
        }
    }
What happens when you try use + on two of these objects?
    TLA cia = new TLA("CIA");
    TLA fbi = new TLA("FBI");
    var cops = 
cia + fbi
;
(local variable) TLA fbi

Error:
  Operator '+' cannot be applied to operands of type 'TLA' and 'TLA'

An error. This is because you need to overload the + operator if you want to be able to use it this way, and we haven't defined what is to happen when we try to + in this way.
3. Say we decided than when we + two TLA objects what should come back is an array of TLA objects containing the two of them. To make this happen, we need to overload the + operator within the class TLA:
    public static TLA[] operator +(TLA tla1, TLA tla2)
    {
        return new TLA[] { tla1, tla2 };
    }
Now when we try to + together two FBI objects, what we get back is the array containing both of them.

If we try to apply the + operator to a series of TLA objects, e.g. fbi + cia + fbi, then working from left to right, it + the first two, producing a TLA[] array, then tries to + that to the third TLA. Since we haven't defined an operator overload taking TLA[] and TLA as arguments, this fails, but it would be easy to add one to the definition of TLA to support a series of chained + operations on TLAs.

3. In a similar way, we decide the unary operator ++ (which usually adds 1 to an integer) can be used to append the string "(plusplus)" to the end of the val field in the TLA:
    public static TLA operator ++(TLA tla)
    {
        string oldVal = tla.val;
        tla = new TLA(oldVal + "(plusplus)");
        return tla;
    }
Normally, the ++ operator acts on the variable directly, you don't have to assign the result of it to the variable again, so we make this behave the same way, altering the value passed in by ref. Because operators cannot return void, we still have to return the original changed TLA object, but the caller has no need to assign it to anything. The TLA was passed in by reference so has already been altered.
    TLA fbi = new TLA("FBI");
    Console.WriteLine(fbi.val);
    fbi++;
    Console.WriteLine(fbi.val);
    fbi++;
    Console.WriteLine(fbi.val);
    fbi++;
    Console.WriteLine(fbi.val);
Output:

FBI
FBI(plusplus)
FBI(plusplus)(plusplus)
FBI(plusplus)(plusplus)(plusplus)

4. As well as standard operators, there are Object methods which we may wish to override, such as ToString(), using the normal override keyword:
    public static override string ToString(TLA tla)
    {
        return "TLA['" + tla.val + "']";
    }
And when we run this from the code:
    TLA cia = new TLA("CIA");
    TLA fbi = new TLA("FBI");
    Console.WriteLine(cia.ToString());
    Console.WriteLine(fbi.ToString());
Output:

TLA['CIA']
TLA['FBI']

And that is all there is to overloading standard operators and methods in your custom classes.