2012-03-19 204 views
2

我試圖從MemberExpression的實例中檢索屬性的值。從MemberExpression獲取屬性值

這是我到目前爲止有:

protected override void VisitMember(Context context, MemberExpression node) 
{    
    var propertyInfo = node.Member as PropertyInfo; 
    if(propertyInfo != null) 
    { 
     var v = propertyInfo.GetValue(node.Member , null); 
     val = Convert.ToString(v); 
    } 
    context.State.Append(val); 
} 

根據我採取的辦法有兩個問題:我不知道預期的類型(字符串,整數,等...),和/或者我無法訪問MemberExpression中的實例。

我正在爲T-SQL轉換器寫一個小的lambda表達式。例如(u)=> u.FirstName == u.LastName;將轉換爲FirstName = 'chuck'。我幾乎可以工作!

更新

我嘗試下面的代碼:

... 

var propertyInfo = node.Member as PropertyInfo; 

if(propertyInfo != null) 
{ 
    var o = propertyInfo.GetValue(node.Expression, null); 
} 

... 

它沒有工作。我得到以下錯誤:

System.Reflection.TargetException : Object does not match target type. 

更新2

這就是我試圖完成:

public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo) 
    { 
     if (typeof(T) != propertyInfo.DeclaringType) 
     { 
      throw new ArgumentException(); 
     } 

     var instance = Expression.Parameter(propertyInfo.DeclaringType, "i"); 
     var property = Expression.Property(instance, propertyInfo); 
     var convert = Expression.TypeAs(property, typeof(object)); 
     return (Func<T, object>)Expression.Lambda(convert, instance).Compile(); 
    } 

但我並不在編譯時知道T

回答

4

I don't know the expected type (string, int, etc...),

使用Expression.Type

I have not been able access the instance from the MemberExpression

使用MemberExpression.Expression - 顯然這是另一種表達方式,因爲你可能有:

foo.GetBar(20).ToString().Length 

在這種情況下,Length財產將是一個MemberExpression,但Expression財產將給MethodCallExpressionToString

+0

我看過的所有例子都使用了Func (即'(Func )Expression.Lambda(convert,instance).Compile();'),這是一個帶泛型的轉換。泛型當然是編譯時間... – 2012-03-19 23:21:10

+0

...我的問題是,我不知道類型,直到運行時。 – 2012-03-19 23:29:50

+0

@ChuckConway:在這種情況下,您不需要泛型方法,只需要返回'Expression'的東西,據推測。 – 2012-03-20 06:44:44

1

I have not been able access the instance from the MemberExpression.

在你的榜樣u => u.FirstName == "chuck",沒有實例它來獲取FirstName財產。

我想你其實想要的財產的名稱 - 這是node.Member.Name(並在你的例子中是「名字」)。請注意,這適用於所有MemberInfo,而不僅僅是PropertyInfo,因此這些字段也可以工作。 (您可能仍要測試,因爲活動也是成員表達式,但沒有任何意義在這裏。)

I don't know the expected type (string, int, etc...),

預期的類型爲PropertyInfo.PropertyTypeFieldInfo.FieldType

+0

有,它作爲MemberExpression參數傳入。 MemberExpresion是'u.FirstName'。我不在尋找房產的名稱。我正在尋求物業的價值。 – 2012-03-19 23:05:21

+0

但是在一個lambda表達式中,除非您在其他地方提供該屬性的值,否則沒有該屬性值的實例。 u => u.FirstName'將只有一個實例,當你在某個對象上實際調用它時,它將獲取該值。 – porges 2012-03-19 23:07:06

+0

這很有道理。我見過的大多數例子都是在檢索屬性值之前編譯lambda表達式。在這些情況下,類型在編譯時已知。在我的情況下,我不知道類型。 – 2012-03-19 23:29:11