c# - 动态生成的 MSIL 中奇怪的 DateTime ToString 行为

标签 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 等。 正如您所看到的,您为它提供了属性和实例的名称,它会创建一个委托(delegate)来检索该特定实例中属性的字符串值。一切正常,直到出现 DateTime。我使用分配给属性的 DateTime.Now 进行测试,每次运行该函数时,我都会得到奇怪的值,例如: enter image description here 我尝试放置一个 IFormatProvider 以防万一 - 结果相同。 .NET版本是4.7.1, 提前致谢。

最佳答案

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

关于c# - 动态生成的 MSIL 中奇怪的 DateTime ToString 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50395976/

相关文章:

c# - 如何在 ASP MVC 的局部 View 中实现选项卡

c# - 如何将我的标题基于窗口的宽度 W/O 不必重复编写相同的代码

.net - Domain Events、EventHandlers、Dispatcher 在哪一层

c# - 在 C# 中为所有事件和委托(delegate)创建一个包罗万象的处理程序

c# - razor 如何将字节 [8] 转换为字符串?

c# - 向多个目标类中的方法调用注入(inject)外部参数

c# - MVC 路由在根目录中拾取区域 Controller

c# - 制作一个特定于类的泛型方法

c# - 在哪里可以找到MSIL字符串常量中的转义字符列表?

.net - 在 .NET 中,当您传递一个类实例/接口(interface)作为参数时,您传递一个对象还是完整的 vtable