要 using System.Reflection、System.ComponentModel、System.Text 三個命名空間
public string ListFields(Type type)
{
StringBuilder sb = new StringBuilder();
FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
sb.Append(@"<table border='1' cellpadding='3' cellspacing='0'><tr><th>Field Name</th>
<th>Type</th><th>Static</th></tr>");
foreach (FieldInfo fInfo in fieldInfos)
{
sb.AppendFormat("<tr><td>{0:s}</td><td>{1:s}</td><td>{2:s}</td></tr>",
fInfo.Name, fInfo.FieldType.FullName, fInfo.IsStatic ? "Yes" : "No");
}
sb.Append("</table>");
return sb.ToString();
}
這樣就可以把 type 裡面定義的私有欄位,用 Table 的方式顯示出來
如果私有欄位定義在 base class 中,則傳入 obj.GetType().BaseType
執行範例一:
System.Web.UI.WebControls.FormView() FormView1 = new System.Web.UI.WebControls.FormView();
ListFields(FormView1.GetType());
Field Name | Type | Static |
EventPageIndexChanged | System.Object | Yes |
EventPageIndexChanging | System.Object | Yes |
EventItemCommand | System.Object | Yes |
EventItemCreated | System.Object | Yes |
EventItemDeleted | System.Object | Yes |
EventItemDeleting | System.Object | Yes |
EventItemInserting | System.Object | Yes |
EventItemInserted | System.Object | Yes |
EventItemUpdating | System.Object | Yes |
EventItemUpdated | System.Object | Yes |
EventModeChanged | System.Object | Yes |
EventModeChanging | System.Object | Yes |
執行範例二:
System.Web.UI.WebControls.DropDownList DopDownList1 = new System.Web.UI.WebControls.DropDownList();
ListFields(DropDownList1.GetType());
??怎麼沒有東西??
那麼改用
ListFields(dropDownList1.GetType().BaseType) 試看看
Field Name | Type | Static |
EventSelectedIndexChanged | System.Object | Yes |
EventTextChanged | System.Object | Yes |
果然有了!
拿到這些私有欄位的名稱有什麼用?各位發覺到了嗎,這些私有欄位都是以 Event 開頭的,也就是說這些是用來儲存 Delegate 的私有變數
接下來,就可以利用以下的程式,來呼叫「已經綁定在物件上的事件處理函式」
public void InvokeEvent(object obj, Type type, string eventName, EventArgs e)
{
PropertyInfo propertyInfo = (type.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic));
EventHandlerList eventHandlerList = (EventHandlerList)propertyInfo.GetValue(obj, null);
FieldInfo fieldInfo = type.GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic);
Delegate[] dels = eventHandlerList[fieldInfo.GetValue(null)].GetInvocationList();
foreach (Delegate d in dels)
{
d.Method.Invoke(d.Target, new object[] { obj, e });
}
}
呼叫範例:
InvokeEvent(DropDownList1, DropDownList1.GetType().BaseType, "EventSelectedIndexChanged", e);