简体   繁体   English

C#中的灵活对象创建

[英]Flexible object creation in C#

I'm creating a custom web server control (extends Panel) that contains a ListControl object. 我正在创建一个包含ListControl对象的自定义Web服务器控件(扩展Panel)。 I want the ListControl type to be flexible, ie allow the type of the ListControl to be specified in the aspx markup. 我希望ListControl类型是灵活的,即允许在aspx标记中指定ListControl的类型。 Currently I'm examining the user's choice and initialising the control using a switch statement: 目前我正在检查用户的选择并使用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.");
        }
    }

Surely there is a more elegant way to do this... obviously I could allow the client code to create the object instead but I want to eliminate the need to use any code other than the aspx markup. 当然有一个更优雅的方法来做到这一点......显然我可以允许客户端代码来创建对象,但我想消除使用除aspx标记之外的任何代码的需要。 Any suggestions would be appreciated. 任何建议,将不胜感激。 Thanks. 谢谢。

You could use a dictionary: 你可以使用字典:

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.");
    }
}

but if you want to be even more flexible, you can bypass the dictionary and use a little bit of reflection: 但是如果你想要更灵活,你可以绕过字典并使用一点点反思:

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.");
    }
}

EDIT: Or if you want the consumer to only have access to the class (since the method is private) you could make the class generic 编辑:或者如果您希望消费者只能访问该类(因为该方法是私有的),您可以使该类具有通用性

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

Check out http://weblogs.asp.net/leftslipper/archive/2007/12/04/how-to-allow-generic-controls-in-asp-net-pages.aspx 查看http://weblogs.asp.net/leftslipper/archive/2007/12/04/how-to-allow-generic-controls-in-asp-net-pages.aspx


This sounds like you may want to use generics 这听起来像你可能想要使用泛型

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

See MSDN docs for more information on generic methods: http://msdn.microsoft.com/en-us/library/twcad0zb(v=vs.80).aspx 有关通用方法的更多信息,请参阅MSDN文档: http//msdn.microsoft.com/en-us/library/twcad0zb(v = vs。80).aspx

Note, the article explains generic methods and how the where keyword is used. 请注意,本文解释了泛型方法以及如何使用where关键字。 But it doesn't explain how the new keyword is used. 但它没有解释如何使用new关键字。 The new keyword specifies that the type argument you provide must have a default constructor . new关键字指定您提供的type参数必须具有默认构造函数 A comment below the article gives another example that uses the new keyword. 本文下面的评论给出了另一个使用new关键字的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM