动态生成的MSIL中的奇怪日期时间ToString行为

时间:2018-05-17 16:05:47

标签: c# .net cil

我需要在运行时动态构建属性检索方法并快速执行,所以我使用Reflection Emit开发了一个解决方案:

public static void Func(string properyName, A obj)
{
    var type = obj.GetType();
    var dynamicMethod = new DynamicMethod("PropertyExtractor", typeof(string), new[] { typeof(A) }, type, true);
    var ilGen = dynamicMethod.GetILGenerator();
    var getMethod = type.GetMethod($"get_{properyName}");
    var property = type.GetProperty(properyName);

    ilGen.Emit(OpCodes.Ldarg_0);
    ilGen.Emit(OpCodes.Castclass, type);
    ilGen.Emit(OpCodes.Callvirt, getMethod);
    var toStringMethod = property.PropertyType.GetMethod("ToString", Type.EmptyTypes);
    ilGen.Emit(OpCodes.Call, toStringMethod);
    ilGen.Emit(OpCodes.Ret);
    var @delegate = (F)dynamicMethod.CreateDelegate(typeof(F));
    var a = @delegate(obj);
}

public delegate string F(A obj); 

public abstract class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class B : A 
{ 
    public DateTime Timestamp { get; set; } 
} 

以下是调用它的代码:

var obj = new B
{
    Id = 1,
    Name = "SomeName",
    Timestamp = DateTime.Today
};

Func("Timestamp", obj);

这只是为了测试它在名为Func的方法中的原因,该方法的参数类型为A,等等。 如您所见,您可以为其指定属性和实例的名称,并创建一个委托来检索该特定实例中属性的字符串值。一切正常,直到有DateTime。我测试了DateTime.Now分配给一个属性,每次运行该函数时都会得到奇怪的值,如:enter image description here 我试图放一个IFormatProvider以防万一 - 相同的结果。 .NET版本是4.7.1, 提前谢谢。

1 个答案:

答案 0 :(得分:2)

我发现了问题。 DateTime是值类型,ToString需要将地址加载到评估堆栈,而不是值。当我添加时间的局部变量并添加指令以将值存储在局部变量中,然后加载该变量的地址时,它就被解析了。感谢所有回复的人。

相关问题