What happens if you try and access a private method in a class? Understandibly, the compiler will kick up a fuss because this breaks the laws of encapsulation.
But is it still accessible? Well, the answer is YES, you can still access it from outside the class!!
So lets look at what happens in the naive sense:
class PrivateMethods
{
private int ReturnNumber() { return 5; }
}
class Program
{
static void Main(string[] args)
{
PrivateMethods p = new PrivateMethods();
p.ReturnNumber();
}
}
You should get:
'PrivateMethods.PrivateMethods.ReturnNumber()' is inaccessible due to its protection level'
Okay, so we definitely can't access it directly, but its a small secret that the compiler is just stopping you do it, but the CLR can still access it. So lets try it via Reflection:
class PrivateMethods
{
private int ReturnNumber() { return 5; }
}
class Program
{
static void Main(string[] args)
{
//Look for Non-Public methods in the instance passed in.
BindingFlags methodFlags = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo mi = typeof(PrivateMethods).GetMethod("ReturnNumber", methodFlags);
int value = (int) mi.Invoke(new PrivateMethods(), null);
}
}
And voila, we have called a private method in a class, when we should have access to it.
But this is quite dangerous isn't it? Well it depends. Some argue that when testing, you may want to test every method, even private ones. But some also argue that the private methods are tested within the public methods, and have no context as a single method, as the test must have some understanding for the inner workings of the method.
But lets just say that we want to stop people doing this - accessing methods by Reflection, how to we do it?
All you need to do, is add an assembly level attribute called "ReflectionPermission", with the SecurityAction.RequestRefuse security applied, and the Unrestricted=true property set. In other words, add this line to your AssemblyInfo.cs:
[assembly: ReflectionPermission ( SecurityAction.RequestRefuse , Unrestricted=true )]
Now, if you run the second code sample from above you will get a "MethodAccessException" thrown.