2013-05-14 10 views
5

私は、次の目標は果たしていき表現構築するにはどうすればよい:は動的に式を使用したプロパティ文字列を評価

public object Eval(object rootObj, string propertyString)

は、例えば:私は「ドンのでEval(person, "Address.ZipCode") => return person.Address.ZipCode

Expression.PropertyOrFieldは動作しませんがそれぞれの中間プロパティの型を持っています。私はスクリプトライブラリに依存関係を作成しないようにしたいと思います。

式を使用しようとしたいのは、これらの式のツリーを複数回実行するときにキャッシュを格納できるからです。私はこれを反復的にまたは再帰的に反映させることが可能であることを認識しています。

+0

私はロザリンがテーブルから外れていると仮定していますか? –

答えて

10

あなたはこのような何かを探しているようですね:

public object Eval(object root, string propertyString) 
{ 
    var propertyNames = propertyString.Split('.'); 
    foreach(var prop in propertyNames) 
    { 
     var property = root.GetType().GetProperty(prop); 
     if (property == null) 
     { 
      throw new Exception(...); 
     } 

     root = property.GetValue(root, null); 
    } 

    return root; 
} 

このExpression使用を作成するには:

public Expression Eval(object root, string propertyString) 
{ 
    var propertyNames = propertyString.Split('.'); 
    ParameterExpression param = Expression.Parameter(root.GetType, "_"); 
    Expression property = param; 
    foreach(var prop in propertyName) 
    { 
     property = Expression.PropertyOrField(property, prop); 
    } 

    return Expression.Lambda(property, param); 
} 
+0

+1 - 私はこのようなことに取り組んでいましたが、あなたは私にそれを打ちました。 – Bobson

+0

'Person.Address.Zipcode'の例では、プロパティとして' Zipcode'を持たないルートオブジェクト 'Person'があります。これはクラス/ struct' Address'のプロパティです。だから私は再帰的な評価が必要だと思う。 –

+2

@JohnWillemse - 各反復で 'root'が変わるので、2回目のパスでは' Zipcode'の 'Address'を見ています。 – Bobson

3

ここExpressionsと協力し、pswgのコードの再帰バージョンです。

public Expression Eval(Expression expression, string property) 
{ 
    var split = property.Split('.'); 
    if (split.Length == 1) 
    { 
     return Expression.PropertyOrField(expression, property); 
    } 
    else 
    { 
     return Eval(Expression.PropertyOrField(expression, split[0]), property.Replace(split[0] + ".", "")); 
    } 
} 
+0

+1しかし、再帰を使用する場合は毎回文字列を分割する必要はないと思います。 'property.IndexOf( '。')'と 'property.Substring(...) 'を使うことができます。 –

+0

@ p.s.w.g - これは本当に良い方法です。私はちょうど怠け者だった。 – Bobson

関連する問題