Saturday, August 3, 2013

GetMethod and vararg

Hi,


I can only suggest to look at the generated IL. For a class:



class c
{
internal static void Test()
{
Console.WriteLine(typeof(c).GetMethod("va1").CallingConvention);
Console.WriteLine(typeof(c).GetMethod("va2").CallingConvention);
va1(1, "b", 'c');
CallVarArg();
}

public static void va1(params object[] o)
{
if (o != null)
{
for (int i = 0; i < o.Length; i++)
Console.WriteLine(o[i].GetType());
}
}

internal static void CallVarArg()
{
va2(__arglist(1, "b", 'c'));
}

public static void va2(__arglist)
{
ArgIterator iterator = new ArgIterator(__arglist);
while (iterator.GetRemainingCount() > 0)
{
TypedReference tf = iterator.GetNextArg();
Console.WriteLine(TypedReference.GetTargetType(tf));
}
}
}

the generated IL for call va2(__arglist(1, "b", 'c')); is:

.maxstack 8

IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: ldstr "b"
IL_0007: ldc.i4.s 99
IL_0009: call void ElmarBoye.Samples.c::va2(int32, string, char)
IL_000e: nop
IL_000f: ret

I've used mixed types to show that there is no magic on the callers site, but there is no boxing as you would see for params object. The evaluation is happening at the callee's site - but that will only happen be if the method is managed. For C(++) the VarArgs arguments must be a native type - and no System.Object for example. See also:

http://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c

(For VC++ look into vadefs.h)


Regards, Elmar


No comments:

Post a Comment