C# 能否使用反射更改DateTime对象中_dateData的私有字段值?

C# 能否使用反射更改DateTime对象中_dateData的私有字段值?,c#,.net-core,C#,.net Core,为了练习,我一直尝试在几种不同的类型上使用反射。目前我正在努力处理DateTime对象。 我试图在不创建新对象的情况下更改现有DateTime对象中的数据(显然不是我应该如何使用它们,但这只是为了练习) 根据DateTime类()的源代码,有一个名为“\u dateData”的私有ulong字段,其中包含对象的实际日期数据。 我试着用正常的方式使用反射来改变这一点,但这似乎没有任何影响 DateTime dateTime = DateTime.Now; FieldInfo dateData =

为了练习,我一直尝试在几种不同的类型上使用反射。目前我正在努力处理DateTime对象。 我试图在不创建新对象的情况下更改现有DateTime对象中的数据(显然不是我应该如何使用它们,但这只是为了练习)

根据DateTime类()的源代码,有一个名为“\u dateData”的私有ulong字段,其中包含对象的实际日期数据。 我试着用正常的方式使用反射来改变这一点,但这似乎没有任何影响

DateTime dateTime = DateTime.Now;

FieldInfo dateData = typeof(DateTime).GetField("_dateData",
    BindingFlags.Instance | BindingFlags.NonPublic);

Console.WriteLine(dateTime.ToString()); // Log date before change
Console.WriteLine(dateData.GetValue(dateTime)); // Log dateData before change

dateData.SetValue(dateTime, (ulong)0); // Change dateData

Console.WriteLine(dateTime.ToString()); // Log date after change - No difference
Console.WriteLine(dateData.GetValue(dateTime)); // Log dateData after change - No difference
代码没有给出任何编译时或运行时错误。我希望代码片段能够实际更改新创建的DateTime对象的值,但它似乎没有改变任何东西。。。
我猜这是因为dateData是一个只读变量。如果是这种情况,是否有其他方法可以更改我缺少的值?

这当然是可能的,但无法以您期望的方式实现,因为
DateTime
是一种值类型

相反,请使用以下命令:

// dateData.SetValue(dateTime, (ulong)0); // Change dateData
TypedReference typed = __makeref(dateTime);
dateData.SetValueDirect(typed, (ulong)0); // Change dateData
这将创建一个指向内存中的值类型的托管引用指针,允许您通过反射对其进行修改

输出:

12/09/2019 15:17:12
9860411019182991289
01/01/0001 00:00:00
0

“如果是这样的话,有没有其他方法可以改变我所缺少的价值观?”这只是一个奇怪的学术练习,还是你有一些实际的使用案例?DateTime是一种价值观类型。调用SetValue时,将其值作为
对象传入。这将导致对DateTime进行装箱(这将把DateTime的值复制到装箱的DateTime中)。然后在装箱对象中更改private字段的值,而不是在原始对象中更改它。如果您想弄清楚反射是如何工作的,那么如果您将自己限制为引用,您将不会那么困惑types@HimBromBeere只是个练习。除了在某些情况下可以节省非常少量的垃圾收集时间之外,没有实际的用例?同样,DateTime是一种值类型-没有垃圾收集needed@Flydog57这是有道理的。我忘了DateTime实际上是结构而不是类。谢谢你的回答!很好,谢谢!而且uu makeref很有意思。在上面找到了一个信息丰富的博客: