Sunday, December 17, 2006

Como obtener todos los campos privados de otra clase

Hace casi 2 meses escribi unos articulos acerca del uso de refleccion, especificamente sobre como ejecutar metodos privados, alguien dejo una pregunta sobre como podria obtener todos los campos privados de una clase, apenas hoy me di tiempo para contestar aqui mismo en el blog; primero vamos a crear una clase de prueba

class TestClass {
private int prop1;

public int Prop1 {
get { return prop1; }
set { prop1 = value; }
}

private string prop2;

public string Prop2 {
get { return prop2; }
set { prop2 = value; }
}

private bool prop3;

public bool Prop3 {
get { return prop3; }
set { prop3 = value; }
}

public bool field4;

public TestClass() {
prop1 = 10;
prop2 = "20";
prop3 = false;
field4 = true;
}
}



luego creamos una instancia de esta clase, y utilizamos el metodo GetFields para obtener la lista de campos, pasando como parametros que queremos los campos privados que pertenezcan a una instancia (que no sean estaticos), una vez que tenemos la lista podemos hacer lo que queramos, en este caso imprimo el tipo del campo y el valor de este

TestClass test = new TestClass();
FieldInfo[] fields = test.GetType().GetFields(BindingFlags.NonPublic BindingFlags.Instance);
foreach (FieldInfo f in fields)
Console.WriteLine(string.Format("type:{0} \t value:{1}", f.FieldType.ToString(), f.GetValue(test)));




listo, eso es todo. Ahora solo para hacerlo un poquito mas interesante me puse a crear una funcion generica para realizar esta tarea y puede reutilizarse con cualquier otra clase:

static void PrintPrivateFields<T>(T theInstance) where T:class {
Type t = theInstance.GetType();
FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic BindingFlags.Instance);
foreach (FieldInfo f in fields)
Console.WriteLine(string.Format("type:{0} \t value:{1}", f.FieldType.ToString(), f.GetValue(theInstance)));
}



para usarla simplemente creamos la instancia de la clase, y pasamos esta instancia a nuestra funcion:


TestClass test = new TestClass();


PrintPrivateFields(test);


noten que no necesito pasarle el tipo generico asi


PrintPrivateFields<TestClass>(test);


sino que el compilador es inteligente y puede derivar el tipo generico.


Espero les sea util, el codigo completo lo encuentran aqui, salu2

No comments: