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()
이미를 대상 배열 필요가 존재하지 않을 경우, 그것은 당신이 대상으로 지정하는 대상에서 소스 배열의 모든 요소를 보유 할 필요가 있습니다.
둘 다 @PatrickDesjardins가 말한 것처럼 얕은 복사를 수행 CopyTo
합니다 (깊은 복사 를 생각하는 많은 오도 된 영혼에도 불구하고 ).
그러나 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
예외 로 변환 할 수 없는 경우 발생).
- 값 유형 요소를 참조 유형 요소로 상자에 넣을 수 있습니다. 예를 들어
- 소스보다 길이가 긴 스토리지에 소스를 복사 할 수 있습니다.
이러한 방법을 또한 지원하기 위해 사용할 수 있습니다주의 와 당신은 당신이 사용하지 말아야 배열 유형의 변수를 처리하는 그렇다면, 또는 사용 대신하고 나 . 충분한 복사는 복사 작업 대상을 확장으로 완료 할 수없는 경우 스토리지 상태가 손상되지 않습니다.ICloneable
ICollection
Clone
CopyTo
Array.Copy
Array.ConstrainedCopy
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 () 모두 얕은 복사본을 만듭니다. 복제 () 메서드는 원본 배열의 박물관을 만듭니다. 배열을 반환합니다.
반면에 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 () 모두)은 첫 번째 (최상위) 수준까지 만들어집니다. 그러나 하위 수준은 복사되지 않습니다. 낮은 수준의 복사본도 필요하면 명시해야합니다. 그렇기 때문에 참조 유형 요소의 복제 또는 복사 후 메모리 또는 복사 된 배열의 각 요소가 원래 배열의 해당 요소가 참조하는 것과 동일한 위치를 참조합니다. 이는 하위 수준에 대해 별도의 인스턴스가 생성되지 않음을 분명히 나타냅니다. 언어 복사 됨 또는 복제 배열의 요소 값을 변경해도 원래 배열의 해당 요소에 영향을 미치게됩니다.
내 설명이 완전하게 생각할 수있는 방법을 찾을 수 있습니다.
이 Clone()
메서드는 대상 인스턴스에 대한 참조를 제공하지 않고 복사본을 제공합니다. 이 CopyTo()
메소드는 요소를 기존 인스턴스에 복사합니다.
둘 다 대상 인스턴스의 참조를 제공하지 않는 많은 구성원이 참조없이 얕은 복사 (일루전 복사)를 제공하는 말했듯이 이것이 핵심입니다.
대답이 혼란 스럽습니다. 얕은 복사라고하면 여전히 동일한 주소를 가리키고 있음을 의미합니다. 즉, 둘 중 하나를 변경하면 다른 것도 변경됩니다.
따라서 A = [1,2,3,4]이고 복제하면 B = [1,2,3,4]가됩니다. 이제 B [0] = 9를 변경하면 A는 이제 A = [9,2,3,4]가됩니다. 그 맞 맞습니까?
둘 다 얕은 복사본입니다. CopyTo 메서드는 전체 복사가 아닙니다. 다음 코드를 확인하십시오.
public class TestClass1
{
public string a = "test1";
}
public static void ArrayCopyClone()
{
TestClass1 tc1 = new TestClass1();
TestClass1 tc2 = new TestClass1();
TestClass1[] arrtest1 = { tc1, tc2 };
TestClass1[] arrtest2 = new TestClass1[arrtest1.Length];
TestClass1[] arrtest3 = new TestClass1[arrtest1.Length];
arrtest1.CopyTo(arrtest2, 0);
arrtest3 = arrtest1.Clone() as TestClass1[];
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
arrtest1[0].a = "new";
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
}
/* Output is
test1
test1
test1
new
new
new */
Array.Clone 은 함수를 호출 할 때 대상 / 대상 배열을 사용할 필요가 없지만 Array.CopyTo 에는 대상 배열과 인덱스가 필요합니다.
Clone()
데이터 / 배열의 구조 만 복사하는 데 사용되며 실제 데이터는 복사하지 않습니다.
CopyTo()
구조와 실제 데이터를 복사합니다.
참고 : String []을 StringBuilder []로 사용하는 것에는 차이가 있습니다.
String에서-String을 변경하면 동일한 문자열을 가리키는 CopyTo 또는 Clone으로 복사 한 다른 배열은 변경되지 않지만 원래 String 배열은 새 문자열을 가리킬 것입니다. 그러나 StringBuilder를 사용하는 경우 배열에서 문자열 포인터는 변경되지 않으므로이 배열에 대해 만든 모든 복사본에 영향을줍니다. 예를 들면 :
public void test()
{
StringBuilder[] sArrOr = new StringBuilder[1];
sArrOr[0] = new StringBuilder();
sArrOr[0].Append("hello");
StringBuilder[] sArrClone = (StringBuilder[])sArrOr.Clone();
StringBuilder[] sArrCopyTo = new StringBuilder[1];
sArrOr.CopyTo(sArrCopyTo,0);
sArrOr[0].Append(" world");
Console.WriteLine(sArrOr[0] + " " + sArrClone[0] + " " + sArrCopyTo[0]);
//Outputs: hello world hello world hello world
//Same result in int[] as using String[]
int[] iArrOr = new int[2];
iArrOr[0] = 0;
iArrOr[1] = 1;
int[] iArrCopyTo = new int[2];
iArrOr.CopyTo(iArrCopyTo,0);
int[] iArrClone = (int[])iArrOr.Clone();
iArrOr[0]++;
Console.WriteLine(iArrOr[0] + " " + iArrClone[0] + " " + iArrCopyTo[0]);
// Output: 1 0 0
}
'ProgramingTip' 카테고리의 다른 글
Knockout.js를 사용하여 특정 위치에서 ObservableArray 항목을 추가 / 삽입하는 방법 (0) | 2020.10.24 |
---|---|
두 개의 다른 파일 보관 git diff (0) | 2020.10.24 |
자바의 링 버퍼 (0) | 2020.10.23 |
.equals () 및 == 연산자로 두 개체 비교 (0) | 2020.10.23 |
입력 요소에서 angularjs 필터 사용 (0) | 2020.10.23 |