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

我只是想知道为什么结构,字符串等是不可变的?是什么原因使它们不可变,而其余对象却可变。什么被认为使对象不可变?


为可变和不可变对象分配和释放内存的方式有何不同?


C# .NET 不变性


ABOUTYOU
浏览 545回答 3
3回答

慕斯709654

结构不是...这就是为什么可变结构是邪恶的。创建可变结构会导致应用程序中各种奇怪的行为,因此,它们被认为是一个非常糟糕的主意(这是因为它们看起来像引用类型,但实际上是一个值类型,并在每次传递时都会被复制)他们周围)。另一方面,字符串是。这使它们具有固有的线程安全性,并允许通过字符串实习进行优化。如果您需要即时构造复杂的字符串,可以使用StringBuilder。

largeQ

当应用于结构和类时,可变性和不变性的概念具有不同的含义。可变类的一个关键方面(通常是关键的弱点)是,如果Foo有一个Bartype 字段List<Integer>,它包含对包含(1,2,3)的列表的引用,其他对同一列表进行引用的代码可以对其进行修改,这样Bar可保存对包含(4,5,6)的列表的引用,即使该其他代码无权访问Bar。相比之下,如果Foo具有Biz类型的字段System.Drawing.Point,则任何东西都可以修改其任何方面的唯一方法Biz将是对该字段具有写权限。结构的字段(公共字段和私有字段)可以通过任何可以更改存储该结构的存储位置的代码进行更改,而不能通过不能更改存储该结构的存储位置的任何代码进行更改。如果封装在结构中的所有信息都保存在其字段中,则该结构可以有效地将不可变类型的控制与可变类型的便利相结合,除非以消除这种便利的方式对结构进行编码(不幸的是,这是一些Microsoft程序员推荐的习惯)。结构的“问题”是,当在只读上下文(或不可变的位置)中在结构上调用方法(包括属性实现)时,系统将复制该结构,在临时副本上执行该方法,然后静默运行丢弃结果。这种行为使程序员提出了一个不幸的想法,即避免变异方法出现问题的方法是使许多结构不允许分段更新,而通过简单地用暴露字段替换属性可以更好地避免问题。顺便说一句,有些人抱怨说,当类属性返回方便地可变的结构时,对该结构的更改不会影响它所来自的类。我认为这是一件好事-返回的项目是一个结构,这一事实使行为明确(特别是如果它是一个暴露字段结构)。比较使用假设的struct和property的代码片段Drawing.Matrix与使用该类在Microsoft实现的实际属性的代码片段://假设结构公共结构{&nbsp; 公众持股量xx,xy,yx,yy,dx,dy;} Transform2d;//“ System.Drawing.Drawing2d.Matrix”的假设属性public Transform2d变换{get;}//“ System.Drawing.Drawing2d.Matrix”的实际属性public float []元素{get; }//使用假设的结构进行编码Transform2d myTransform = myMatrix.Transform;myTransform.dx + = 20;...使用myTransform的其他代码//使用实际的Microsoft属性进行编码float [] myArray = myMatrix.Elements;myArray [4] + = 20;...其他代码使用myArray查看实际的Microsoft属性,是否有任何方法可以确定写入是否myArray[4]会影响myMatrix?即使查看http://msdn.microsoft.com/zh-cn/library/system.drawing.drawing2d.matrix.elements.aspx页面,也有什么方法可说?如果该属性是使用基于结构的等效项编写的,则不会造成混淆;返回该结构的属性将只返回六个数字的当前值。更改myTransform.dx只不过是对未附加到任何其他内容的浮点变量的写操作。任何不喜欢变更myTransform.dx不会影响这一事实的人都myMatrix应该同样生气,因为写作myArray[4]不会影响myMatrix或者,不同的是的独立性myMatrix和myTransform是显而易见的,而独立myMatrix和myArray不。
打开App,查看更多内容
随时随地看视频慕课网APP