代码之家  ›  专栏  ›  技术社区  ›  Tim Meers

使用列表的更好、更干净的方法是什么

  •  9
  • Tim Meers  · 技术社区  · 16 年前

    我想在我正在开发的几个应用程序中实现一些更好的使用列表的方法。我当前的实现如下所示。

    我的网页.aspx.cs

    protected void Page_Load(object sender, EventArgs e)
    {
        BLL.PostCollection oPost = new BLL.PostCollection();
        oPost.OpenRecent();
        rptPosts.DataSource = oArt;
        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 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 回复  |  直到 16 年前
        1
  •  17
  •   Jon Skeet    16 年前

    首先,我不会从 List<T> -你并不是真的擅长这种行为。

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

    public static Post FromDataRow(DataRow row)
    

    同样,您也可以使用列表方法:

    public static List<Post> RecentPosts()
    

    实例 方法,这将允许模拟等。或者,在Post中:

    public static List<Post> ListFromDataSet(DataSet ds)
    

    列表<T> 本身-您正在使用.NET3.5吗?如果是这样,您可以使用LINQ使其更整洁:

    public static List<Post> ListFromDataSet(DataSet ds)
    {
        return ds.Tables[0].AsEnumerable()
                           .Select(row => Post.FromDataRow(row))
                           .ToList();
    }
    
        2
  •  2
  •   lesscode    16 年前

    您是否从列表中派生<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;
                } 
            }
        }    
    
        ...
    }
    

    你也变得不知道你的文章的潜在消费者会如何消费它们。绝对肯定必须让每个Post都可以执行ToList(),但其他代码可能希望使用LINQ查询,在找到正确的Post后使枚举短路。

        3
  •  2
  •   Daniel Dyson    16 年前

    编辑:约翰斯凯特的答案可能是一个更好的选择。但如果你只想做一些简单的改变,请继续阅读:

    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;
        }
    }
    
        4
  •  2
  •   Community Mohan Dere    9 年前

    我想实现一些更好的使用列表的方法

    这似乎是个奇怪的要求。“列表”类型是一种手段,很少是目的。记住这一点,实现真正目的的一个更好的方法是使用IEnumerable而不是List,因为List迫使您将整个集合保存在内存中,而IEnumerable一次只需要一个对象。诀窍就在于你得用电线 在处理流中,从数据层一直到表示,使用它。

    我在下面的链接中有一个很好的例子,关于如何以一种非常干净的方式做到这一点:
    Fastest method for SQL Server inserts, updates, selects

    IEnumerable<IDataRecord> . 一旦你做到了,剩下的过程就很简单了。

        5
  •  0
  •   BlackICE    16 年前

    你可以这样做:

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