ifade

2010-09-23 30 views
10

Böyle bir şey olacağını kesinlikle yazılı yardımcı yazmaya çalışıyorum dize özellik adı alın Bunu almak için?ifade

var propName = Html.Lookup(x => x.FooId); 
+0

bir dize olarak mülkü al [olası yinelenen, Bir İfadeden >] (http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) –

+1

Neden yeniden keşfediyorsunuz? 'ViewData.ModelMetadata'? –

+0

@Craig Stuntz Gerçekten ne demek istediğimi anlamadım, sadece yazılan bir yardımcı oluşturucu oluşturmak istiyorum – Omu

cevap

22
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; 
    } 
} 

Sonra onu çağırır.

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

Kullanım ExpressionHelper sınıfı. Func delege, İfade derleme zamanında ExpressionTree üretiyor. Expression.Compile() dönüş temsilcisi, ancak Func çalışma zamanında ExpressionTree alamadı.

+0

Bunun işe yarayacağını düşünüyorum. ama sanki doğru bir şekilde ifade etmediğimi ya da bir şey kullanamayacağımı düşünmüştüm. – Omu

+0

istediğim soruyu şimdi düzenledim – Omu

+0

Sorunun cevabını güncellenen soruyla eşleştirin. –

12

Henüz başka kod:

+1

için mücadele ediyorum Bu yana, ben Mvc çerçevenin kendisi kullanır neden olur. –

+0

Bu ayrıca, yukarıda kabul edilen yanıtın tersine "Class.PropertName" değerini döndürür. –

8

Ben System.Web.Mvc referans var olmamalıdır nerede web projesi dışında bu işlevselliği gerektiğinde Şu anda bu sınıfını kullanarak: bu hakkında

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

İyi şey - derine sadece bir daha giderken o nokta kaybetmez seviyesi.

0

biraz geç ama hattı 4

üzerinde değer türleri için .Net Bu işleme etti 4'te benim için çalışıyor basit bir çözüm ilanıyla
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; 
    }