0

辞書を使用してプロパティを格納する汎用オブジェクトがあります。

class MyObject 
{
    Dictionary<string, object> Properties = new Dictionary<string, object>();
    internal GetValue(string name) { return Properties[name]; }
    internal SetValue(string name, object value) { Properties[name] = value; } 
}
MyObject obj1 = New MyObject();
obj1.SetValue("Name", "John");
obj1.SetValue("Age", 23);

MyObject obj2 = New MyObject();
obj2.SetValue("Name", "Mary");
obj2.SetValue("Age", 24);

List<MyObject> ObjList = new List<MyObject>();
ObjList.Add(obj1);
ObjList.Add(obj2);

次に、特定のエントリを見つけるためにObjListをクエリする必要があります。動的LINQ(動的LINQ(パート1:LINQ動的クエリライブラリの使用))は完璧に見えますが、私が見る限り、オブジェクトには事前定義されたプロパティが必要です。

次のようなクエリを実行します。

ObjList.Where("Name == 'Mary' || Age < 24");

すべてのトークン(名前、年齢など)は「GetValue」を呼び出す必要があります。助言がありますか?

明らかに、whereステートメントは完全にユーザー次第であり、修正されていません。

4

2 に答える 2

1

動的LINQ拡張メソッドのソースWhere句は次のとおりです。

public static IQueryable Where(this IQueryable source, string predicate, params object[] values) {
    if (source == null) throw new ArgumentNullException("source");
    if (predicate == null) throw new ArgumentNullException("predicate");
    LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable), "Where",
            new Type[] { source.ElementType },
            source.Expression, Expression.Quote(lambda)));
}

複雑な部分はDynamicExpression.ParseLambdaビットです。ソースをざっと見てみると、解析コードに「ParseMemberAccess」関数が含まれていることがわかります。これは、次のようなことができる可能性があることを示唆しているようです。

ObjList.Where("GetValue('Name') == 'Mary' || GetValue('Age') < 24");

また、パーサーが現在それを許可していない場合は、許可するように簡単に拡張できます。

于 2010-11-28T21:41:36.843 に答える
1

C#4.0では、プロパティトークンがそれぞれGetValue()とSetValue()に解決されるように、インターフェイスをMyObject実装することができます。IDynamicMetaDataProviderこれで、動的LINQは期待どおりに機能するはずです。

例については、この投稿を参照してください

于 2010-11-29T02:30:11.007 に答える