我试图转换一个匿名对象数组,其中每个对象看起来像这样:
new {type="internal",title="Linktitle",target="_blank",link="http://www.google.se"}
我已经声明了一个类"Link",匿名对象应该被强制转换为这个类
class Link{
public string type {get;set;}
public string target {get;set;}
public string title {get;set;}
public string link {get;set;}
}
现在我正在尝试转换对象,像这样
List<Link> links = Model.relatedLinks.Select(l => new Link{type=l.type,target=l.target,title=l.title,link=l.link}).ToList();
然后我得到错误
Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
我找到了这个关于如何cast匿名对象的页面,但我用同样的方式来做。还是我错过了什么?
如果relatedLinks
本身是一个动态值,则有两个问题:
- 已经报告的lambda表达式部分
- 扩展方法不能在动态值上调用(作为扩展方法)。这影响
Select
和ToList
方法。
可以通过转换lambda表达式来绕过第一个。您可以通过直接调用Enumerable.Select
来处理第二个问题:
// Note: don't use var here. We need the implicit conversion from
// dynamic
IEnumerable<Link> query = Enumerable.Select(Model.relatedLinks,
(Func<dynamic, Link>) (l => new Link {
type = l.type,
target = l.target,
title = l.title,
link = l.link } );
var links = query.ToList();
或者为了便于格式化:
Func<dynamic, Link> projection = l => new Link {
type = l.type,
target = l.target,
title = l.title,
link = l.link };
IEnumerable<Link> query = Enumerable.Select(Model.relatedLinks, projection);
var links = query.ToList();
如果Model.relatedLinks
已经是IEnumerable<dynamic>
(或类似的东西),那么你可以调用Select
作为扩展方法代替-但你仍然需要有一个强类型委托。例如,后一个版本将变成:
Func<dynamic, Link> projection = l => new Link {
type = l.type,
target = l.target,
title = l.title,
link = l.link };
IEnumerable<Link> query = Model.relatedLinks.Select(projection);
var links = query.ToList();