System.Array.Clone() 是不是保证克隆值类型?

Posted

技术标签:

【中文标题】System.Array.Clone() 是不是保证克隆值类型?【英文标题】:Is System.Array.Clone() guaranteed to clone value types?System.Array.Clone() 是否保证克隆值类型? 【发布时间】:2014-08-07 17:46:50 【问题描述】:
int[] array1 = new[]  1, 2, 3 ;
int[] array2 = (int[])array1.Clone();

array2[0] = 9;

Debug.Assert(array1[0] != array2[0]);

这很好用。 Clone() 做了一个浅拷贝,但是数组类型是值类型,所以它们也会被克隆。

我的问题是这在语言规范中是否明确,或者这是否只是当前实现的产物?

我的怀疑是由于 System.Array 通过运行时泛型在幕后“不可见”地支持值类型。查看公共方法,您会期望值类型被装箱。

【问题讨论】:

您为什么希望值类型被装箱? 值类型值的行为类似于值,而不是引用。将它们存储在数组中并不会突然改变。或任何其他类类型。当然,这很大程度上是设计使然。 【参考方案1】:

之所以有效,是因为两个数组绝对不可能共享同一个值类型的实例。

规范没有具体说明Array.Clone 在值类型中的行为与在引用类型中的行为。但是规范确实说值类型的实例在赋值时被逐位复制。因此,当array1[i] 复制到array2[i] 时,您会在索引i 处获得实例的克隆。总是。

但请记住,如果值类型具有引用类型的字段,则只会复制引用 - 而不是引用类型的实例。

我的疑问是 Array 的潜在拳击是否会否定这一点。即,盒装引用被复制而不是基础值类型。

即使array1[i] 在克隆过程中被装箱,它也必须被取消装箱,这样您最终会得到int[] 而不是object[]。该值将在拆箱时被克隆。

【讨论】:

我接受值类型分配是位复制的,但我的疑问是 Array 的潜在装箱是否会否定这一点。即,盒装引用被复制而不是基础值类型。 @GazTheDestroyer 我已经更新了我的答案。但同样,它归结为我在第一句话中所说的:“两个数组绝对不可能共享同一个值类型的实例”。值类型的实例存在于其容器中。所以如果你有两个容器(array1array2),并且每个容器都有自己的内存空间,一个int就不能同时存在于两个地方。 是的,感谢您的澄清。我玩过一些代码,并意识到我困惑的症结在于认为有某种方法可以在不更改引用本身的情况下更新盒装值的“内容”。你不能,它只是得到一个新的“盒子”。

以上是关于System.Array.Clone() 是不是保证克隆值类型?的主要内容,如果未能解决你的问题,请参考以下文章

C# 面试题及答案31-60

等保测评结论为差,是不是表示等保工作白做了?

等保测评结论为差,是不是表示等保工作白做了?

三级等保是不是icp?两者是一样吗?

三级等保是不是icp?两者是一样吗?

线程的上下文保存在哪里,是不是可以通过编程方式访问(无需修改内核)?