我有一个包含10个元素的数组X。我想创建一个新数组,包含X中从索引3开始并在索引7结束的所有元素。当然,我可以很容易地写一个循环,将它为我,但我想保持我的代码尽可能干净。c#中有一个方法可以帮我做这个吗?
类似(伪代码):
Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)
数组中。拷贝不符合我的需要。我需要在新数组中的项目是克隆。数组中。copy只是一个c风格的memcpy等效,这不是我要找的。
克隆数组中的元素并不是一种通用的方法。您想要深度克隆还是所有成员的简单副本?
让我们采用“尽最大努力”的方法:使用ICloneable接口或二进制序列化克隆对象:
public static class ArrayExtensions
{
public static T[] SubArray<T>(this T[] array, int index, int length)
{
T[] result = new T[length];
for (int i=index;i<length+index && i<array.Length;i++)
{
if (array[i] is ICloneable)
result[i-index] = (T) ((ICloneable)array[i]).Clone();
else
result[i-index] = (T) CloneObject(array[i]);
}
return result;
}
private static object CloneObject(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0,SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}
}
这并不是一个完美的解决方案,因为没有一个解决方案适用于任何类型的对象。
在c# 8中,他们引入了一个新的范围和索引类型,可以这样使用:
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Index i1 = 3; // number 3 from beginning
Index i2 = ^4; // number 4 from end
var slice = a[i1..i2]; // { 3, 4, 5 }
引用:
https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#ranges-and-indices
https://devblogs.microsoft.com/dotnet/building-c-8-0/
在c# 8.0中,你现在可以像Python一样做许多更漂亮的工作,包括反向索引和范围,例如:
int[] list = {1, 2, 3, 4, 5, 6};
var list2 = list[2..5].Clone() as int[]; // 3, 4, 5
var list3 = list[..5].Clone() as int[]; // 1, 2, 3, 4, 5
var list4 = list[^4..^0].Clone() as int[]; // reverse index