I think there isn't a real reason why it can't be. Maybe the reason is just: because it is documented.
As far as I know, there isn't any compiler magic that makes out
special. Look at this CIL code:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 17 (0x11)
.maxstack 1
.locals init ([0] int32 y)
IL_0000: nop
IL_0001: ldloca.s y
IL_0003: call void ConsoleApplication15.Program::X(int32&)
IL_0008: nop
IL_0009: ldloc.0
IL_000a: call void [mscorlib]System.Console::WriteLine(int32)
IL_000f: nop
IL_0010: ret
} // end of method Program::Main
.method public hidebysig static void X([out] int32& i) cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.s 10
IL_0004: stind.i4
IL_0005: ret
} // end of method Program::X
Derived from this method:
public static void X(out int i)
{
i = 10;
}
static void Main(string[] args)
{
int y;
X(out y);
Console.WriteLine(y);
}
As you see, the variable is allocated in the calling method, and the value is passed 'by reference'. Defining a default value for an out
parameter 'just' breaks checking if a value is set (since it is already).
Also, as Damien_The_Unbeliever commented, it might just be a feature overlooked / skipped in the initial build of optional parameters, since out
already existed back then.