首页 > 解决方案 > 您可以使用反射更改 DateTime 对象中 _dateData 的私有字段值吗?

问题描述

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

根据 DateTime 类的源代码(https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/DateTime.cs)有一个名为“ _dateData”包含对象的实际日期数据。我尝试以正常方式使用反射来改变它,但这似乎没有任何影响。

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 是一个只读变量。如果是这种情况,是否有另一种方法可以改变我所缺少的价值观?

标签: c#.net-core

解决方案


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

推荐阅读