Is there a generic CIL code to convert any type instance to string?

北战南征 提交于 2019-12-05 10:56:39

Edit:

Also important: note that I am using typeof(object).GetMethod(...), not typeof(T).GetMethod(...) - your line argument_type.GetType().GetMethod( "ToString" ); looks very suspect IMO.


I suspect the issue is that you are loading a local/argument, rather than the address of a local/argument - in the line immediately before what is shown. Constrained needs this so that it can correctly perform the static-call implementation; for the virtual-call implementation, it can simply dereference this to get the actual reference.

Other than that: Constrained should work fine - see below (in particular, note the Ldarga_S). Of course, another option is to use Box, but this will have more overhead. Constrained is the ideal way of calling ToString on an arbitrary type.

using System;
using System.Reflection.Emit;

public class RefTypeNoImpl { }
public class RefTypeImpl { public override string ToString() { return "foo"; } }
public struct ValTypeNoImpl { }
public struct ValTypeImpl { public override string ToString() { return "bar"; } }

static class Program
{
    static void Main()
    {
        Test<RefTypeNoImpl>();
        Test<RefTypeImpl>();
        Test<ValTypeNoImpl>();
        Test<ValTypeImpl>();
    }


    static void Test<T>() where T : new()
    {
        var dm = new DynamicMethod("foo", typeof(string), new[] { typeof(T) });
        var il = dm.GetILGenerator();
        il.Emit(OpCodes.Ldarga_S, 0);
        il.Emit(OpCodes.Constrained, typeof(T));
        il.Emit(OpCodes.Callvirt, typeof(object).GetMethod("ToString"));
        il.Emit(OpCodes.Ret);
        var method = (Func<T, string>)dm.CreateDelegate(typeof(Func<T, string>));
        Console.WriteLine(method(new T()));
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!