在做Rss输出的时候,想把经常用到的linq放到一个方法内
var feedtop
=
(from feed
in
rssFeeds[
0
].Descendants(
"
item
"
)
select new
{
Title = feed.Element("title").Value,
Link = feed.Element("link").Value,
Author = feed.Element("author").Value,
PubDate = DateTime.Parse(feed.Element("pubDate").Value),
Description = feed.Element("description").Value
} ).Take(count);
select new
{
Title = feed.Element("title").Value,
Link = feed.Element("link").Value,
Author = feed.Element("author").Value,
PubDate = DateTime.Parse(feed.Element("pubDate").Value),
Description = feed.Element("description").Value
} ).Take(count);
- 问题:匿名类型的对象无法传递到方法体外
问题出现了,开始想找到返回匿名类型的方法 想到利用C#的类型推导(这里有 07年Dah的一篇文章细说 [C# 3.0] 传递匿名类型对象的问题),来返回匿名类型,可是 在方法声明的时候必须指明方法返回值的类型。
这让我犯难了,没办法搬出终极武器Msdn。
这里引用一下Msdn的话
匿名类型具有方法范围。若要向方法边界外部传递一个匿名类型或一个包含匿名类型的集合,必须首先将匿名类型强制转换为对象。但是,这会使匿名类型的强类型化无效。如果必须存储查询结果或者必须将查询结果传递到方法边界外部,请考虑使用普通的命名结构或类而不是匿名类型。
2. 解决方法:投影匿名类型
开始改造我们最初的代码,
首先要提炼出代替匿名类型的实体类
public
class
Rss
{
public string Title { get ; set ; }
public string Link { get ; set ; }
public string Author { get ; set ; }
public DateTime PubDate { get ; set ; }
public string Description { get ; set ; }
public Rss( string title, string link, string author, DateTime pubDate, string description)
{
Title = title;
Link = link;
Author = author;
PubDate = pubDate;
Description = description;
}
}
{
public string Title { get ; set ; }
public string Link { get ; set ; }
public string Author { get ; set ; }
public DateTime PubDate { get ; set ; }
public string Description { get ; set ; }
public Rss( string title, string link, string author, DateTime pubDate, string description)
{
Title = title;
Link = link;
Author = author;
PubDate = pubDate;
Description = description;
}
}
接着很简单替换掉new{} 并构造存放linq的方法
private
IEnumerable
<
Rss
>
XElementToRss(IEnumerable
<
XElement
>
rssitem,
int
top)
{
return (from feed in rssitem
select new Rss(
feed.Element( " title " ).Value,
feed.Element( " link " ).Value,
feed.Element( " author " ).Value,
DateTime.Parse(feed.Element( " pubDate " ).Value),
feed.Element( " description " ).Value
)).Take(top);
}
{
return (from feed in rssitem
select new Rss(
feed.Element( " title " ).Value,
feed.Element( " link " ).Value,
feed.Element( " author " ).Value,
DateTime.Parse(feed.Element( " pubDate " ).Value),
feed.Element( " description " ).Value
)).Take(top);
}
在外围就可以进行调用了
XDocument rssfeed
=
XDocument.Load(path);
var feeddb = XElementToRss(rssfeed.Descendants( " item " ), 20 );
var feeddb = XElementToRss(rssfeed.Descendants( " item " ), 20 );
Ps:在做Rss的程序开始用的RssToolkit.dll 然后 toDataTable(), 因为要把多个源合并到一起进行处理,所以效率极其低下。后来突然想起自己为什么不用linq 然后把代码改造成了linq的 呵呵节省50多行代码。