Получить имя свойства строки из выражения - PullRequest
11 голосов
/ 23 сентября 2010

Я пытаюсь написать строго типизированный помощник что будет примерно так:

Html.Lookup(x => x.FooId);

на данный момент у меня есть это:

public static MvcHtmlString Lookup<T,TReturn>(this HtmlHelper<T> html, Func<T, TReturn> expression)
{
     // get string "FooId" here
}

Кто-нибудь знает, как это получить?

Ответы [ 4 ]

24 голосов
/ 23 сентября 2010
public static class ExpressionsExtractor
{
    public static string Lookup<T, TProp>(this HtmlHelper<T> html, Expression<Func<T, TProp>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;

        if (memberExpression == null)
            return null;

        return memberExpression.Member.Name;
    }
}

Затем вы бы назвали его с:

var propName = Html.Lookup(x => x.FooId);
14 голосов
/ 24 сентября 2010

Еще один код.

public MvcHtmlString Lookup<T, TReturn>(this HtmlHelper<T> html, Expression<Func<T, TReturn>> expression)
{
  return MvcHtmlString.Create(ExpressionHelper.GetExpressionText(expression));
}

Используйте класс ExpressionHelper.Func - делегат, Expression - генерировать ExpressionTree во время компиляции.Expression.Compile () возвращает делегат, но Func не получает ExpressionTree во время выполнения.

8 голосов
/ 24 сентября 2010

В настоящее время использую этот класс, когда мне нужна эта функциональность за пределами веб-проекта, где ссылка System.Web.Mvc не должна существовать:

namespace Interreg.Domain{
  using System;
  using System.Linq.Expressions;
  public class PropertyName{
    public static string For<T>(
      Expression<Func<T,object>> expression){
      var body=expression.Body;
      return GetMemberName(body);
    }
    public static string For(
      Expression<Func<object>> expression){
      var body=expression.Body;
      return GetMemberName(body);
    }
    public static string GetMemberName(
      Expression expression){
      if(expression is MemberExpression){
        var memberExpression=(MemberExpression)expression;
        if(memberExpression.Expression.NodeType==
           ExpressionType.MemberAccess)
          return GetMemberName(memberExpression.Expression)+"."+memberExpression.Member.Name;
        return memberExpression.Member.Name;
      }
      if(expression is UnaryExpression){
        var unaryExpression=(UnaryExpression)expression;
        if(unaryExpression.NodeType!=ExpressionType.Convert)
          throw new Exception(string.Format("Cannot interpret member from {0}",expression));
        return GetMemberName(unaryExpression.Operand);
      }
      throw new Exception(string.Format("Could not determine member from {0}",expression));
    }
  }
}

Хорошая вещь в этом - она ​​не теряет точки при углублениичем только один уровень.

0 голосов
/ 22 ноября 2016

немного поздно, но я публикую простое решение, которое работает для меня в .Net 4. В строке 4

public PropertyInfo GetPropertyInfo<TSource>(Expression<Func<TSource, object>> propertyLambda) {
        var member = propertyLambda.Body as MemberExpression;
        if (member == null) {// value types return Convert(x.property) which can't be cast to MemberExpression
            var expression = propertyLambda.Body as UnaryExpression;
            member = expression.Operand as MemberExpression;
        }
        return member.Member as PropertyInfo;
    }
есть обработка типов значений
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...