我有一个类型化数组 MyType[] types;
,我想制作一个独立的数组副本。我尝试了这个:
MyType[] types2 = new MyType[types.Length] ;
types2 = types ;
但这样会创建对第一个对象的引用。然后我尝试了Array.Copy( types , types2 , types.Length ) ;
但是我也有同样的问题:修改第一个数组中的值同时也会改变副本中的值。
如何制作完全独立或深度复制一个数组、列表或可枚举对象?
根据第一个帖子,他只需要这个“数组的独立副本”。对shallowCopy
数组本身的更改不会出现在types
数组中(意味着元素赋值,尽管他上面说的是“深拷贝”)。如果这符合您的需求,它将具有最佳性能。
MyType[] shallowCopy = (MyType[])types.Clone();
他还提到了“深拷贝”,对于那些不是原始类型递归值聚合的可变类型,深拷贝将会有所不同。如果MyType
实现了ICloneable
,那么这对于深拷贝非常有效:
MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());
如果你急于求成:
newarray = new List<T>(oldarray).ToArray();
使用受保护的方法MemberwiseClone(执行浅复制)或使用深度克隆技术,在MyType上实现一个克隆方法。您可以让它实现ICloneable,然后编写几个扩展方法来克隆相应的集合。
interface ICloneable<T>
{
T Clone();
}
public static class Extensions
{
public static T[] Clone<T>(this T[] array) where T : ICloneable<T>
{
var newArray = new T[array.Length];
for (var i = 0; i < array.Length; i++)
newArray[i] = array[i].Clone();
return newArray;
}
public static IEnumerable<T> Clone<T>(this IEnumerable<T> items) where T : ICloneable<T>
{
foreach (var item in items)
yield return item.Clone();
}
}
private static object GetCopy(object input)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, input);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
使用方法:
MyType[] items = new MyType[2];
// populate the items in the array
MyType[] copies = (MyType[])GetCopy(items);
我也想做同样的事情:通过值复制数组,用于像排序这样的操作,以便稍后可以使用原始源数组重新初始化另一个临时数组。经过研究,我发现这并不是那么简单就能实现的。因此,我想出了一个解决方法。下面是我的代码:
string[] planetNames = new string[] { "earth", "venus", "mars" };
string[] tempNames = new string[planetNames.Length];
for (int i = 0; i < planetNames.Length; i++)
{
tempNames[i] = planetNames[i];
}
planetNames是我的原始数组。 tempNames是我将独立于planetNames进行排序的数组。 我已经测试过了,当我尝试对tempNames进行排序时,这段代码不会对planetNames进行排序,这正是我想要实现的。
如果你想创建一个只包含原始数组中对象引用的副本(或者你有一个值类型对象的数组),最简单的解决方案是:
var newArray = oldArray.ToArray()
public MyType Copy(MyType obj)
)。然后解决方案将如下所示。var newArray = oldArray.Select(x => Copy(x)).ToArray()
Copy(x)
是自定义实现的,对吗? - Thor我发现如果你只想要一个简单的字符数组复制,你可以通过使用 char 来欺骗 C# 进行按值复制:
char[] newchararray = new char[desiredchararray.Length];
for (int k = 0; k < desiredchararray.Length; k++)
{
char thecharacter = newchararray[k];
newchararray[k] = thecharacter;
oldchararray[k] = oldchararray[k] + 1;
}
对我来说似乎可以工作,但如果有人持不同意见,请告诉我 :)
在这种情况下,复制数组的值是数字。
int[] arr = { 1, 2, 3, 4, 5 };
int[] copyArr = new int[arr.Length];
for (int i = 0; i <arr.Length; i++)
{
copyArr[i]=arr[arr.Length-i-1];
}
Console.WriteLine(string.Join(" ",arr));**
.ToArray()
而不是oldarray.ToArray()
?你的方法将在列表构造函数中调用CopyTo
,并在ToArray
中调用Copy
,我不确定我看到了什么意义。 - CervEd