2009-12-27 2 views
6

나는이 인스턴스의 객체 데이터 멤버를 변경하려고합니다 은 같은 유형의 다른 객체 (스왑) 인 으로 인해 만료됩니다. 내 시스템 제약 조건에 =, 새로운 또는 세터 연산자를 사용할 수 없습니다.C# Reflection - 변수 필드의 값 변경

기본적으로 변수 필드의 값을 변경하고 싶습니다.이 필드는 다른 개체 (해당 인스턴스의 변수)에 들어있는 개체입니다.

리플렉션을 사용하면 가능합니까? 그렇다면 누군가 기본 방향을 알려주시겠습니까?

감사 아브

+0

당신이 몇 가지 코드를 공유 할 수 (cartonclass의, 정수) SetFieldValue (3 cartonyoudropped, "survivingeggcount"), 제발 ? –

+0

속성이나 필드를 변경하려는 값입니까? 그것이 속성이라면, 그 뒤에있는 들판의 이름을 아십니까? 기본적으로 속성에 접근 자 설정이없는 경우에는 리플렉션을 사용하여 값을 변경할 수 없습니다. 그러나 필드가 뒤에 있으면 private 인 경우에도 리플렉션을 사용하여 변경할 수 있습니다. 어떤 경우에는 (나는 그것에 대한 참조를 기억하지 못함) 개인 필드에 대한 반영 액세스를 거부 할 수도 있습니다. –

답변

13

예, 그것의 가능한. 한마디로

는 숨겨진 (개인/보호/내부) 필드의 값을 변경

Type typeInQuestion = typeof(TypeHidingTheField); 
FieldInfo field = typeInQuestion.GetField("FieldName", BindingFlags.NonPublic | BindingFlags.Instance); 
field.SetValue(instanceOfObject, newValue); 

그런 짓을. 읽을 수있는 해당 FieldInfo.GetValue(...)을 사용하십시오. 두 가지를 겸해서 원하는 스와핑 작업을 얻으십시오.

나를 BindingFlags에 붙들어 두지 마십시오. (나는 항상 처음 시도에서 잘못 이해하는 것 같습니다) 정확한 구문이지만, 기본적으로 그 것입니다.

참조 용으로 System.Reflection을 찾으십시오. Fasterflect를 사용하는 경우

typeof(MyType).SetField("MyField", anotherObject); 

, 당신은 귀찮게 할 필요가 없습니다 : 당신이 .NET 3.5을 사용하는 경우

+0

BindingFlags는 좋아 보이지만 Public을 포함 할 수도 있습니다 ... BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance – David

4

, 다음과 같은 코드로 그것을 해결하기 위해 내 오픈 소스 라이브러리, Fasterflect을 사용할 수 있습니다 오른쪽 BindingFlags 사양 및 성능 관련 내용 (리플렉션 사용시와 동일).

제네릭 VB에서
0

하지만 초보적인 오류 처리 :

Module somereflectionops 
    Function GetFieldValue(Of OBTYPE, FIELDTYPE)(instance As OBTYPE, fieldname As String, Optional specbindingflags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Instance) As FIELDTYPE 
     Dim ot As Type = GetType(OBTYPE) 
     Dim fi As FieldInfo 
     Try 
      fi = ot.GetField(fieldname, BindingFlags.Default Or specbindingflags) 
      If fi Is Nothing Then Return Nothing 
      Return fi.GetValue(instance) 
     Catch ex As Exception 
      Return Nothing 
     End Try 
    End Function 

    Function SetFieldValue(Of OBTYPE, FIELDTYPE)(instance As OBTYPE, fieldname As String, value As FIELDTYPE, Optional specbindingflags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Instance) As Boolean 
     Dim ot As Type = GetType(OBTYPE) 
     Dim fi As FieldInfo 
     Try 
      fi = ot.GetField(fieldname, BindingFlags.Default Or specbindingflags) 
      If fi Is Nothing Then Return false 
      fi.SetValue(instance, value) 
      Return True 
     Catch ex As Exception 
      Return False 
     End Try 
    End Function 
End Module 

사용 :