使用索引/范围对数组进行切片是不是会创建数组的副本
Posted
技术标签:
【中文标题】使用索引/范围对数组进行切片是不是会创建数组的副本【英文标题】:Does slicing an array using Index/Range create a copy of the array使用索引/范围对数组进行切片是否会创建数组的副本 【发布时间】:2019-10-10 20:33:39 【问题描述】:随着 C# 8.0 引入了结构体 Index
和 Range
,我们现在可以轻松获得数组的切片,执行类似的操作
string[] baseArray = "a","b", "c", "d", "e", "f";
var arr = baseArray[1..^2];
像这样对数组进行切片会复制数组吗?或者它没有像ArraySegment<T>
那样复制吗?
【问题讨论】:
你的测试不是真的有效。您所做的只是创建结构,而不是使用它们。例如,Linq 版本只返回一个IEnumerable
,但实际上并没有做任何事情。
@DavidG 好的,感谢您指出这一点。删除了我的测试用例。然而,原来的问题仍然存在,它是否复制了数组?
【参考方案1】:
自己试试吧:
string[] baseArray = "a", "b", "c", "d", "e", "f" ;
var arr = baseArray[1..^2];
Debug.WriteLine(arr[0]);
Debug.WriteLine(baseArray[1]);
arr[0] = "hello";
Debug.WriteLine(arr[0]);
Debug.WriteLine(baseArray[1]);
输出
b
b
hello
b
我们可以断定 string 数组被复制了。
但是,如果我们使用对象数组:
public class Foo
public string Bar get; set;
Foo[] baseArray =
new Foo Bar = "a" ,
new Foo Bar = "b" ,
new Foo Bar = "c" ,
new Foo Bar = "d" ,
new Foo Bar = "e" ,
new Foo Bar = "f"
;
var arr = baseArray[1..^2];
Debug.WriteLine(arr[0].Bar);
Debug.WriteLine(baseArray[1].Bar);
arr[0].Bar = "hello";
Debug.WriteLine(arr[0].Bar);
Debug.WriteLine(baseArray[1].Bar);
arr[0] = new Foo Bar = "World" ;
Debug.WriteLine(arr[0].Bar);
Debug.WriteLine(baseArray[1].Bar);
这个输出
b
b
hello
hello
World
hello
数组中的对象不会被复制而是被引用。
在数组中设置另一个对象不会影响另一个。
【讨论】:
以上是关于使用索引/范围对数组进行切片是不是会创建数组的副本的主要内容,如果未能解决你的问题,请参考以下文章
将 Pandas DataFrame 切片成新的 DataFrame