C# 编译器错误:无法转换 lambda 表达式
Posted
技术标签:
【中文标题】C# 编译器错误:无法转换 lambda 表达式【英文标题】:C# compiler error: Cannot convert lambda expression 【发布时间】:2011-07-15 13:08:15 【问题描述】:我正在尝试使用 Lambda 表达式和反射来获取成员分层名称(而不是使用文本常量),以在我的控件绑定信息无效时强制执行编译时错误。
这是在 ASP.NET MVC 项目中,但它不是特定于 MVC 的问题 AFAIK。编辑:具体来说,我希望以下评估为真:
string fullname = GetExpressionText(model => model.Locations.PreferredAreas);
"Locations.PreferredAreas" == fullname;
我得到一个编译错误:
错误 4:无法将 lambda 表达式转换为类型 'System.Linq.Expressions.LambdaExpression' 因为它不是委托类型。
为什么参数在下面的第二种情况下起作用,而在第一种情况下不起作用?
// This doesn't compile:
string tb1 = System.Web.Mvc.ExpressionHelper.
GetExpressionText(model => model.Locations.PreferredAreas);
// But this does:
MvchtmlString tb2 =
Html.TextBoxFor(model => model.Locations.PreferredAreas);
这是来自 ASP.NET MVC Codeplex 项目的相关代码。在我看来,它将相同的参数传递给相同的方法:
// MVC extension method
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
return TextBoxHelper(
htmlHelper,
metadata,
metadata.Model,
ExpressionHelper.GetExpressionText(expression),
htmlAttributes);
// MVC utility method
public static string GetExpressionText(LambdaExpression expression)
// Split apart the expression string for property/field accessors to create its name
// etc...
【问题讨论】:
你忘了包括你的问题最相关的部分——GetExpressionText 源代码:) 没关系,它是一个 MVC 助手。看我的回答。 这真的相关吗?基于 Eric Lippert 的回答(他回答的内容,而不仅仅是他能够回答的事实)GetExpressionText 背后的来源不相关,对吧? 你还记得你最终做了什么吗?那个代表埃里克在说什么? 查看下面的另一个答案以获得代码示例,Lum。 【参考方案1】:错误信息是正确的。可以将 lambda 转换为兼容的委托类型 D 或表达式兼容的委托类型 Expression<D>
。 Expression<Func<TM, TP>>
就是其中之一。 “LambdaExpression”不是那些。因此,您在尝试将 lambda 转换为 LambdaExpression,而不是实际的表达式树类型时遇到错误。那里一定有一个代表。
【讨论】:
谢谢你,埃里克,我相信你是对的。我正在努力理解它:) 所以你说 (lambda to Expression在尝试修复 lambda 表达式之前,请确保已添加以下引用:
System.Linq; System.Linq.Expressions;
缺少这些引用也可能导致相同的错误(“无法将 lambda 表达式转换为类型 'System.Linq.Expressions.Lambda 表达式',因为它不是委托类型”)。
希望这会有所帮助...
【讨论】:
【参考方案3】:我认为你应该尝试使用这样的辅助方法:
public static string GetExpressionText<M, P>(this M model, Expression<Func<M, P>> ex)
return GetExpressionText(ex);
【讨论】:
这似乎可行,但M的实例不是必需的,所以这实际上不属于扩展方法,对吧? 没错,您可以将此帮助程序声明为GetExpressionText<M, P>(Expression<Func<M, P>> ex)
,但在这种情况下,您必须明确指定类型参数。扩展方法语法更简洁,虽然它需要声明一个“未使用”参数。
对不起,我无法在两个地方给出答案 - Eric 修复了我的大脑,你给了我我需要的代码......这是一个折腾,但我认为 Eric 回答了我的问题并在此过程中尝试(几乎成功)教一个人钓鱼。以上是关于C# 编译器错误:无法转换 lambda 表达式的主要内容,如果未能解决你的问题,请参考以下文章
错误:无法将 lambda 表达式转换为类型“bool”,因为它不是 Kendo Chart 中的委托类型