2009-09-09 21 views

Respuesta

9

Sí, es posible utilizar la reflexión para establecer el valor de un campo de sólo lectura después de que el constructor ha quedado

var fi = this.GetType() 
      .BaseType 
      .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic); 

fi.SetValue(this, 1); 

EDITAR

Actualizado para buscar en el tipo principal directo. Esta solución probablemente tendrá problemas si los tipos son genéricos.

+0

pero, con este código, no puedo obtener el campo principal. ¿bien? – Custodio

+0

@ Luís, actualizado el código de buscar en el tipo de los padres u – JaredPar

+0

ahora por qué sólo puedo conseguir mi campo utilizando " k__BackingField"? – Custodio

1

Esta clase le permitirá hacerlo:

http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs

Uso:

new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue); 

Por cierto, va a trabajar en los campos o propiedades públicas/no pública. Para facilitar su uso puede utilizar la clase derivada PropertyValue así:

new PropertyValue<int>(this, "_myParentField").Value = newValue; 
+0

1 para la biblioteca-csharptest red. Tiene un registrador interesante. –

1

Sí, se puede.

Para los campos, use la clase FieldInfo. El parámetro BindingFlags.NonPublic le permite ver campos privados.

public class Base 
{ 
    private string _id = "hi"; 

    public string Id { get { return _id; } } 
} 

public class Derived : Base 
{ 
    public void changeParentVariable() 
    { 
     FieldInfo fld = typeof(Base).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic); 
     fld.SetValue(this, "sup"); 
    } 
} 

y una pequeña prueba para demostrar que funciona:

public static void Run() 
{ 
    var derived = new Derived(); 
    Console.WriteLine(derived.Id); // prints "hi" 
    derived.changeParentVariable(); 
    Console.WriteLine(derived.Id); // prints "sup" 
} 
0

Como sugiere JaredPar, hice la siguiente manera:

//to discover the object type 
Type groupType = _group.GetType(); 
//to discover the parent object type 
Type bType = groupType.BaseType; 
//now I get all field to make sure that I can retrieve the field. 
FieldInfo[] idFromBaseType = bType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 

//And finally I set the values. (for me, the ID is the first element) 
idFromBaseType[0].SetValue(_group, 1); 

Gracias a todos.

+0

¿Está seguro de que idFromBaseType [0] es el campo correcto? Probablemente deberías unir por nombre ... –

+0

Para mí funciona, porque mi primer elemento es la ID. Pero he intentado obtener el campo con una cadena sin éxito. – Custodio

Cuestiones relacionadas