2014-07-09 1 views
2

내가 뭘 잘못하고 있는지 알 수 없습니다. 나는이 코드를 가지고있다 :C# 반사가 Point 클래스에서 작동하지 않습니까?

Point p = new Point(); 
//point is (0,0) 
p.X = 50; 
//point is (50,0) 
PropertyInfo temp = p.GetType().GetProperty("X"); 
temp.SetValue(p, 100, null); 
//and point is still (50,0) 
MethodInfo tt = temp.GetSetMethod(); 
tt.Invoke(p, new object[] { 200 }); 
//still (50,0) 

왜?

나는 대답을 찾고 있었지만 나는 아무것도 찾지 못했습니다.

+0

. 대단히 고마워. – user3820501

답변

2

포인트는 클래스가 아니라 구조체입니다. 그것의 값 유형과 그 값에 의해 전달됩니다. 따라서 SetValue 메서드에 포인트를 전달하면 점의 복사본이 전달됩니다. 그렇기 때문에 원본 인스턴스 p은 업데이트되지 않습니다.

연구 교재 : Value and Reference Types

6

아, 변경할 수 구조체의 기쁨. Sergey가 말한 것처럼 Point은 구조체입니다. PropertyInfo.SetValue을 호출 할 때 p 값을 가져 와서 boxing (값을 복사)하고 상자의 내용을 수정 한 다음 무시합니다.

당신은 여전히 반사를 사용할 수 있습니다 -하지만 중요한 것은, 당신은 단지 그것을 한 번 박스 싶다. 그래서이 작품이 변화 p의 가치,하지만 당신은 나중에 다시 언 박싱 수 있습니다되지 않습니다

object boxed = p; 
PropertyInfo temp = p.GetType().GetProperty("X"); 
temp.SetValue(boxed, 100, null); 
Console.WriteLine(boxed); // {X=100, Y=0} 
MethodInfo tt = temp.GetSetMethod(); 
tt.Invoke(boxed, new object[] { 200 }); 
Console.WriteLine(boxed); // {X=200, Y=0} 

참고 : 나는 거의 분명 뭔가있을 줄 알았

object boxed = p; 
property.SetValue(boxed, ...); 
p = (Point) boxed; 
+0

권투에 +1 멋진 트릭! –

+0

또는 RuntimeHelpers.GetObjectValue (p)를 사용하여 'SetValue'를 호출 할 때 복싱을 제어 할 수 있습니다. –

+0

@KonradKokosa : 음, 아마도 :) 내가 그 자신을 사용했다고 말할 수는 없지만 어떻게 될지 모르겠다. 여기에서 유용 할 ... –

관련 문제