【问题标题】:Convert or Cast List<Widget> to a Widgets class将 List<Widget> 转换或转换为 Widgets 类
【发布时间】:2014-02-20 16:48:13
【问题描述】:

场景:

我正在维护一个大型 ASP.NET 应用程序,其中所有方法都返回一个通用列表。这导致的主要问题是 ObjectDataSource 不支持返回通用列表的方法。

我想做的事:

想出一种在不重写现有方法的情况下使用 ObjectDataSource 的方法。我提供了一种可行的技术,但想知道是否有更好的方法。

我了解我正在尝试的任何方法都会对性能产生负面影响。我主要关心的是减少我必须花费在维护和增强此应用程序上的时间。但是,我想实施一种对性能影响最小的方法。

返回通用列表的方法示例

    public static List<Widget> GetAll()
    {
        List<Widget> temp = new List<Widget>();

        Widget w1 = new Widget();
        w1.Name = "test 1";
        Widget w2 = new Widget();
        w2.Name = "test 2";

        temp.Add(w1);
        temp.Add(w2);

        return temp;
    }

以下方法可行,但我不确定这是最好的方法,因为它需要迭代列表项

public class Widgets : List<Widget>
{
    public Widgets()
    {}
}


public static Widgets GetAll2()
{
   List<Widget> temp = WidgetManager.GetAll();
   Widgets widgets = new Widgets();
   foreach (Widget widget in temp)
   {
      widgets.Add(widget);
   }
   return widgets;
}

以下操作无效。

public class Widgets : List<Widget>
{
    public Widgets()
    {}
}

public static Widgets GetAll2()
{
   List<Widget> tempWidgets1 = GetAll();
   Widgets tempWidgets2 = (Widgets)tempWidgets1;
   return tempWidgets2;
}

以下是基于KMP & kohrhner 提供的答案和评论的完整解决方案。上面的部分代码重复但更详细。

完成这项工作的关键是将以下构造函数添加到实体列表类。除了添加构造函数之外,不需要额外的代码来实现 IEnumerable。

public Widgets(IEnumerable collection) : base(collection) { }

数据访问层

请注意,数据访问层返回的 List 不适用于 ObjectDataSource。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DemoClassLibrary.Entities;

namespace DemoClassLibrary.DAL
{
    public class WidgetDAL
    {
        public static List<Widget> GetAll()
        {
            List<Widget> temp = new List<Widget>();

            Widget w1 = new Widget();
            w1.Name = "test 1";
            Widget w2 = new Widget();
            w2.Name = "test 2";

            temp.Add(w1);
            temp.Add(w2);

            return temp;
        }
    }
}

实体

无需对实体类进行任何更改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoClassLibrary.Entities
{
    public class Widget
    {
        public string Name
        {
            get;
            set;
        }
    }
}

实体列表类

需要创建一个实体列表类才能使用 ObjectDataSource。我的一个关键要求是不能修改原始 DAL。然而,仍然需要使用 DAL 来填充实体列表类。完成这项工作的关键是添加以下构造函数。

public Widgets(IEnumerable collection) : base(collection) { }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoClassLibrary.Entities.Collections
{
    public class Widgets : List<Widget>
    {
        public Widgets(IEnumerable<Widget> collection) : base(collection) { }

        public Widgets()
        { }
    }
}

业务逻辑层

使业务逻辑层工作的关键是实例化 Widgets 类。这有效地将List&lt;Widget&gt; 转换为Widgets

小部件 tempWidgets2 = 新小部件(tempWidgets1)

using System.ComponentModel;
using DemoClassLibrary.DAL;
using DemoClassLibrary.Entities;
using DemoClassLibrary.Entities.Collections;

namespace DemoClassLibrary.BLL
{
    [DataObjectAttribute()]
    public class WidgetManager
    {
        public static Widgets GetAll()
        {
            List<Widget> tempWidgets1 = WidgetDAL.GetAll();
            Widgets tempWidgets2 = new Widgets(tempWidgets1);
            return tempWidgets2;
        }
    }
}

ASPX 页面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"    Inherits="DemoWebApplication._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        DataSourceID="ObjectDataSource1">
            <Columns>
                <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetAll" 
        TypeName="DemoClassLibrary.BLL.WidgetManager"></asp:ObjectDataSource>
    </div>
    </form>
</body>
</html>

【问题讨论】:

  • 难道你不能让小部件拥有 List (即将它传递给构造函数并将其存储为成员变量)吗?这样,您就可以从 Widgets 实现 IEnumerable 并推迟到拥有的列表或您想做的任何事情,以便它可以被 ObjectDataSource 使用。

标签: c# asp.net generics generic-list generic-collections


【解决方案1】:

您可以在您的 Widgets 类中实现一个带有参数的构造函数:

public Widgets(IEnumerable<Widget> collection) : base(collection) { }

你可以这样实例化它:

List<Widget> tempWidgets1 = GetAll();
Widgets tempWidgets2 = new Widgets(tempWidgets1);

【讨论】:

  • 这很好用。乍一看,我以为您一定遗漏了实现 IEnumerable 的代码,但所需要做的只是添加构造函数。我会为所有人发布完整的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
相关资源
最近更新 更多