2009-12-27 21 views
6

Tengo una instancia de una clase, quiero cambiar un miembro de datos de objeto de esta instancia solo con otro objeto del mismo tipo (swap), debido a las limitaciones de mi sistema no puedo usar =, operadores nuevos o setter.C# Reflection - cambiando el valor de un campo de una variable

Básicamente me gustaría cambiar el valor de un campo de una variable, el campo es un objeto contenido dentro de otro objeto, la variable que tengo en su instancia.

¿es posible usar la reflexión? Si es así, ¿alguien puede darme una dirección básica?

Gracias Yoav

+0

¿Se puede compartir algo de código, por favor ? –

+0

¿El valor que desea cambiar es una propiedad o un campo? Si es una propiedad, ¿conoce el nombre del campo que está detrás? - Básicamente, si una propiedad no tiene un descriptor de acceso establecido, no puede cambiar su valor (incluso utilizando la reflexión); sin embargo, si hay un campo detrás de él, incluso si es privado, puede (generalmente) cambiarlo utilizando la reflexión. En algunos casos (no recuerdo la referencia), incluso se puede denegar el acceso de reflexión a campos privados. –

Respuesta

13

Sí, es posible.

En resumen, hacer algo como

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

para cambiar el valor de un campo oculto (privado/protegido/interno). Use el FieldInfo.GetValue(...) correspondiente para leer; combine los dos trivialmente para obtener su operación de intercambio deseada.

No me sostenga de los BindingFlags (parece que siempre me equivoco en el primer intento) o la sintaxis exacta , pero eso es básicamente.

Mire System.Reflection de referencia.

+0

BindingFlags se ven bien, pero es posible que también desee incluir Public ... BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance – David

4

Si utiliza .NET 3.5, puede utilizar mi biblioteca de código abierto, Fasterflect, para tratar de que con el siguiente código:

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

Al utilizar Fasterflect, usted no tiene que molestarse con el especificación BindingFlags correcta y la implicación del rendimiento (como cuando se usa la reflexión).

0

en VB con los genéricos, pero el manejo de errores rudimentaria:

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 

uso: SetFieldValue (De cartonclass, Integer) (cartonyoudropped, "survivingeggcount", 3)

Cuestiones relacionadas