列舉未知類別裡面所有的成員:欄位、屬性、方法
在某些時刻(例如你身在一個沒有VisualStudio的開發環境中),面對一個未公開、陌生的類別(Class),我們最想要知道的是它擁有了哪些成員(欄位、屬性、方法...等),這時候我們需要的就是反射(反應)System.Reflection類別來幫我們達成想要的目地了。
假設有一個叫做Sample的Class,對我們來說是全然的陌生的,例如以下:
class Sample
{
private int _iField;
public int iProperty { set { _iField = value; } get { return _iField; } }
public string cMethod(string cName, int iAge) { return "Don'tCare"; }
}
我們可以透過System.Reflection.FieldInfo、System.Reflection.PropertyInfo、System.Reflection.MethodInfo等類別,來取得相關的物件陣列,不過本篇文章為求最大化適用,因此是使用System.Reflection.MemberInfo類別來列舉所有的成員。
在程式碼的中段,針對類别所屬的方法(Method)我們有使用一點小小的System.Linq來進行子查詢,這樣一來我們可以對於參數的部份,進行更深一層的查詢。程式碼如下,請自行參考:
static void Main(string[] args)
{
//取得成員集合
System.Reflection.MemberInfo[] oMembers = typeof(Sample).GetMembers();
//巡訪成員
foreach (var oTemp in oMembers)
{
string cParameters = "";
if (oTemp.MemberType == System.Reflection.MemberTypes.Method)
{
cParameters = string.Format("({0})",
string.Join(
", ",
((System.Reflection.MethodInfo)oTemp).GetParameters()
.Select(obj => obj.ParameterType + " " + obj.Name)
.ToArray()
)
);
}
Console.WriteLine(string.Format("這是:{0},名稱是:{1}{2}",
oTemp.MemberType.ToString(),
oTemp.Name,
cParameters));
}
Console.Read();
}
輸出結果,當然是會把System.Object下所有的東西繼承過來,因此列出的成員中會有Sample Class中我們沒有寫到的成員,這是正常的。輸出的結果如下:
這是:Method,名稱是:set_iProperty(System.Int32 value)
這是:Method,名稱是:get_iProperty()
這是:Method,名稱是:cMethod(System.String cName, System.Int32 iAge)
這是:Method,名稱是:ToString()
這是:Method,名稱是:Equals(System.Object obj)
這是:Method,名稱是:GetHashCode()
這是:Method,名稱是:GetType()
這是:Constructor,名稱是:.ctor
這是:Property,名稱是:iProperty
另外要注意的事,我的GetMembers()是用預設值,也就是不加入任何的引數,這樣一來只會列舉public等級的成員,如果你有需要列舉到private或是static(靜態)、instance(執行個體)區別的方法,這就要加入一些BindingFlags了。例如:
System.Reflection.BindingFlags.Public
System.Reflection.BindingFlags.NonPublic
System.Reflection.BindingFlags.Instance
System.Reflection.BindingFlags.Static