Translate parameters in object arrays into their own type in .NET Emit

59 views Asked by At

There are some definations:

public class Message
{
    public SayType Say(string name)
    {
        Console.Write("Hello," + name );
        return SayType.Name;
    }
}

public enum SayType
{
    Name
}
 public delegate SayType SayDelegate(Message message,params object[] o);
    public void Test()
    {
        DynamicMethod dynamicMethod = 
            new DynamicMethod("Say",typeof(SayType),new Type[]{typeof(Message),typeof(object)});
               var il = dynamicMethod.GetILGenerator();
        il.Emit(OpCodes.Ldarg,0);
        il.Emit(OpCodes.Ldarg,1);
        il.Emit(OpCodes.Ldc_I4,0);
        il.Emit(OpCodes.Ldelem_Ref);
        il.Emit(OpCodes.Castclass, typeof(string));
        il.Emit(OpCodes.Callvirt,typeof(Message).GetMethods()[0]);
        il.Emit(OpCodes.Ret);
        System.Delegate delegates = dynamicMethod.CreateDelegate(typeof(SayDelegate));
        delegates.DynamicInvoke(new Message(),"b");
}

The second segement of the code is designed for the Message.Say specially. Which means I know there is just one parameter in the object arrays.

What I want is to cast the first member in the object arrays as string.

However, I got a bug:

Unhandled exception. System.ArgumentException: Object of type 'System.String' ca
nnot be converted to type 'System.Object[]'.

How can I solve it?

1

There are 1 answers

2
Sweeper On BEST ANSWER

DynamicInvoke doesn't know that the second parameter of your delegate is a params, so it doesn't wrap the argument "b" in an object[]. params is only a C# language feature after all.

So either don't use DynamicInvoke:

((SayDelegate)delegates).Invoke(new Message(),"b");

Or wrap "e" in a object[] yourself.

delegates.DynamicInvoke(new Message(), new object[] {"b"});