Reflection给我们的编程带来极大的便利,然而我们却往往会忽略掉这把双刃剑(同样锋利)的另外一面。By design, 只要你具有了相应的ReflectionPermission, Reflection 就允许你访问一个Assembly里中的所有Classes (包括NonPublic),也允许你访问一个Class中的所有Methods, Properties以及Fields(包括NonPublic)!
而在我们实际工作中,很多人从意识上都认为在面向对象的保护机制下,private member是别人无法访问的,因此如果我不允许别人访问我的某个member,只需要在其前面加上private就ok……殊不知在Reflection下面向对象的保护机制简直就是形同虚设,下面我们来看一个例子。
想象这样一种场景:
我有一个名为SecLib的Assembly,里面有一个公共的加密方法(Encrypt)和一个私有的解密方法(Decrypt),我的原意是只允许别人使用Encrypt来进行加密,而Decrypt只由我自己调用(由于这完全是一对紧密耦合的方法,把它们放在一个Assembly里面是很自然的事情):
下载该例子的完整代码:ReflectionTrap.zip
而在我们实际工作中,很多人从意识上都认为在面向对象的保护机制下,private member是别人无法访问的,因此如果我不允许别人访问我的某个member,只需要在其前面加上private就ok……殊不知在Reflection下面向对象的保护机制简直就是形同虚设,下面我们来看一个例子。
想象这样一种场景:
我有一个名为SecLib的Assembly,里面有一个公共的加密方法(Encrypt)和一个私有的解密方法(Decrypt),我的原意是只允许别人使用Encrypt来进行加密,而Decrypt只由我自己调用(由于这完全是一对紧密耦合的方法,把它们放在一个Assembly里面是很自然的事情):
public class SecLib
{
public static byte[] Encrypt(string s)
{
}
private static string Decrypt(byte[] d)
{
}
}
//string s = SecLib.Decrypt(d);
却可以通过Reflection来达到目的:Type t = typeof(SecLib);
MethodInfo mi = t.GetMethod("Decrypt", BindingFlags.Static | BindingFlags.NonPublic);
string s = (string)mi.Invoke(null, new object[]{encryptedData});
下载该例子的完整代码:ReflectionTrap.zip