奇技淫巧: Reflection存取內部/私有類別及子類別
| | | 0 | |
以下是昨天偵察.NET 2.0版本問題時新學的黑暗技巧。
使用反組譯工具追查到FtpControlStream這個internal class,想呼叫其中的方法驗證問題所在:

問題來了,既然是內部/私有類別,以外部程式的角度就不可能大大方方地宣告
FtpControlStream ftpStm = new FtpControlStream();
輕鬆搞定,得透過Reflection技巧實現。
Reflection的第一步要取得型別(Type),而外部程式不認得內部/私有類別,不可能用typeof(FtpControlStream)方式取型別,需要繞點路。進一步,呼叫時的一個參數GetPathOption,其型別是一個私有列舉,算是內部類別中的子類別,又是一項新挑戰。
解說都寫在註解裡了,大家直接看Code吧!
using System; using System.Net; namespace ConsoleApplication1 { class Program { static void Main(string[] args)
{ //因為FtpControlStream是內部類別 //不可能用typeof(FtpControlStream)方式取得Type //要先取得其所屬Assembly(System.dll),再GetType() //先找到跟FtpControlStream在同一個Assembly的FtpWebRequest //找到Assembly var asm = typeof(FtpWebRequest).Assembly; var fcsType = asm.GetType("System.Net.FtpControlStream"); Console.WriteLine(fcsType.FullName);
//接下來表演取得子類別GetPathOption //直覺上大家會寫成System.Net.FtpControlStream.GetPathOption Type gpoType = asm.GetType("System.Net.FtpControlStream.GetPathOption"); //結果會找不到 if (gpoType == null)
Console.WriteLine("取得GetPathOption失敗!"); //原來子類別在Type字串中是用+表示的啦 gpoType = asm.GetType("System.Net.FtpControlStream+GetPathOption"); Console.WriteLine(gpoType.FullName);
//同場加映,怎麼宣告內部/私有列舉? //由於限定內部存取,無法用GetPathOption gpo = GetPathOption.Normal就搞定 //所以要透過Enum.Parse(參考: http://bit.ly/QAUvEf) object gpo = Enum.Parse(gpoType, "Normal");
Console.WriteLine(gpo.ToString());
Console.Read();
}
}
}
Comments
Be the first to post a comment