2013-05-01 75 views
4

我正在創建一個包含ListControl對象的自定義Web服務器控件(擴展Panel)。我希望ListControl類型是靈活的,即允許在aspx標記中指定ListControl的類型。目前我正在檢查用戶的選擇和使用switch語句初始化控制:在C#中創建靈活的對象

public ListControl ListControl { get; private set; } 

private void InitialiseListControl(string controlType) { 
     switch (controlType) { 
      case "DropDownList": 
       ListControl = new DropDownList(); 
       break; 
      case "CheckBoxList": 
       ListControl = new CheckBoxList(); 
       break; 
      case "RadioButtonList": 
       ListControl = new RadioButtonList(); 
       break; 
      case "BulletedList": 
       ListControl = new BulletedList(); 
       break; 
      case "ListBox": 
       ListControl = new ListBox(); 
       break; 
      default: 
       throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified."); 
     } 
    } 

當然還有一個更優雅的方式來做到這一點...很明顯,我可以允許客戶端代碼來創建對象,而不是,但我想消除使用除aspx標記之外的任何代碼的需要。任何建議,將不勝感激。謝謝。

+0

用戶是指其他正在使用ListControl的開發人員,還是指實際用戶? – 2013-05-01 02:42:37

+0

是的,我指的是將在頁面上使用此控件的開發人員。我希望他們能夠在標記中指定類型,例如 kad81 2013-05-01 02:55:42

回答

5

你可以使用字典:

Dictionary<string, Type> types = new Dictionary<string, Type>(); 
types.Add("DropDownList", typeof(DropDownList)); 
... 

private void InitialiseListControl(string controlType) 
{ 
    if (types.ContainsKey(controlType)) 
    { 
     ListControl = (ListControl)Activator.CreateInstance(types[controlType]); 
    } 
    else 
    { 
     throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified."); 
    } 
} 

,但如果你想更加靈活,可以繞過字典和使用反射的一點點:

private void InitialiseListControl(string controlType) 
{ 
    Type t = Type.GetType(controlType, false); 
    if (t != null && typeof(ListControl).IsAssignableFrom(t)) 
    { 
     ListControl = (ListControl)Activator.CreateInstance(t); 
    } 
    else 
    { 
     throw new ArgumentOutOfRangeException("controlType", controlType, "Invalid ListControl type specified."); 
    } 
} 
+0

愛上你的第二個建議,但是GetType方法拋出了一個異常,無法在可用程序集中找到類型......我不得不手動加載System.Web程序集,然後使用assembly.GetType來代替。 – kad81 2013-05-01 04:41:24

2

編輯:或者如果你想消費者只能訪問該類(因爲該方法是私人的),你可以使該類通用

public class MyController<TList> where TList : ListControl, new() 
{ 
    public TList ListControl { get; private set; } 
} 

退房http://weblogs.asp.net/leftslipper/archive/2007/12/04/how-to-allow-generic-controls-in-asp-net-pages.aspx


這聽起來像是你可能想使用泛型

private void InitialiseListControl<TList>() where TList : ListControl, new() 
{ 
    ListControl = new TList(); 
} 

參見MSDN文檔上通用的方法的詳細信息:http://msdn.microsoft.com/en-us/library/twcad0zb(v=vs.80).aspx

注意,本文僅介紹泛型方法以及如何使用where關鍵字。但它沒有解釋如何使用new關鍵字。 new關鍵字指定您提供的類型參數必須具有default constructor。文章下面的評論給出了另一個使用new關鍵字的例子。