在这里的SO讨论之后,我已经多次看到这样的评论,即可变结构体是“邪恶的”(就像在这个问题的答案中)。
c#中的可变性和结构的实际问题是什么?
在这里的SO讨论之后,我已经多次看到这样的评论,即可变结构体是“邪恶的”(就像在这个问题的答案中)。
c#中的可变性和结构的实际问题是什么?
当前回答
我不会说可变性是邪恶的,但可变性通常是程序员急于提供最大功能的标志。在现实中,这通常是不需要的,反过来,使界面更小,更容易使用,更难使用错误(=更健壮)。
其中一个例子就是竞态条件中的读/写和写/写冲突。这些在不可变结构中根本不可能发生,因为写操作不是有效的操作。
另外,我认为可变性几乎从来都不是真正需要的,程序员只是认为它在未来可能会出现。例如,改变日期是没有意义的。相反,在旧日期的基础上创建一个新的日期。这是一个廉价的操作,所以性能不是一个考虑因素。
其他回答
结构是值类型,这意味着它们在传递时被复制。
所以如果你改变了一份副本,你只是改变了那份副本,而不是原件,也不是周围可能存在的其他副本。
如果你的struct是不可变的,那么所有通过值传递的自动副本都是相同的。
如果你想要改变它,你必须有意识地用修改过的数据创建一个结构的新实例。(非副本)
可变结构体并不邪恶。
在高绩效环境下,它们是绝对必要的。例如,当缓存线和垃圾收集成为瓶颈时。
我不认为在这些完全有效的用例中使用不可变结构体是“邪恶的”。
我可以看到c#的语法没有帮助区分值类型或引用类型的成员的访问,所以我完全赞成使用强制不变性的不可变结构,而不是可变结构。
然而,与其简单地给不可变结构贴上“邪恶”的标签,我建议接受这种语言,提倡更有帮助和建设性的经验法则。
例如:"struct是默认复制的值类型。如果你不想复制他们,你需要一份推荐信。 “首先尝试使用只读结构体”。
Value types basically represents immutable concepts. Fx, it makes no sense to have a mathematical value such as an integer, vector etc. and then be able to modify it. That would be like redefining the meaning of a value. Instead of changing a value type, it makes more sense to assign another unique value. Think about the fact that value types are compared by comparing all the values of its properties. The point is that if the properties are the same then it is the same universal representation of that value.
正如Konrad所提到的,更改日期也没有意义,因为值代表的是唯一的时间点,而不是具有任何状态或上下文依赖关系的时间对象的实例。
希望这能让你明白。可以肯定的是,它更多的是关于您试图用值类型捕获的概念,而不是实际的细节。
如果你曾经用C/ c++这样的语言编程,结构体可以作为可变的。只要把球传给裁判,没有什么会出错的。我发现的唯一问题是c#编译器的限制,在某些情况下,我无法强迫这个愚蠢的东西使用对结构的引用,而不是Copy(比如当结构是c#类的一部分时)。
所以,可变结构体不是邪恶的,是c#把它们变成了邪恶的。我一直在c++中使用可变结构体,它们非常方便和直观。相比之下,c#让我完全放弃了作为类成员的结构体,因为它们处理对象的方式。他们的便利让我们付出了代价。
我不会说可变性是邪恶的,但可变性通常是程序员急于提供最大功能的标志。在现实中,这通常是不需要的,反过来,使界面更小,更容易使用,更难使用错误(=更健壮)。
其中一个例子就是竞态条件中的读/写和写/写冲突。这些在不可变结构中根本不可能发生,因为写操作不是有效的操作。
另外,我认为可变性几乎从来都不是真正需要的,程序员只是认为它在未来可能会出现。例如,改变日期是没有意义的。相反,在旧日期的基础上创建一个新的日期。这是一个廉价的操作,所以性能不是一个考虑因素。