gpt4 book ai didi

c# - DateTime 对象未从 MSIL 返回正确的值

转载 作者:太空狗 更新时间:2023-10-30 01:35:43 24 4
gpt4 key购买 nike

我注意到我在 MSIL 中编写的一些用于高速获取对象的任意属性的代码没有获取 DateTime 属性的正确值。无论 DateTime 对象的实际值如何,它总是返回相同的值,例如。年份总是返回 1,毫秒返回 88,等等......

LINQPad 中的一些精简代码演示了这一点。获取 mc.Inner.Age 返回正确的值,mc.Inner.DateOfBirth 返回正确的 DateTime 值,但尝试获取 mc.Inner.DateOfBirth 的任何特定部分总是返回不正确的值。我已经查看并尝试了一些方法来让它工作,但我还没有足够的经验来真正知道此时还可以尝试什么。我不确定我的代码中是否存在细微的错误,或者 DateTime 对象是否存在某些特殊情况导致发生这种情况。

void Main()
{
var mc = new MyClass();
mc.FirstName = "Jane";
mc.LastName = "Doe";
mc.Inner.DateOfBirth = new DateTime(1960, 2, 13);
mc.Inner.Age = 54;

Object obj = mc;
obj = this.GetObjectProperty(obj, "Inner");
obj = this.GetObjectProperty(obj, "DateOfBirth");
obj = this.GetObjectProperty(obj, "Year");
obj.Dump();

obj = mc;
obj = obj.GetType().GetProperty("Inner").GetValue(obj);
obj = obj.GetType().GetProperty("DateOfBirth").GetValue(obj);
obj = obj.GetType().GetProperty("Year").GetValue(obj);
obj.Dump();
}

private Object GetObjectProperty(Object obj, String property)
{
var m = obj.GetType().GetMethod("get_" + property, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);

DynamicMethod meth = new DynamicMethod("GetObjectProperty", typeof(Object), new [] { typeof(Object) }, obj.GetType());
var il = meth.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, obj.GetType());
il.EmitCall(OpCodes.Call, m, null);

if (m.ReturnType.IsValueType)
il.Emit(OpCodes.Box, m.ReturnType);

il.Emit(OpCodes.Ret);

return ((GetObjectPropertyDelegate)meth.CreateDelegate(typeof(GetObjectPropertyDelegate), obj))();
}

private delegate Object GetObjectPropertyDelegate();

public class MyClass
{
public MyClass()
{
this.Inner = new MyInnerClass();
}

public String FirstName { get; set; }
public String LastName { get; set; }
public MyInnerClass Inner { get; set; }
}

public class MyInnerClass
{
public DateTime DateOfBirth { get; set; }
public int Age { get; set; }
}

最佳答案

对值类型的调用必须传递一个托管指针作为 this 参数。这是为了支持值类型的变异方法。

您正在将对象引用传递给值类型的盒装实例。可能是 DateTime.Year 的 jitted 代码正在访问一些随机的内存位。你破坏了内存安全。此 IL 不可验证。我不记得装箱和未装箱的内存布局,但您可能正在阅读(部分)方法表或 vtable 或对象 header 的其他部分。

使用Unbox获取指向装箱实例内容的托管指针。

关于c# - DateTime 对象未从 MSIL 返回正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587083/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com