C# 为什么日期结构是不可变的?

C# 为什么日期结构是不可变的?,c#,objective-c,C#,Objective C,我想知道为什么像C#的DateTime和Obj-C的NSDate这样的日期结构和对象是不可变的 我在寻找这种设计背后的原因,以及使这些信息不可变的好处,而不仅仅是“因为它们可以” 更新: 似乎有一个类似的问题,对我的问题有一个极好的答案,但具体针对Java,可以在这里找到: 结合对我问题的回答,我不确定目标C是什么,但在C中,日期是由一个简单的数字类型支持的。因为一个数字是不可变的,所以基于它的日期也是不可变的。我不确定Objective-C是什么,但是日期时间是不可变的,因为使它们可变实际上很

我想知道为什么像C#的DateTime和Obj-C的NSDate这样的日期结构和对象是不可变的

我在寻找这种设计背后的原因,以及使这些信息不可变的好处,而不仅仅是“因为它们可以”

更新: 似乎有一个类似的问题,对我的问题有一个极好的答案,但具体针对Java,可以在这里找到:


结合对我问题的回答,我不确定目标C是什么,但在C中,日期是由一个简单的数字类型支持的。因为一个数字是不可变的,所以基于它的日期也是不可变的。

我不确定Objective-C是什么,但是
日期时间是不可变的,因为使它们可变实际上很难正确地做到

这是因为如果您从方法(包括属性)返回它们,您将得到一个副本,而不是原始副本。这可能意味着以下代码将无法按预期运行:

someObject.Timestamp.SetSeconds(10.0);
其中,
SetSeconds
无效,并改变基础结构


它不会做任何事情,因为你会得到一个Timestamp对象的副本,给它加上10秒,然后对该副本什么也不做。

不变性使很多事情变得更容易。如果你不必担心你的内心会发生变化,那么你就不必编写很多保护代码。你不必做很多假设。事情不出差错的可能性很大

字符串、日期和其他类型的公共对象在现代语言中是不可变的,因为它简化了编译器、框架,并且意味着编译器在进行优化时可以自由地进行假设

要点是,只需很小的代价(如果你想更改值,就必须创建一个新对象),你就可以获得很多真正的性能、稳定性和可靠性。

为在.net中使用而编写的绝大多数(99.99%)结构(无论是在框架中定义的还是在用户代码中定义的)要么代表一个固定的独立值集合,可以接受对其类型合法的值的任何组合(例如,包含
X
Y
点),或者表示单个抽象实体。Microsoft在.net中的结构使用指南未能区分这些不同的使用场景,假设所有结构都符合第二种模式,不幸的结果是,第一种类型的结构通常以一种只适用于第二种类型的结构的方式编写。然而,事实上,.net中的
DateTime
结构肯定不符合独立值集合的条件,因此指南完全适用于它


首先,
DateTime
直接公开任何字段并不是一个好方法。没有明确的
DateTime
结构封装的独立值集,因此不清楚任何字段的类型。此外,许多属性不能被合理地变异,因为它们不是独立的;例如,如果一个人有一个表示2012年2月29日的
DateTime
,他将年份设置为2011年,然后将月份设置为3,那么结果日期应该是什么?只有使用方法对
DateTime
进行变异才有意义,不幸的是,vb.net和C#都会假装允许对只读结构实例调用变异方法,方法是静默地替换代码,如
MyList[3]。MutatingMethod()和坏得可怕的
var-temp=MyList[3];temp.MutatingMethod()。对于Microsoft来说,通过定义一个属性来解决这个问题应该相当简单,这样在只读实例上调用一个带有该属性的方法应该会导致编译器错误,而不是代码中断,但不幸的是,Microsoft的语言人宁愿声明可变结构是邪恶的,与其修复语言,使其不受影响,

不如说,既然字符串是不可变的,那么由字符串支持的bean也是不可变的(例如,它们的“名称”和“标题”属性)?您可以提供非常容易地更新该数字的方法。确实,您可以同时执行这两个操作。有很多更好的理由让数据类型保持不变。我只是认为这可能是.NET选择日期不可变的原因之一。@IANMERSER:不是重复的,不可变结构可能是由于不同的原因造成的。因为
DateTime
表示单个值,所以允许对其进行更改是没有意义的。此外,可变结构是真正的邪恶。字符串也表示单个值,但有一个名为NSMutableString的类。时间可能会改变,例如时钟类中包含的日期。这是唯一的好答案。另外两个专门处理.NET DateTime对象,并错误地解释了为什么它们是不可变的。+1。不过,我不想做同样的论证,因为NSString是不可变的,但它有一个可变的子类,所以关于您下面没有更改的保证似乎并不适用于所有情况。@Thilo-从技术上讲,您可以做很多事情来解决不可变性,但是这样做通常是危险的,并且可能导致不可预测的结果。@evanmcdonnal:我引用了一个实际的方法,这是错误的,但是
Properties
和可变结构都有众所周知的和有文档记录的顾虑。如果您调用的某个对象对返回的结构进行了变异,则该变异将丢失,除非您将其保留在调用端。如果您要更改该值,则必须创建一个新对象可能是负数。例如,如果您有一个正在执行数千次更新的SortedList,那么垃圾收集最终必须处理数千次新的日期时间。出于这个原因,我通常编写一个带有comparia的简单可变类