什么是更好,更清洁的方式使用List <t> </t>

时间:2010-05-25 13:27:53

标签: c# list

我正在寻找一些更好的方法来在我正在使用的几个应用程序中使用List。我目前的实现看起来像这样。

MyPage.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    BLL.PostCollection oPost = new BLL.PostCollection();
    oPost.OpenRecent();
    rptPosts.DataSource = oArt;
    rptPosts.DataBind();
}

BLL班级

public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }

    public void OpenRecentInitFromRow(DataRow row)
    {
        this.PostId = (int) row["id"];
        this.PostTitle = (string) row["title"];
        this.PostContent = (string) row["content"];
        this.PostCreatedDate = (DateTime) row["createddate"];
    }
}
public class PostCollection : List<Post>
{
    public void OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Post oPost = new Post();
            oPost.OpenRecentInitFromRow(row);
            Add(oPost);
        }
    }
}

现在虽然这项工作做得很好,但我只是想知道是否有任何方法可以改进它,并且只是让它更清洁,不得不使用两个不同的类做我认为可能只发生一个类或使用接口。

5 个答案:

答案 0 :(得分:17)

首先,我不会从List<T>派生出来 - 你并不是真正专注于这种行为。

我还建议您可以使Post不可变(至少是外部的),并编写一个静态方法(或构造函数)来创建一个基于DataRow的方法:

public static Post FromDataRow(DataRow row)

同样,你可以有一个列表方法:

public static List<Post> RecentPosts()

返回它们。不可否认,在某种DAL类中可能会更好地作为实例方法,这将允许模拟等。或者,在Post:

public static List<Post> ListFromDataSet(DataSet ds)

现在,关于List<T>本身的使用 - 您使用的是.NET 3.5吗?如果是这样,你可以使用LINQ:

使这个更加整洁
public static List<Post> ListFromDataSet(DataSet ds)
{
    return ds.Tables[0].AsEnumerable()
                       .Select(row => Post.FromDataRow(row))
                       .ToList();
}

答案 1 :(得分:2)

编辑:John Skeet的回答可能是更好的选择。但是,如果您只想进行一些简单的更改,请继续阅读:

将数据库访问代码OpenRecentInitFromRow放入PostCollection并将其视为Post Manager类。这样Post类就是一个普通的旧数据传输对象。

public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }
}

public class PostCollection : List<Post>
{
    public void OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Add(LoadPostFromRow(row));
        }
    }

    private Post LoadPostFromRow(DataRow row)
    {
        Post post = new Post();
        post.PostId = (int) row["id"];
        post.PostTitle = (string) row["title"];
        post.PostContent = (string) row["content"];
        post.PostCreatedDate = (DateTime) row["createddate"];
        return post;
    }
}

答案 2 :(得分:2)

您是从List&lt; T&gt;推导出来的吗?因为你想为PostCollection的其他消费者提供添加和删除项目的能力吗?我猜不是,而你实际上只是想要一种方法来公开你可以绑定的集合。如果是这样,你可以考虑使用迭代器:

class BLL {
    ...

    public IEnumerable<Post> RecentPosts {
        get {
            DataSet ds = DbProvider.Instance().Post_ListRecent(); 
            foreach (DataRow row in ds.Tables[0].Rows) 
            { 
                Post oPost = new Post(); 
                oPost.OpenRecentInitFromRow(row); 
                yield return oPost;
            } 
        }
    }    

    ...
}

尽管这可能被认为是糟糕的形式(因为我们有一个可能正在进行网络调用的属性获取器),但这种迭代器方法将消除为从未枚举的Posts调用OpenRecentInitFromRow的开销。 / p>

您也不知道邮件的潜在消费者可能想要消费它们。绝对,肯定必须让每个Post都可以执行ToList()的代码,但是其他代码可能想要使用LINQ查询,该查询在找到正确的Post之后使枚举短路。

答案 3 :(得分:2)

  

我正在寻找一些更好的方法来使用List

这似乎是一个奇怪的要求。 “列表”类型是一种手段,很少是结束。考虑到这一点,实现真正结束的一种更好的方法是使用IEnumerable而不是List,因为该List强制您将整个集合保留在内存中,而IEnumerable一次只需要一个对象。诀窍在于,您必须在处理流中连接所有,从数据层一直到演示,然后使用它。

我在下面的链接中有一个很好的例子,说明如何以非常干净的方式执行此操作:
Fastest method for SQL Server inserts, updates, selects

根据您现有的数据层代码,您可以浏览(长)帖子的前半部分 - 主要的一点是您使用迭代器块将SqlDataReader转换为IEnumerable<IDataRecord>。一旦掌握了这一点,其余部分就会非常简单。

答案 4 :(得分:0)

你可以这样做:

protected void Page_Load(object sender, EventArgs e)
{
    BLL.PostCollection oPost = new BLL.PostCollection();
    rptPosts.DataSource = Post.OpenRecent();
    rptPosts.DataBind();
}
public class Post
{
    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string PostCreatedDate { get; set; }

    public void OpenRecentInitFromRow(DataRow row)
    {
        this.PostId = (int) row["id"];
        this.PostTitle = (string) row["title"];
        this.PostContent = (string) row["content"];
        this.PostCreatedDate = (DateTime) row["createddate"];
    }

    public static List<Post> OpenRecent()
    {
        DataSet ds = DbProvider.Instance().Post_ListRecent();
        foreach (DataRow row in ds.Tables[0].Rows)
        {
            Post oPost = new Post();
            oPost.OpenRecentInitFromRow(row);
            Add(oPost); //Not sure what this is doing
        }
        //need to return a List<Post>
    }
}