2009-05-10 3 views
1

IEnumerable을 허용하는 컬렉션에 생성자가 있습니다. 항목을 사용하여 새 모음집을 열거하고 만들고 싶지만 같은 항목을 참조하지는 않습니다. 항목 값과 심판 종류가 될 수 있습니다ref 유형 (deepcopy)을 복사하는 방법은 무엇입니까?

CustomCollection cc = new CustomCollection (IEnumerable<T> items) 
{ 
    foreach (var item in items) 
    { 
     this.Add(item); // justs adds the reference for ref types. 
    } 
} 

편집 : .NET 컬렉션은 같은 방법을 가지고는 전체 복사하지 않습니다. 왜 원래 컬렉션과 동일한 요소를 참조하는 컬렉션을 원하십니까?

답변

-2

수 없습니다. 모든 객체가 클론과 같은 방법을 지원하는 것은 아닙니다.

0

귀하의 항목이 IClonable 인터페이스 (인터페이스 기능의 올바른 구현과 함께)를 지원한다면 당신은 깊은 복사본을 만드는 .clone 함수를 호출 할 수 있다고 생각합니다.

+1

ICloneable이 잘못 지정되었지만 (얕은 또는 심층으로 표시되지 않음) 드물게 지원됩니다. –

3

해당 클래스가 직렬화를 지원하는 경우 컬렉션을 임시 스트림으로 serialize하고 새 컬렉션으로 역 직렬화 할 수 있습니다.

일부 클래스는 ICloneable을 지원하지만 프로그래머가 결정할 수있는 것은 ICloneable을 지원하는 클래스입니다. 깊은 사본 일 수도 있지만 그렇지 않을 수도 있습니다.

물론 모든 클래스가 직렬화 나 복제를 지원하는 것은 아니므로 원하는 것은 모든 유형에 대해 수행 할 수 없습니다.

작동하려면 몇 가지 제한을 설정해야합니다. 내가 많은 일을하지 않은 것처럼

private object GetCopy(object original) 
{ 
    if (original == null) 
    { 
     return null; 
    } 

    object result; 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     formatter.Serialize(stream, original); 
     stream.Position = 0; 
     result = formatter.Deserialize(stream); 
     stream.Close(); 
    } 
    return result; 
} 
2

,이 같은 전체 복사본을 만들 수 있습니다 반사와 함께 할 수 있을까요? 나는 반사는 일반적으로 성능 저하를 초래 실현,하지만 당신은 다음과 같은 스위치의 경우 일이 어떤 종류의 작업을 수행 할 수 있습니다

(의사 코드)

if(item.isValueType) { 
    newCol.Add(item) 
} elseif(item.isRefType && item.SupportsICloneable) { 
    newCol.Add(item.clone()) 
} else { 
    doReflectionCopy() 
} 

또한 추가 할 수있는 코드를 직렬화 가능한 체크를 위해 Frederik의 메소드를 포함한다.

+0

그래, 나는 복사하고 붙여 넣을 수있었습니다. 당신은 그것들을 깊게 복제 할 필요가 있거나 단지 같은 참조를 가리키고 있습니다. – Chris

+0

@Chris : 죄송합니다. 귀하의 의견을 이해할 수 없습니다. 위의 코드는 현재 작업하고있는 프로젝트에서 가져온 것입니다 (캐시에서 객체의 복사본을 가져 오는 경우에 사용합니다).이 코드는 딥 복사 메커니즘을 제공합니다. 반환 된 객체는 원래 객체에서 완전히 분리됩니다. –

-2

내가 구문을 모르는,하지만 수 잠재적으로 : 객체 직렬화 경우

0

딥 복사본의 효과는 크게 다르므로 깊은 복사본이 CLR에서 자동으로 제공되지 않습니다. 예를 들어, 딥 카피가 OS 관리 리소스 (SQL 연결, 소켓, 사용자 정의 GDI 브러시 등)에 대한 핸들을 포함하는 객체를 복제 한 경우 어떻게 될지 상상해보십시오.

위에서 제안한 것과 같은 방법을 사용해야합니다. 소스가 인터페이스를 제대로 구현한다고 믿는다면 T가 ICloneable인지 확인하십시오. 그렇지 않은 경우 (소스를 신뢰하는지, 또는 T가 복제 불가능한 경우), 오브젝트가 ISerializable로 표시되어 있는지, SerializableAttribute를 가지고 있는지를 확인한 다음, 새로운 오브젝트로 serialize/deserialize하십시오.

T가 복제 가능 또는 직렬화 가능하지 않으면 예외를 throw하고 전체 복사본을 만들지 않아야합니다.

관련 문제