¿Puedo cambiar un campo privado heredado de solo lectura en C # usando la reflexión?
-
05-07-2019 - |
Pregunta
como en java tengo:
Class.getSuperClass().getDeclaredFields()
¿Cómo puedo saber y establecer un campo privado desde una superclase?
Sé que esto no es muy recomendable, pero estoy probando mi aplicación y necesito simular una situación incorrecta en la que la identificación es correcta y el nombre no. Pero esta identificación es privada.
Solución
Sí, es posible usar la reflexión para establecer el valor de un campo de solo lectura después de que el constructor se haya ejecutado
var fi = this.GetType()
.BaseType
.GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
EDIT
Actualizado para buscar en el tipo primario directo. Esta solución probablemente tendrá problemas si los tipos son genéricos.
Otros consejos
Sí, puedes.
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"
}
Esta clase te permitirá hacerlo:
http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs
Uso:
new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue);
Por cierto, funcionará en campos o propiedades públicas / no públicas. Para facilitar su uso, puede utilizar la clase derivada PropertyValue de esta manera:
new PropertyValue<int>(this, "_myParentField").Value = newValue;
Como sugiere JaredPar, hice lo siguiente:
//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.