C#结构最佳实践,可能的矛盾?

C#结构最佳实践,可能的矛盾?,c#,struct,initialization,immutability,C#,Struct,Initialization,Immutability,我知道在C#struct上大约有1000个问题。我想反复说明我理解了值语义、stackallocs的性能优势等。我的具体问题源于这篇msdn文章中关于何时在类上使用结构的内容。 首先,他们谈到了容器(特别是数组)的内联数据的好处。一次分配,以及数组中所有结构的不可由用户定义的默认初始化。然而,他们也强调结构应该是不可变的 如果我声明一个mystuct[]s=newmystruct[16],我有16个默认值内联的mystruct。如果我按照建议创建了一个没有外部可变性的“犹太”结构,那么这个结构

我知道在C#struct上大约有1000个问题。我想反复说明我理解了值语义、stackallocs的性能优势等。我的具体问题源于这篇msdn文章中关于何时在类上使用结构的内容。

首先,他们谈到了容器(特别是数组)的内联数据的好处。一次分配,以及数组中所有结构的不可由用户定义的默认初始化。然而,他们也强调结构应该是不可变的

如果我声明一个
mystuct[]s=newmystruct[16],我有16个默认值内联的mystruct。如果我按照建议创建了一个没有外部可变性的“犹太”结构,那么这个结构对我有何用处?我怀疑我是否打算独占一个0-积分和null的数组

当仅作为记录或属性返回(即单一数据传输)时,它们是否意味着不可变


如果在默认数组初始化和建议的不变性之间的特定冲突之前已经提出,请标记为重复。感谢您的见解。

两者之间没有实际矛盾:

执行
var s=newmystruct[16]之后
,确实您已经将16个
mystruct
实例的和数组初始化为默认值

但是,执行
s[0]=new mystruct()
不会改变数组第一个单元格的结构,而是将其替换为新结构


因此结构本身仍然是不可变的。

讨论的不可变性是通过结构的方法,而不是结构本身的值。结构的一个实例总是可以通过赋值进行变异——想想for循环中的整数循环变量;每次通过循环时,它都会发生变化

但是,对于框架的
System.Int32
struct(即
int
)来说,使用
DoubleIt
方法使基础整数的值加倍,而不进行一些明显的赋值操作(例如
++i;
实际上是
i=i+1;

考虑
string.Replace
StringBuilder.Replace
之间的区别。
System.String
类是不可变的。字符串上的Replace方法返回一个新的字符串实例,该实例表示替换操作后的原始字符串。StringBuilder的替换会对内部对象进行适当的替换

因此,如果我创建一个整数数组:

var ar = new int[] {1, 2, 3, 4};
我总是可以通过数组赋值来改变该数组(System.array实例、引用类型)的内容:

 ar[2] = 200;

没有意义的是在那个(整数)数组元素上调用一些变异方法

可能的重复:Eric Lippert的一篇好文章:如果预期的默认初始化是为了性能或方便,但是我必须循环每个默认初始化元素,使用基于用户定义构造函数的值覆盖所有字段,为什么不让我指定默认初始化的值?即使只进行了一次分配,我也看不到在结构上进行两次成员智能传递的好处。但您可以使用用户定义的数据初始化数组:
var x=new mystruct[]{new mystruct(),new mystruct(),new mystruct()}
将创建一个包含3个完全初始化的
mystruct
实例的数组……如果我有一个256元素的数组,并且我的结构中有一个int,我想成为
-1
,而不是
0
,初始化列表不是一个实用的解决方案。@schulmaster如何初始化一个新的
int
数组?@schulmaster no,不会的。但是一个循环会很好。如果你问在初始化数组时初始化数组“cells”有什么好处,我无法回答这个问题,我必须做一些阅读,现在已经接近午夜了,所以不是今天。我很确定这背后有一个很好的理由——c#是由一些聪明人设计的。