为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

ABOUTYOU 2019-11-27 10:42:21
我只是想知道为什么结构,字符串等是不可变的?是什么原因使它们不可变,而其余对象却可变。什么被认为使对象不可变?为可变和不可变对象分配和释放内存的方式有何不同?C# .NET 不变性
查看完整描述

3 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

结构不是...这就是为什么可变结构是邪恶的。

创建可变结构会导致应用程序中各种奇怪的行为,因此,它们被认为是一个非常糟糕的主意(这是因为它们看起来像引用类型,但实际上是一个值类型,并在每次传递时都会被复制)他们周围)。

另一方面,字符串是。这使它们具有固有的线程安全性,并允许通过字符串实习进行优化。如果您需要即时构造复杂的字符串,可以使用StringBuilder


查看完整回答
反对 回复 2019-11-27
?
largeQ

TA贡献2039条经验 获得超7个赞

当应用于结构和类时,可变性和不变性的概念具有不同的含义。可变类的一个关键方面(通常是关键的弱点)是,如果Foo有一个Bartype 字段List<Integer>,它包含对包含(1,2,3)的列表的引用,其他对同一列表进行引用的代码可以对其进行修改,这样Bar可保存对包含(4,5,6)的列表的引用,即使该其他代码无权访问Bar。相比之下,如果Foo具有Biz类型的字段System.Drawing.Point,则任何东西都可以修改其任何方面的唯一方法Biz将是对该字段具有写权限。


结构的字段(公共字段和私有字段)可以通过任何可以更改存储该结构的存储位置的代码进行更改,而不能通过不能更改存储该结构的存储位置的任何代码进行更改。如果封装在结构中的所有信息都保存在其字段中,则该结构可以有效地将不可变类型的控制与可变类型的便利相结合,除非以消除这种便利的方式对结构进行编码(不幸的是,这是一些Microsoft程序员推荐的习惯)。


结构的“问题”是,当在只读上下文(或不可变的位置)中在结构上调用方法(包括属性实现)时,系统将复制该结构,在临时副本上执行该方法,然后静默运行丢弃结果。这种行为使程序员提出了一个不幸的想法,即避免变异方法出现问题的方法是使许多结构不允许分段更新,而通过简单地用暴露字段替换属性可以更好地避免问题。


顺便说一句,有些人抱怨说,当类属性返回方便地可变的结构时,对该结构的更改不会影响它所来自的类。我认为这是一件好事-返回的项目是一个结构,这一事实使行为明确(特别是如果它是一个暴露字段结构)。比较使用假设的struct和property的代码片段Drawing.Matrix与使用该类在Microsoft实现的实际属性的代码片段:


//假设结构

公共结构{

  公众持股量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不。


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 583 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信