我知道C#结构上大约有1,000个问题。我想进行迭代,以了解值语义,stackallocs的性能优势等。我的具体问题来自于这篇msdn文章,有关何时在类上使用结构。 MSDN struct vs class C#
首先,他们谈到了容器(尤其是数组)的内联数据的好处。一种分配,以及数组中所有结构的用户无法定义的默认初始化。但是,他们也强调结构应该是不变的。
如果我声明mystuct[] s = new mystruct[16];
,则有16个mystruct
,其默认值是内联的。如果我按照建议创建了没有外部可变性的“洁净”结构,那么该结构对我有什么用?我怀疑我打算只包含0个整数和null的数组。
当仅用作记录或属性返回(即单一数据传输)时,它们是否意味着不可变?
如果之前已经讨论了默认数组初始化和建议的不变性之间的特定冲突,请标记为重复。感谢您的任何见识。
答案 0 :(得分:1)
两者之间没有实际矛盾:
执行var s = new mystruct[16];
后,确实已经将mystruct
的16个实例数组初始化为默认值。
但是,进行s[0] = new mystruct(<arguments list here>)
不会使数组的第一个单元格的结构发生突变,而是将其替换为新的结构。
所以它本身的结构仍然是不可变的。
答案 1 :(得分:1)
所讨论的不变性是通过结构的方法,而不是结构本身的值。一个结构体的实例总是可以通过赋值来进行突变-考虑一下for循环中的整数循环变量;每次循环都会改变它。
但是,对于框架的System.Int32
结构(即int
)来说,使用DoubleIt
方法会导致基础整数的值加倍而没有任何意义是没有意义的明显的赋值操作(例如++i;
实际上是i=i+1;
的方式。)
请考虑string.Replace
和StringBuilder.Replace
之间的区别。 System.String
类是不可变的。字符串上的Replace方法返回一个新的字符串实例,该实例表示替换操作后的原始字符串。 StringBuilder的Replace会进行替换,从而使内部对象发生变异。
因此,如果我创建一个整数数组:
var ar = new int[] {1, 2, 3, 4};
我总是可以通过分配数组来改变该数组的内容(一个System.Array实例,一个引用类型):
ar[2] = 200;
没有任何意义的是在那个(整数)数组元素上调用某种变异方法。