In short, you are not doing anything wrong. Its restriction on implementation when called.
ref . , .
...
, , IL. :
.method public hidebysig static void SampleMethod(string throwsException, [out] string& text) cil managed
{
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldstr "Hello"
IL_0007: stind.ref
IL_0008: ldarg.0
IL_0009: ldsfld string [mscorlib]System.Boolean::TrueString
IL_000e: call bool [mscorlib]System.String::op_Equality(string, string)
IL_0013: ldc.i4.0
IL_0014: ceq
IL_0016: stloc.0
IL_0017: ldloc.0
IL_0018: brtrue.s IL_0025
IL_001a: ldstr "Test Exception"
IL_001f: newobj instance void [mscorlib]System.Exception::.ctor(string)
IL_0024: throw
IL_0025: ret
}
, "Hello" () . , .
invoke . IL , , , . Invoke:
public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
return UnsafeInvokeInternal(obj, parameters, arguments);
}
, InvokeArgumentsCheck, , . :
internal Object[] CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
{
Object[] copyOfParameters = new Object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
}
return copyOfParameters;
}
, ( ). , , , , .
UnsafeInvokeInternal. :
private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
{
if (arguments == null || arguments.Length == 0)
return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
else
{
Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
for (int index = 0; index < arguments.Length; index++)
parameters[index] = arguments[index];
return retValue;
}
}
"else". , , , . "".
, , "" "Hello" . ( ), arguments, .
, , , .