在 UserControl 中使用泛型类型的正确方法是什么?

bdr*_*ing 5 .net c# asp.net generics

对于初学者来说,也许有人可以帮助更好地命名这个问题。

我想要实现的目标:

下面是我想要实现的目标的一个非常简单的示例,仅使用基本工作部件就能够得出我正在寻找的解决方案。

我希望能够在 .ascx.cs 代码隐藏中创建以下文件:

public partial class DynamicControl<T> : System.Web.UI.UserControl where T : class
{
    public List<T> Items;

    public void Add(T item) {
        Items.Add(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

在 .ascx 文件中正确引用此内容:

<% foreach (var item in Items) { %>
    <p>item.Name</p>
<% } %>
Run Code Online (Sandbox Code Playgroud)

并将其加载到带有如下标记的 .aspx 文件中:

<custom:DynamicControl ID="DynamicControl1" ItemType="Person" runat="server" />
Run Code Online (Sandbox Code Playgroud)

或者甚至在 .aspx.cs 代码隐藏中为:

DynamicControl1.ItemType = Type.GetType("Person");
Run Code Online (Sandbox Code Playgroud)

真的,一切皆有可能。

我只需要一种在我的网站上创建通用用户控件的方法,我可以在其中以编程方式(或在标记中)设置项目类型,并使用 .ascx.cs 和 .ascx 文件以及引用的 .aspx 文件。

我尝试过的:

1)创建一个DynamicControlBuilder并继承该类ControlBuilder,然后使用 将该类附加为属性[ControlBuilder(typeof(DynamicControlBuilder))]。结果使得控件不会将泛型类型添加到 .aspx.designer.cs 文件中,并且 .ascx 文件也不知道如何呈现。

2)创建使用泛型类型的类的内部属性DynamicControl,只是我找不到类似DynamicControl<dynamic>或类似的默认成员的良好解决方案 - 因为显然该对象在那时不兼容我不会得到任何自动完成或编译时错误处理。

3)使用一种方法来执行类似的操作Add<T>(T item) where T : class,例如,这就是我现在正在做的事情......但是如果我想向单个控件添加大量项目,这就会变得丑陋。我不希望开发人员每次都必须为每个方法重新声明类型。它也没有解决那里的问题List<T> Items,这意味着我没有从那一端得到自动完成,这也很丑陋。

先感谢您!

Mat*_*son 0

我可以问你想做什么吗?

如果要显示许多不同类型的项目,更好的策略是拥有一个像 IDisplayable 这样的接口,列出显示项目所需的属性。现在任何项目都可以放在界面上并能够被控件使用,并且控件不必担心知道如何从许多不同的对象中挖掘显示信息。

所以你的控件就变成了公共部分类 DisplayItemsControl : System.Web.UI.UserControl { public List Items;

public void Add(IDisplayable item) {
    Items.Add(item);
}
Run Code Online (Sandbox Code Playgroud)

}

而且,考虑到上面的例子,界面就是

公共接口 IDisplayable { 字符串名称{get;} }