Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#按值复制数组_C#_Arrays - Fatal编程技术网

C#按值复制数组

C#按值复制数组,c#,arrays,C#,Arrays,我有一个类型化数组MyType[]类型 我想制作这个阵列的独立副本。我试过这个 MyType[] types2 = new MyType[types.Length] ; types2 = types ; 但这会创建对第一个的引用。然后我试着 Array.Copy( types , types2 , types.Length ) ; 但我有同样的问题:更改第一个数组中的值也会更改副本中的值 如何制作数组、IList或IEnumerable的完全独立或深度拷贝?使用受保护的方法Memberwi

我有一个类型化数组
MyType[]类型
我想制作这个阵列的独立副本。我试过这个

MyType[] types2 = new MyType[types.Length] ;

types2 = types ;
但这会创建对第一个的引用。然后我试着

Array.Copy( types , types2 , types.Length ) ;
但我有同样的问题:更改第一个数组中的值也会更改副本中的值


如何制作数组、IList或IEnumerable的完全独立或深度拷贝?

使用受保护的方法MemberwiseClone(执行浅拷贝)或使用深度克隆技术在MyType上实现克隆方法。您可以让它实现一个IClonable,然后编写几个扩展方法来克隆相应的集合

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();
    }
}
接口可克隆
{
T克隆();
}
公共静态类扩展
{
公共静态T[]克隆(此T[]数组),其中T:IClonable
{
var newArray=newt[array.Length];
for(var i=0;i

您必须这样做,因为当您使用array.Copy创建新数组时,它会复制引用,而不是引用的对象。每个类型都负责复制自己。

根据第一篇文章,他所需要的只是“阵列的独立副本”。对
shallowCopy
数组本身的更改不会出现在
types
数组中(意思是元素赋值,这实际上是他在上面显示的,尽管他说了“deep copy”)。如果这符合您的需要,它将具有最佳性能

MyType[] shallowCopy = (MyType[])types.Clone();
他还提到了一个“深度副本”,对于不是原语递归值类型聚合的可变类型来说,它是不同的。如果
MyType
实现了
ICloneable
,这对于深度拷贝非常有用:

MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());

如果您的类型是可序列化的,则可以使用序列化技术获取数组的副本(包括项的深度副本):

要使用它:

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];
}
string[]planetNames=新字符串[]{“地球”、“金星”、“火星”};
string[]tempNames=新字符串[planetNames.Length];
对于(int i=0;i

planetNames是我的源数组。tempNames是我稍后将独立于planetNames进行排序的数组。我已经对此进行了测试,当我对tempNames进行排序时,这段代码不会对planetNames进行排序,这正是我试图实现的。

我发现,如果您只需要一个简单的字符数组副本,您可以使用字符诱使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;

}
char[]newchararray=新字符[desiredchararray.Length];
for(int k=0;k
似乎对我有用,但如果有人不同意,请告诉我:)

对于不耐烦的人:

newarray = new List<T>(oldarray).ToArray();
newarray=新列表(oldarray).ToArray();

如果您只想创建一个引用旧数组中对象的数组的副本(或者如果您有值类型对象的数组),最简单的解决方案是

var newArray = oldArray.ToArray()
如果您想要深度复制,您应该有一个复制您类型的单个对象的方法(例如,
公共MyType复制(MyType obj)
)。然后解决方案看起来像

var newArray = oldArray.Select(x => Copy(x)).ToArray()

在本例中,复制数组值的是数字

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));**
int[]arr={1,2,3,4,5};
int[]copyArr=新int[arr.Length];

对于(int i=0;i我的类型不可序列化=(char是一种值类型。对于引用类型,这将起不同的作用。Microsoft说:因为它没有指定深度和浅层复制语义。最好创建一个自己的IDeepCopyable接口。为了澄清这一点,
copy(x)
是一个自定义实现,对吗?是的,没有方法执行任何类型对象的深度复制。任何对象中都有方法,但它受到保护,只创建浅层复制(对象本身的复制,但不创建引用类型字段的新副本),而不是深度复制。您是否有理由先创建一个列表,然后调用
.ToArray()
而不是
oldarray.ToArray()
?您的方法将在列表构造函数中调用
CopyTo
,在
ToArray
中调用
复制
,我不确定我是否明白这一点
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));**