【问题标题】:Error when trying to cast anonymous object, Razor尝试投射匿名对象 Razor 时出错
【发布时间】:2013-01-14 00:34:22
【问题描述】:

我正在尝试转换一组匿名对象,其中每个对象如下所示:

new {type="internal",title="Linktitle",target="_blank",link="http://www.google.se"}

我已经声明了一个“链接”类,匿名对象应该被强制转换到该类

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

我找到了this 页面,了解如何强制转换匿名对象,但我也是这样做的。还是我错过了什么?

【问题讨论】:

标签: c# linq lambda umbraco


【解决方案1】:

如果relatedLinks 本身是一个动态值,你就会遇到两个问题:

  • 已报告的 lambda 表达式部分
  • 不能对动态值调用扩展方法(as 扩展方法)。这会影响SelectToList 方法。

您可以通过转换 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&lt;dynamic&gt;(或类似的东西),那么您可以将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();

【讨论】:

  • 我收到错误 'object' does not contain a definition for 'ToList'。我已经包含了 System.Linq
  • @AntonGildebrand:啊,好吧 - 我可以解决这个问题。请参阅我编辑的答案。
  • 非常感谢您的帮助!我不太明白为什么 ToList() 不起作用,您介意解释一下吗?
  • @AntonGildebrand:Select 方法是动态调用的,因此就编译器而言,结果是dynamic 类型。这意味着您不能调用ToList 扩展方法。我给出的代码将结果隐式转换为IEnumerable&lt;Link&gt; 以将其分配给query 值,然后您只需使用普通扩展方法即可。
猜你喜欢
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多