2009-10-05 51 views
4

對於下面的Lambda表達式:LAMBDA物業名稱和數組索引

GetPropertyNameAndArrayIndex(() => SomeArray[0]) 

我知道,你可以得到property name的表達式。我也知道你可以通過使用ConstantExpression並訪問Right值來得到數組索引。我的問題是你如何獲得數組索引(或右值)時,它不是一個常數,即

for (int i = 0; i < 5; i++) 
{ 
    GetPropertyNameAndArrayIndex(() => SomeArray[i]) 
} 

任何幫助將不勝感激。

+0

請編輯。 「我知道你可以[缺少動詞]屬性名稱和數組索引」 – 2009-10-05 20:56:29

+0

@Emilio謝謝你指出我可憐的語法:) – Kane 2009-10-05 21:05:01

+3

小心這個片段:lambda將捕獲我的_variable_ in一個closre,而不是變量在創建時的值。您稍後再調用該函數,並且在所有迭代中創建的表達式將評估爲在最後一次迭代中創建的表達式。 – 2009-10-05 21:07:49

回答

3

正如評論中已經指出的那樣;請注意,如果異步使用,則給出的示例容易受到捕獲變量的影響 - 但可能「按原樣」確定。

要做到這一點徹底涉及很多邊緣的情況下(或者你可以欺騙和使用Compile()) - 但這裏顯示的總主題(不使用Compile)的例子:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
class Program 
{ 
    static void Main() 
    { 
     string[] arr = { "abc", "def" }; 
     for (int i = 0; i < arr.Length; i++) 
     { 
      Foo(() => arr[i]); 
     } 
    } 
    static object Foo<T>(Expression<Func<T>> lambda) 
    { 
     object obj = Walk(lambda.Body); 
     Console.WriteLine("Value is: " + obj); 
     return obj; 

    } 
    static object Walk(Expression expr) 
    { 
     switch (expr.NodeType) 
     { 
      case ExpressionType.ArrayIndex: 

       BinaryExpression be = (BinaryExpression)expr; 
       Array arr = (Array)Walk(be.Left); 
       int index = (int) Walk(be.Right); 
       Console.WriteLine("Index is: " + index); 
       return arr.GetValue(index); 
      case ExpressionType.MemberAccess: 
       MemberExpression me = (MemberExpression)expr; 
       switch (me.Member.MemberType) 
       { 
        case MemberTypes.Property: 
         return ((PropertyInfo)me.Member).GetValue(Walk(me.Expression), null); 
        case MemberTypes.Field: 
         return ((FieldInfo)me.Member).GetValue(Walk(me.Expression)); 
        default: 
         throw new NotSupportedException(); 
       } 
      case ExpressionType.Constant: 
       return ((ConstantExpression) expr).Value; 
      default: 
       throw new NotSupportedException(); 

     } 
    } 

} 
+0

@Marc我很謙虛...非常感謝 – Kane 2009-10-06 07:01:33

+0

這是一個詳盡無遺的步行列表嗎? – Maslow 2010-06-16 17:07:59

+0

@Maslow絕對不是。我有一個更完整的3.5列表,但是它在4.0中再次增長。訣竅是弄清楚你需要支持哪些場景。 – 2010-06-16 20:06:50