2012-11-09 23 views
2
class Program 
{ 
    static void Main(string[] args) 
    { 
     Expression<Func<string[], Poco>> exp = a => new Poco { MyProperty1 = a[0], MyProperty2 = a[1], MyProperty3 = a[2] }; 
     var lambda = exp.Compile(); 

     var output = lambda(new[] {"one", "two", "three"}); 

     Console.WriteLine(output.MyProperty1); 
    } 
} 

class Poco 
{ 
    public string MyProperty1 { get; set; } 
    public string MyProperty2 { get; set; } 
    public string MyProperty3 { get; set; } 
} 

我對調用lambda的部分不感興趣,這只是爲了完整性。我完全失去了試圖瀏覽表達樹,這可能教我如何釣魚。鑑於這個lambda,我怎樣才能用表達式樹手動編寫它?

回答

1
private static Expression<Func<string[], Poco>> CreateExpr() 
{ 
    ParameterExpression paramExpr = Expression.Parameter(typeof(string[]), "a"); 
    var newExpr = Expression.New(typeof(Poco)); 

    var memberExprs = Enumerable.Range(0, 3) 
     .Select(i => 
     { 
      string propertyName = "MyProperty" + (i + 1); 
      var property = typeof(Poco).GetProperty(propertyName); 
      Expression.Bind(property, Expression.ArrayIndex(paramExpr, Expression.Constant(i))); 
     }); 

    var expr = Expression.MemberInit(newExpr, memberExprs); 
    return Expression.Lambda<Func<string[], Poco>>(expr, paramExpr); 
} 
+0

+1,我很好奇,是否有任何理由使用'Item'屬性超過'Expression.ArrayIndex'? –

+0

@ default.kramer - 我不知道「Expression.ArrayIndex」。我已經更新了使用它的答案,所以謝謝! – Lee

1

我現在沒有時間翻譯完整的樹,但您可以做的一件事是編譯您的代碼,然後使用ildasm(或反射器等)來查看編譯器正在做什麼。你不能總是在自己的代碼中完成相同的操作,但它可以讓你瞭解你想要的表達方式。特別是,在這種情況下,你會想:

如果我得到的時間以後,我會嘗試構建一個完整的工作示例創建Expression<TDelegate>

相關問題