如果DateTime是不可变的,为什么以下工作?

我以为我理解了Immutable的意思,但我不明白为什么以下编译和工作:

DateTime dt = DateTime.Now; Console.WriteLine(dt); 

复制并粘贴下一部分几次

 dt = DateTime.Now; Console.WriteLine(dt); Console.ReadLine(); 

正如预期的那样,它会运行,当我按下回车键时,它会在下次显示…我认为这是不可能的,我需要创建一个新对象。 为什么允许/工作? 或者,这本书我的工作是错误的,而且DateTime不是不可变的(但是我已经在几个来源上读过这个)?

DateTime对象本身是不可变的,但不是引用dt 。 允许dt更改它指向的DateTime对象。 不变性是指我们无法更改DateTime对象内的变量。

例如,我们不能去

 dt.Day = 3; 

dt本身只是一个指向DateTime对象的引用变量。 根据其定义,允许变化

正如pst所提到的那样, readonly和const可能更接近你所想的,你不能改变变量的值。


旁注: DateTime是一个Structure ,因此是一个值类型 ,我通过调用dt ‘来误导。 但是,我认为dt仍然只是一个变量’指向’一个不可变对象,而变量本身仍然是可变的。 感谢dan04指出这一点。

您只是告诉变量dt引用DateTime的不同实例。 每次访问时, DateTime.Now属性都会生成一个新的DateTime实例。

Now属性类似于:

  DateTime Now { get { // Get the OS time return new DateTime(year, month, day, hour, min, sec...) } } 

(技术上是错误的,Now在内部调用调用操作系统的UtcNow :-),但是你得到了这个想法)。

DateTime.Now是DateTime的工厂:-)

看到这个 。

查看所有这些方法说明…它总是说“返回一个新的DateTime …”。 它不会更改当前的DateTime对象,因此它是不可变的。

变量引用是另一回事。 可以把它看作是指向实际不可变DateTime对象的指针,可以将其更改为指向不同的对象。

如果非平凡结构类型的实例存储在可写存储位置(非readonly字段,局部变量,数组槽等)中,则其所有字段都是可变的。 如果实例存储在不可写的存储位置( readonly字段,编译器生成的临时值等),则其字段都不可变。 “不可变结构类型”的概念是用词不当,因为声明:

 myStruct1 = myStruct2; // Assume variables are of the same structure type 

如果myStruct1是可写的,则将myStruct1所有公共和私有字段替换为myStruct1的相应字段; 如果myStruct1不可写,则该语句将生成编译时错误。 结构的代码在这个问题上没有发言权,甚至不会被告知发生了分配

虽然DateTime没有提供可以修改现有DateTime实例的方法, 除非通过整个结构赋值 ,但它无法阻止代码用一个实例的内容覆盖另一个实例的字段,就像dateTimeVariable = DateTime.Now;

答案很简单。 DateTime不是不可变的。 这是一个结构。 而且我不知道如何拥有一个不可变的结构。

如果你这样做:

 DateTime d1 = DateTime.Now; DateTime d2 = DateTime.Now; d1 = d2; 

然后,结构d1将被d2的值覆盖。

(DateTime实际上只有一个值。如果你运行一个反编译器,它是一个名为“ticks”的私有字段我相信。)

没有参考的东西,或其他任何时髦的东西。