Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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"});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading