Applies to C# (tested in VS2005)
On a recent post I talked about accessing (another's class) private methods through reflection; apparently not a lot of people was aware that this was possible. Well, here's another one for y'all, you can instantiate a class even if it's constructor is private
Here I'm including one example for a private constructor, one for protected and one for a (regular) public constructor, all of them using reflection.
Let's create our test class to play with:
public class TestClass {
private TestClass() {
Console.WriteLine("private TestClass constructor");
}
protected TestClass(int i) {
Console.WriteLine(string.Format("protected TestClass constructor (int:{0})", i));
}
public TestClass(string s) {
Console.WriteLine(string.Format("public TestClass constructor (string:{0})", s));
}
}
now let's see how easy is to instantiate this class using any of it's constructor, regardless of their visibility, all this through reflection:
- you need to include System.Reflection in your uses clause
The first one is a simple parameterless private constructor, not much is required here
//*** Private constructor
ConstructorInfo ci1 = typeof(TestClass).GetConstructor(
//*** Non public and instance (non static) constructor
BindingFlags.NonPublic | BindingFlags.Instance,
//*** No binder, no parameters, so no parameter modifiers
null, new Type[0], new ParameterModifier[0]);
//*** Call our constructor
TestClass tc1 = (TestClass)ci1.Invoke(new object[0]);
The second one is protected (you still still use "non-public" for the BindingFlags),
it does include a parameter so we have to pass the parameter type
//*** Protected constructor
ConstructorInfo ci2 = typeof(TestClass).GetConstructor(
//*** non public and instance (non static) constructor
BindingFlags.NonPublic | BindingFlags.Instance,
//*** no binder, 1 parameter of type int, no modifiers for the param
null, new Type[1] { typeof(int) }, new ParameterModifier[0]);
//*** Call our constructor
TestClass tc2 = (TestClass)ci2.Invoke(new object[1] { 10 });
The third one is public, we could instantiate it without reflection,
but I'll just leave it as an example.
//*** Public constructor
ConstructorInfo ci3 = typeof(TestClass).GetConstructor(
//*** public and instance method
BindingFlags.Public | BindingFlags.Instance,
//*** no binder, 1 parameter of type string, no parameter modifiers
null, new Type[1] { typeof(string) }, new ParameterModifier[0]);
//*** Call our constructor
TestClass tc3 = (TestClass)ci3.Invoke(new object[1] { "test" });
That's it, that simple; this technique should rarely be used, more than anything I want you to be aware that it is possible and how easy it is
You could even combine the flags: BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance and it would instantiate the class if the access modifier was private, protected or public
You can find the full code here, have fun
By the way, I'm in Guadalajara now, I'll be here until Tuesday, then I'm going to Tulancingo Hidalgo and then Aguascalientes, if anyone wants to join me for dinner or just talk let me know