【问题标题】:Does slicing an array using Index/Range create a copy of the array使用索引/范围对数组进行切片是否会创建数组的副本
【发布时间】:2019-10-10 20:33:39
【问题描述】:

随着 C# 8.0 引入了结构体 IndexRange,我们现在可以轻松获得数组的切片,执行类似的操作

string[] baseArray = {"a","b", "c", "d", "e", "f"};

var arr = baseArray[1..^2];

像这样对数组进行切片会复制数组吗?或者它没有像ArraySegment<T>那样复制吗?

【问题讨论】:

  • 你的测试不是真的有效。您所做的只是创建结构,而不是使用它们。例如,Linq 版本只返回一个IEnumerable,但实际上并没有做任何事情。
  • @DavidG 好的,感谢您指出这一点。删除了我的测试用例。然而,原来的问题仍然存在,它是否复制了数组?

标签: c# arrays performance c#-8.0


【解决方案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

数组中的对象不会被复制而是被引用。

在数组中设置另一个对象不会影响另一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 2014-04-04
    • 2018-11-07
    • 2017-09-17
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多