Retrieving Property name from lambda expression

前端 未结 21 1698
迷失自我
迷失自我 2020-11-21 11:12

Is there a better way to get the Property name when passed in via a lambda expression? Here is what i currently have.

eg.

GetSortingInfo         


        
21条回答
  •  爱一瞬间的悲伤
    2020-11-21 11:40

    I've found that some of the suggested answers which drill down into the MemberExpression/UnaryExpression don't capture nested/subproperties.

    ex) o => o.Thing1.Thing2 returns Thing1 rather than Thing1.Thing2.

    This distinction is important if you're trying to work with EntityFramework DbSet.Include(...).

    I've found that just parsing the Expression.ToString() seems to work fine, and comparatively quickly. I compared it against the UnaryExpression version, and even getting ToString off of the Member/UnaryExpression to see if that was faster, but the difference was negligible. Please correct me if this is a terrible idea.

    The Extension Method

    /// 
    /// Given an expression, extract the listed property name; similar to reflection but with familiar LINQ+lambdas.  Technique @via https://stackoverflow.com/a/16647343/1037948
    /// 
    /// Cheats and uses the tostring output -- Should consult performance differences
    /// the model type to extract property names
    /// the value type of the expected property
    /// expression that just selects a model property to be turned into a string
    /// Expression toString delimiter to split from lambda param
    /// Sometimes the Expression toString contains a method call, something like "Convert(x)", so we need to strip the closing part from the end
    /// indicated property name
    public static string GetPropertyName(this Expression> propertySelector, char delimiter = '.', char endTrim = ')') {
    
        var asString = propertySelector.ToString(); // gives you: "o => o.Whatever"
        var firstDelim = asString.IndexOf(delimiter); // make sure there is a beginning property indicator; the "." in "o.Whatever" -- this may not be necessary?
    
        return firstDelim < 0
            ? asString
            : asString.Substring(firstDelim+1).TrimEnd(endTrim);
    }//--   fn  GetPropertyNameExtended
    

    (Checking for the delimiter might even be overkill)

    Demo (LinqPad)

    Demonstration + Comparison code -- https://gist.github.com/zaus/6992590

提交回复
热议问题