4

我正在创建一个包含 ListControl 对象的自定义 Web 服务器控件(扩展面板)。我希望 ListControl 类型灵活,即允许在 aspx 标记中指定 ListControl 的类型。目前我正在检查用户的选择并使用 switch 语句初始化控件:

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 标记之外的任何代码的需要。任何建议,将不胜感激。谢谢。

4

2 回答 2

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.");
    }
}
于 2013-05-01T02:19:15.883 回答
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关键字指定您提供的类型参数必须具有默认构造函数。文章下方的评论给出了另一个使用新关键字的示例。

于 2013-05-01T02:32:14.313 回答