The += operator uses the + operator, so the first is really:
o = o + c;
What the compiler actually creates is:
o = String.Concat((object)o, (object)c);
The integer is boxed, and the Concat method that takes object parameters is called. The ToString method will be called on both parameters to get their string values, and they are concatenated.
If you first convert the integer to a string, the code gets more straight forward:
o += c.ToString();
which becomes:
o = String.Concat(o, c.ToString());
In the second code, the types in the conditional operator doesn't match:
bool ? string : int
The second and third operand has to have the same type, like in the third code:
bool ? string : string
The second code really becomes:
o = String.Concat(
o,
P == 2
? String.Concat((object)".", (object)c)
: c
);
and the third code really becomes:
o = String.Concat(
o,
P == 2
? String.Concat((object)".", (object)c)
: String.Concat((object)String.Empty, (object)c)
);
Anyhow, you should consider using a StringBuilder to build strings instead of using the += operator:
StringBuilder builder = new StringBuilder;
if (P == 2) {
builder.Append('.');
}
builder.Append(c);