C# 使用列表的更好、更干净的方法是什么<;T>;

C# 使用列表的更好、更干净的方法是什么<;T>;,c#,list,C#,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();

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

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等级(s)

公共类职位
{
公共int PostId{get;set;}
公共字符串PostTitle{get;set;}
公共字符串后内容{get;set;}
公共字符串后创建数据{get;set;}
public void OpenRecentitFromRow(数据行)
{
this.PostId=(int)行[“id”];
this.PostTitle=(字符串)行[“title”];
this.PostContent=(字符串)行[“content”];
this.PostCreatedDate=(日期时间)行[“createddate”];
}
}
公共类后收集:列表
{
公共图书馆
{
数据集ds=DbProvider.Instance().Post_ListRecent();
foreach(ds.Tables[0].行中的DataRow行)
{
Post oPost=新Post();
oPost.openrecentitfromrow(row);
添加(oPost);
}
}
}

现在,虽然这一切都很好,但我只是想知道是否有任何方法可以改进它,让它更干净,因为我认为使用两个不同的类可以在一个类或使用一个接口中完成某些事情

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

将数据库访问代码OpenRecentitFromRow放入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;
    }
}
公共类职位
{
公共int PostId{get;set;}
公共字符串PostTitle{get;set;}
公共字符串后内容{get;set;}
公共字符串后创建数据{get;set;}
}
公共类后收集:列表
{
公共图书馆
{
数据集ds=DbProvider.Instance().Post_ListRecent();
foreach(ds.Tables[0].行中的DataRow行)
{
添加(LoadPostFromRow(row));
}
}
专用Post LoadPostFromRow(数据行)
{
Post Post=新Post();
post.PostId=(int)行[“id”];
post.PostTitle=(字符串)行[“title”];
post.PostContent=(字符串)行[“内容”];
post.PostCreatedDate=(日期时间)行[“createddate”];
回程站;
}
}

首先,我不会从
列表中派生出
——您并不是真正的专门化行为

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

public static Post FromDataRow(DataRow row)
同样,您也可以使用列表方法:

public static List<Post> RecentPosts()
publicstaticlist-RecentPosts()
这会退回它们。诚然,作为某种DAL类中的实例方法,这可能会更好,它将允许模拟等。或者,在Post中:

public static List<Post> ListFromDataSet(DataSet ds)
公共静态列表ListFromDataSet(数据集ds)
现在,关于
List
本身的使用,您使用的是.NET3.5吗?如果是这样,您可以使用LINQ使其更加整洁:

public static List<Post> ListFromDataSet(DataSet ds)
{
    return ds.Tables[0].AsEnumerable()
                       .Select(row => Post.FromDataRow(row))
                       .ToList();
}
公共静态列表ListFromDataSet(数据集ds)
{
返回ds.Tables[0].AsEnumerable()
.Select(行=>Post.FromDataRow(行))
.ToList();
}
您可以这样做:

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>
    }
}
受保护的无效页面加载(对象发送方,事件参数e)
{
BLL.PostCollection oPost=新的BLL.PostCollection();
rptPosts.DataSource=Post.OpenRecent();
rptPosts.DataBind();
}
公营职位
{
公共int PostId{get;set;}
公共字符串PostTitle{get;set;}
公共字符串后内容{get;set;}
公共字符串后创建数据{get;set;}
public void OpenRecentitFromRow(数据行)
{
this.PostId=(int)行[“id”];
this.PostTitle=(字符串)行[“title”];
this.PostContent=(字符串)行[“content”];
this.PostCreatedDate=(日期时间)行[“createddate”];
}
公共静态列表OpenRecent()
{
数据集ds=DbProvider.Instance().Post_ListRecent();
foreach(ds.Tables[0].行中的DataRow行)
{
Post oPost=新Post();
oPost.openrecentitfromrow(row);
Add(oPost);//不确定这是在做什么
}
//需要返回一个列表
}
}
您之所以从列表中派生,是因为您想为其他收集后的消费者提供添加和删除项目的功能吗?我猜不是,你实际上只是想要一种方法来公开一个可以绑定到的集合。如果是这样,你可以考虑一个迭代器,也许:

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

    ...
}
类BLL{
...
公共IEnumberedrecentposts{
得到{
数据集ds=DbProvider.Instance().Post_ListRecent();
foreach(ds.Tables[0].行中的DataRow行)
{ 
Post oPost=新Post();
oPost.openrecentitfromrow(row);
收益率;
} 
}
}    
...
}
尽管这可能被认为是糟糕的形式(因为我们有一个属性getter可能正在进行网络调用),但这种迭代器方法将消除为从不枚举的帖子调用OpenRecentitFromRow的开销

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

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

这似乎是一个奇怪的要求。“列表”类型是一种手段,很少是目的。记住这一点,实现真正目的的一个更好的方法是使用IEnumerable而不是List,因为该List迫使您将整个集合保存在内存中,而IEnumerable一次只需要一个对象。诀窍在于,您必须连接处理流中的所有内容,fr
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;
            } 
        }
    }    

    ...
}