【发布时间】:2011-05-24 03:01:42
【问题描述】:
我正在构建一个包含三种主要类型的“在线新闻出版物”的网站:Article、BlogPost 和 ColumnPost。在整个站点上,我有各种控件可以输出这些列表,混合在一起和未混合。因此,在许多控件上,我有一个文章列表,而在其他控件上,我可以有一个博客文章和专栏文章列表。在一些地方,我什至有文章、博客文章和专栏文章的列表。所以我围绕这三个创建了一个包装类,称为Publication。我以前的类是这样继承的:
BasePage : System.Web.UI.Page
Article : BasePage
BlogPost : BasePage
ColumnPost : BasePage
many other pages types : BasePage
使用我的新 Publication 包装器,它们看起来像:
BasePage : System.Web.UI.Page
Publication : BasePage
Article : Publication
BlogPost : Publication
ColumnPost : Publication
现在我可以这样做了:
var dataSource = new List<Publication>();
articlesForThisControl().ForEach(a => dataSource.Add(a));
blogPostsForThisControl().ForEach(bp => dataSource.Add(bp));
columnPostsForThisControl().ForEach(cp => dataSource.Add(cp));
... dataSource.SortByDate() ...
现在最重要的是,我使用 C# 中的中介者模式在许多可能需要重叠数据的竞争控件之间进行调解。我以前有一个ArticleMediator,但现在我把它改成了PublicationMediator。
我的问题:
从基类列表中检索派生类列表的最佳/最简单方法是什么?所以我的中介基本上接受List<Publication> 并返回List<Publication>。如果我知道列表中的所有内容都是Article,那么有什么简单的方法可以将其取回并将其转换为List<Article>?现在我正在做以下这似乎是很多代码,但如果这是我应该做的,那我很好。我只是想知道是否有更简单的方法:
List<Article> articles = new List<Article>();
PublicationMediator.CalculateResults();
PublicationMediator.GetResults(this.UniqueID).PublicationList.Where(p => p is Article).ToList().ForEach(p => articles.Add((Article)p));
PublicationList 属性是返回的List<Publication>,中介已决定允许当前控件使用。我知道我只想要一个List<Article>,所以我必须遍历列表中的每个Publication,并确保它是一个Article,然后我必须将它添加到一个实际的List<Article>。有没有更简单的方法来做到这一点?
我不想更改调解器以返回List<Article> 的原因是因为在某些地方我需要BlogPost 和ColumnPost 所以我实际上需要将我的转发器绑定到List<Publication> 和范围内ItemDataBound 可以查看当前项是BlogPost 还是ColumnPost。
更新
我接受了接受的答案并将其制成扩展名:
public static List<T> GetSublist<T>(this List<Publication> publications) where T : Publication {
return publications.OfType<T>().ToList<T>();
}
【问题讨论】:
标签: c# asp.net linq abstraction base-class