繁体   English   中英

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

[英]What is a better, cleaner way of using List<T>

我正在寻找在我正在开发的几个应用程序中实现一些更好的方法来使用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);
        }
    }
}

现在虽然这一切都运行得很好,但我只是想知道是否有任何方法可以改进它,并且只是让它更清洁,不得不使用两个不同的类做我认为可能只在一个类或使用一个界面。

首先,我不会从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();
}

编辑: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;
    }
}

您是从List <T>派生的,因为您想为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的开销。

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

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

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

我在下面的链接中有一个很好的例子,关于如何以非常干净的方式执行此操作:
SQL Server最快的插入,更新和选择方法

根据您现有的数据层代码,您可以浏览(长)帖子的前半部分 - 主要的一点是您使用迭代器块将SqlDataReader转换为IEnumerable<IDataRecord> 一旦你拥有了它,那么在剩下的时间里它非常简单。

你可以这样做:

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>
    }
}

暂无
暂无

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

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