[c#] System.Array.CopyTo ()와 System.Array.Clone ()의 차이점

System.Array.CopyTo()과 의 차이점은 무엇입니까 System.Array.Clone()?



답변

클론 () 메소드는 새로운 어레이 원의 배열에있는 모든 요소를 포함하는 (a 얕은 복사) 객체를 반환한다. 하는 CopyTo () 메소드 복사본 다른 기존의 배열 요소. 둘 다 얕은 복사를 수행합니다. 단순 복사는 내용 (각 배열 요소)에 원래 배열의 요소와 동일한 객체에 대한 참조가 포함되어 있음을 의미합니다. 이러한 방법 중 어느 것도 수행하지 않는 딥 복사는 각 요소의 객체에 대한 새 인스턴스를 생성하여 다르지만 동일한 객체를 생성합니다.

따라서 차이점은 다음과 같습니다.

1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.

편집하다:

잘못된 예를 제거하십시오.


답변

지금까지 언급되지 않은 또 다른 차이점은

  • Clone()새가 처음부터 생성되기 때문에 대상 배열이 필요 아직 존재한다.
  • CopyTo()이미를 대상 배열 필요가 존재하지 않습니다 만, 그것은 당신이 대상으로 지정하는 인덱스에서 소스 배열의 모든 요소를 보유 할 충분한해야합니다.


답변

다른 많은 답변에서 언급했듯이 두 방법 모두 배열의 얕은 복사본 을 수행 합니다. 그러나 아직 해결되지 않은 차이점과 권장 사항이 다음 목록에 강조 표시되어 있습니다.

의 특성 System.Array.Clone:

  • .NET 4.0, 그것은 그 쇼 사용하여 테스트, 느린보다CopyTo 아마 사용하기 때문에를 Object.MemberwiseClone;
  • 결과 를 적절한 유형으로 캐스팅해야합니다 .
  • 결과 배열은 소스와 길이가 같습니다.

의 특성 System.Array.CopyTo:

  • Clone동일한 유형의 배열에 복사 할 때보빠릅니다 .
  • 로 호출 Array.Copy상속는 기능입니다 가장 유용한 것들되는 :
    • 값 유형 요소를 참조 유형 요소로 상자에 넣을 수 있습니다. 예를 들어 int[]배열을 object[];
    • 복사기, 예를 들어, 값 유형 요소로 참조 형 소자를 언 박싱 수 object[]박스의 배열 int로를 int[];
    • 값 유형에 대해 확장 변환을 수행 할 수 있습니다 (예 int[]:를 long[].
    • 예를 들어, Stream[]배열을에 복사하는 등 요소를 다운 캐스트 할 수 있습니다 MemoryStream[](소스 배열의 요소를 MemoryStream예외 로 변환 할 수 없는 경우 발생).
  • 소스보다 길이가 긴 타겟 스토리지에 소스를 복사 할 수 있습니다.

또한 이러한 방법을 지원하기 위해 사용할 수 있습니다주의 ICloneableICollection당신은 당신이 사용하지 말아야 배열 유형의 변수를 처리하는 그렇다면, Clone또는 CopyTo사용 대신하고 Array.CopyArray.ConstrainedCopy. 제한된 복사는 복사 작업을 성공적으로 완료 할 수없는 경우 대상 스토리지 상태가 손상되지 않도록합니다.


답변

둘 다 @PatrickDesjardins가 말한 것처럼 얕은 복사를 수행 CopyTo합니다 (깊은 복사 를한다고 생각하는 많은 오도 된 영혼에도 불구하고 ).

그러나 CopyTo하나의 배열을 대상 배열의 지정된 인덱스에 복사 할 수 있으므로 훨씬 더 많은 유연성이 제공됩니다.


답변

object[] myarray = new object[] { "one", 2, "three", 4, "really big number", 2324573984927361 };

//create shallow copy by CopyTo
//You have to instantiate your new array first
object[] myarray2 = new object[myarray.Length];
//but then you can specify how many members of original array you would like to copy 
myarray.CopyTo(myarray2, 0);

//create shallow copy by Clone
object[] myarray1;
//here you don't need to instantiate array, 
//but all elements of the original array will be copied
myarray1 = myarray.Clone() as object[];

//if not sure that we create a shalow copy lets test it
myarray[0] = 0;
Console.WriteLine(myarray[0]);// print 0
Console.WriteLine(myarray1[0]);//print "one"
Console.WriteLine(myarray2[0]);//print "one"

소스


답변

CopyTo () 및 Clone () 모두 얕은 복사본을 만듭니다. Clone () 메서드는 원본 배열의 복제본을 만듭니다. 정확한 길이 배열을 반환합니다.

반면에 CopyTo ()는 원래 배열의 요소를 지정된 대상 배열 인덱스에서 시작하는 대상 배열로 복사합니다. 이것은 이미 존재하는 배열에 요소를 추가합니다.

다음 코드는 CopyTo ()가 딥 카피를 만든다는 게시물과 모순됩니다.

public class Test
{
public string s;
}

// Write Main() method and within it call test()

private void test()
{
Test[] array = new Test[1];
array[0] = new Test();
array[0].s = "ORIGINAL";

Test[] copy = new Test[1];
array.CopyTo(copy, 0);

// Next line displays "ORIGINAL"
MessageBox.Show("array[0].s = " + array[0].s);
copy[0].s = "CHANGED";

// Next line displays "CHANGED", showing that
// changing the copy also changes the original.
MessageBox.Show("array[0].s = " + array[0].s);
}

조금 설명하겠습니다. 배열의 요소가 참조 유형이면 복사본 (Clone () 및 CopyTo () 모두)은 첫 번째 (최상위) 수준까지 만들어집니다. 그러나 하위 수준은 복사되지 않습니다. 더 낮은 수준의 복사본도 필요하면 명시 적으로해야합니다. 그렇기 때문에 참조 유형 요소의 복제 또는 복사 후 복제 또는 복사 된 배열의 각 요소는 원래 배열의 해당 요소가 참조하는 것과 동일한 메모리 위치를 참조합니다. 이는 하위 수준에 대해 별도의 인스턴스가 생성되지 않음을 분명히 나타냅니다. 그렇다면 복사 됨 또는 복제 됨 배열의 요소 값을 변경해도 원래 배열의 해당 요소에는 영향을 미치지 않습니다.

내 설명이 완전하다고 생각하지만 이해할 수있는 다른 방법을 찾지 못했습니다.


답변

Array.Clone()int또는 문자열 의 배열을 참조로 메서드에 전달할 때 기술적으로 깊은 복사를 수행 합니다.

예를 들면

int[] numbers = new int[] { -11, 12, -42, 0, 1, 90, 68, 6, -9 };

SortByAscending(numbers); // Sort the array in ascending order by clone the numbers array to local new array.
SortByDescending(numbers); // Same as Ascending order Clone

방법이 숫자 배열을 정렬하지만 정렬 방법에 전달 된 실제 참조에 영향을주지 않더라도 숫자 배열은 1 번 줄에서 동일한 정렬되지 않은 초기 형식이됩니다.

참고 : 복제는 정렬 방법에서 수행되어야합니다.