列舉未知類別裡面所有的成員:欄位、屬性、方法

在某些時刻(例如你身在一個沒有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
反射 反應 System.Reflection Fields Properties Methods Events