C# compiler error: Cannot convert lambda expression

13,443

Solution 1

The error message is correct. A lambda can be converted to a compatible delegate type, D, or to an expression-of-compatible-delegate-type Expression<D>. Expression<Func<TM, TP>> is one of those. "LambdaExpression" is neither of those. Therefore you get an error trying to convert the lambda to LambdaExpression, but not to an actual expression tree type. There has to be a delegate in there somewhere.

Solution 2

Before trying to fix the lambda expressions, be sure that the following references have already been added:

System.Linq;
System.Linq.Expressions;

The lack of these references may cause the same error as well ("Cannot convert lambda expression to type 'System.Linq.Expressions.Lambda Expression' because it is not a delegate type").

Hope this helps...

Solution 3

I think you should try to use a helper method like that:

public static string GetExpressionText<M, P>(this M model, Expression<Func<M, P>> ex)
{
    return GetExpressionText(ex);
}
Share:
13,443
shannon
Author by

shannon

Updated on June 05, 2022

Comments

  • shannon
    shannon almost 2 years

    I'm trying to use a Lambda expression and reflection to get a member hierarchical name (rather than using a text constant), to enforce compile-time errors if my control binding information is invalid.

    This is in an ASP.NET MVC project, but it's not an MVC-specific question AFAIK. EDIT: Specifically, I want the following to evaluate to true:

    string fullname = GetExpressionText(model => model.Locations.PreferredAreas);
    "Locations.PreferredAreas" == fullname;
    

    Instead I get a compile error:

    Error 4: Cannot convert lambda expression to type 'System.Linq.Expressions.LambdaExpression' because it is not a delegate type.

    Why does the parameter work in the second case below, but not the first?

    // 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);
    

    Here's the relevant code from the ASP.NET MVC Codeplex project. It looks to me like it passes the same parameter through to the same method:

    // 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...