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

时间:2011-02-19 17:40:52

标签: c# .net datetime

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

DateTime dt = DateTime.Now;

Console.WriteLine(dt);

复制并粘贴下一部分

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

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

6 个答案:

答案 0 :(得分:45)

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

例如,我们不能去

dt.Day = 3;

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

正如pst提到的那样,readonlyconst可能更接近您的想法,而您无法更改变量的值。


旁注:DateTimeStructure,因此是value type,我通过调用dt'参考'来误导我。但是,我认为dt仍然只是一个变量'指向'一个不可变对象,而变量本身仍然是可变的。感谢dan04指出了这一点。

答案 1 :(得分:19)

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

答案 2 :(得分:5)

Now属性类似于:

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

(技术上是假的,Now在内部调用调用操作系统的UtcNow :-),但你明白了。)

DateTime.Now是DateTime的工厂: - )

答案 3 :(得分:1)

请参阅this

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

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

答案 4 :(得分:0)

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

myStruct1 = myStruct2; // Assume variables are of the same structure type
如果myStruct1可写,

myStruct1的所有公共和私有字段替换为myStruct2的相应字段;如果myStruct1不可写,则该语句将生成编译时错误。 结构的代码在此事上没有发言权,甚至不会通知发生的任务

虽然DateTime没有提供现有DateTime实例可以修改的方法,除了整个结构分配,但它无法阻止代码覆盖字段一个实例与另一个实例的内容,与dateTimeVariable = DateTime.Now;一样。

答案 5 :(得分:0)

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

如果你这样做:

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

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

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

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