2009-11-26 5 views
10

유형별 복제 코드를 작성하지 않고도 boxed ValueType으로 알려져있을 때 객체를 복제 할 수 있습니까? 참조ValueType을 복제 할 수 있습니까?

List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M}; 
DuplicateLastItem(values); 

I가 가지고있는 문제점에 대한 partical

일부 코드 값은 스택 기반 가상 머신 명령이다. (그리고 typof (int) typeof (DateTime) ....)을 작성하기에는 너무 게으른 Im)

업데이트 나는 혼잣말을하고 (다른 몇몇 사람들은) 혼란 스럽다고 생각합니다. 내가 가지고있는 해결책은 다음과 같습니다.

List<ValueType> values = new List<ValueType> { 3, DateTime.Now, 23.4M }; 

// Clone 
values.Add(values[values.Count() - 1]); 

// Overwrite original 
values[2] = 'p'; 

foreach (ValueType val in values) 
    Console.WriteLine(val.ToString()); 
+0

존 존 존, 당신이 그것을 언 박싱한다면 당신은 "변수의 유형"을 입력해야합니다, 결국 .. – Peter

+1

을 온다. 성취하려는 것을 보여 주실 수 있습니까? C# 4의 "동적 인"키워드가 도움이 될 것입니다. – shahkalpesh

+0

DuplicateLastItem의 기능은 무엇입니까? – shahkalpesh

답변

3

내가 완전히 오해 한 경우 잘 모르겠다.
이 작업을 수행하려고합니까? 당신이 어디에 있든

public static void Main() 
{ 
    List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M}; 
    DuplicateLastItem(values); 

    Console.WriteLine(values[2]); 
    Console.WriteLine(values[3]); 
    values[3] = 20; 
    Console.WriteLine(values[2]); 
    Console.WriteLine(values[3]); 
} 

static void DuplicateLastItem(List<ValueType> values2) 
{ 
    values2.Add(values2[values2.Count - 1]); 
} 
5

값 유형의 모든 할당은 정의에 의한 것입니다.

편집 :

당신의 치형의 사본이있는 ReferenceType의 인스턴스에 포함됩니다 치 형을 권투.

클로닝 방법에 따라 차이점이 없습니다.

+0

이것은 약 박스 값입니까? – Peter

+0

"값 유형의 모든 할당은 정의에 의한 것입니다." 잘못되었습니다. 할당은 값 유형을 "복제"하지 않습니다. 같은 값에 대한 참조를 얻습니다. –

+0

Jorge, 이것이 ValueTypes과 ReferenceTypes의 근본적인 차이점입니다. 'int i = 1; int a = i;'<- a는 i의 복제본이됩니다 –

2
private static T CloneUnboxed<T>(object o) where T : struct 
    { 
     return (T)o; 
    } 

    private static object CloneBoxed<T>(object o) where T : struct 
    { 
     return (object)(T)o; 
    } 

값 유형이 불변이어야한다고 가정 할 때 나는 둘 중 어느 하나에 대한 필요성을 질문합니다.

1

개체를 ValueType으로 캐스팅하는 경우 복제가 수행되지 않습니까? 이것은 다음 reboxed 수 :

int i = 3; 
object b = i; // box it 
ValueType c = (ValueType) b; // unbox it 
object d = c; // box it, effectively creating a clone 

그래서, 내가 효과적인 복제 방법이 될 말을 생각 : 왜 당신은 어쨌든 코드를 복제해야합니까

object clone = (ValueType) boxed; 
+0

아니요, 그렇지 않습니다. 필자는 테스트 한 결과, ReferenceEquals 메서드는 b와 c를 비교할 때 true를 반환합니다. –

+0

b와 d를 비교해 보았습니까? 두 개의 박스 값입니까? –

+0

좋아, 나 자신을 시도하고 동일한 값 유형에 두 상자 작업이 사용되는 동일한 상자에 나타나는 것 같습니다. 그것에 대해 생각해 보면, 이것은 CLR의 합리적인 행동입니다. –

2

? 값 유형 일 경우은 일반적으로 어쨌든 변경할 수 없으며 복싱으로 변경되지 않습니다. 따라서 잘 설계된 값 유형에는 복제 요구 사항이 없습니다.

object x = 1; 
var type = x.GetType(); 
var clone = Convert.ChangeType(x, type); 

// Make sure it works 
Assert.AreNotSame(x, clone); 

결과는 새로운 객체에 박스 값의 사본입니다 :

+0

정확합니다. 질문과 코드 예제가 중요하다고 생각하면 항상 도움이됩니다. – shahkalpesh

+0

'IEnumerator '이 있다고 가정합니다. 'T02'에서 파생 된 일부 알 수없는 유형 'U'에 대해 'List .Enumerator'가 있다고 가정합니다. 'U'를 안다면'List .Enumerator'로 캐스팅하면 상태의 스냅 샷이 찍히지 만, 그렇게하면'U' 타입을 알아야합니다. – supercat

+0

@supercat 음, 실수로 잘못된 글에 댓글을 찍은 것 같습니다. 적어도 나는 그 연결이 보이지 않는다. –

4

당신은 Convert.ChangeType를 사용하여 해킹을 사용할 수 있습니다.

+0

Im은 CLR의 용기에 대해 잘 모르지만 내가 가지고있는 해결책은 확실합니다. 다른 대답에 대한 의견에서 말했듯이, CLR이 "영리한"일을하는 것을 잡았을 것입니다. –

+0

이것은 유일한 질문입니다.이 질문에 대한 답은 다음과 같습니다. 구조체로 알려진 유형이지만 그렇지 않으면 알려지지 않은 힙 (heap) 객체이며 구성원 별 복제본을 만들려고합니다. 인터페이스를 구현하지 않는 한 힙 객체의 유형을 알지 못하고 실제로 힙 객체를 많이 할 수 없기 때문에 이상한 질문 인 것 같습니다. 그리고 인터페이스를 구현하기 위해 구조체를 정의하려는 경우 적절한 복제본을 포함 할 수도 있습니다 함수를 호출합니다. – supercat

관련 문제