Sunday, December 17, 2006

Get (another's class) private fields

About 2 months ago I wrote a couple articles on reflection, specifically about executing another's class private methods, someone left a question on how you can get the private fields, just now I found the time to answer to that; first of all let's create a test class:

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;
}
}



Then we create an instance of it, and use the method GetFields to (you guessed) get the list of fields, we just have to specify on the parameters that we want private members and they have to be instance members (non-static), once we get the list we can do *whatever* we want with it, in this case the code prints the field type and it's value


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)));


That's about it. Now, just to make it a little bit more interesting I created a small generic function to accomplish the previous task and now you can reuse that with any other class:

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)));
}



To use it, we just create an instance of that class and pass the instance to the function:


TestClass test = new TestClass();


PrintPrivateFields(test);


Note that I don't need to specify the type when calling the function


PrintPrivateFields<TestClass>(test);


The compiler is smart enough to figure it out (since the only parameter is of that type).


Hope the code is useful, you can find the full code here

No comments: