C# 泛型对象上的动态LINQ(没有任何硬编码属性)

C# 泛型对象上的动态LINQ(没有任何硬编码属性),c#,linq,generics,dynamic-linq,C#,Linq,Generics,Dynamic Linq,我有一个通用对象,它使用字典存储属性: class MyObject { Dictionary<string, object> Properties = new Dictionary<string, object>(); internal GetValue(string name) { return Properties[name]; } internal SetValue(string name, object value) { Propert

我有一个通用对象,它使用字典存储属性:

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);
类MyObject
{
字典属性=新字典();
内部GetValue(字符串名称){返回属性[名称];}
内部SetValue(字符串名称,对象值){Properties[name]=value;}
}
MyObject obj1=新的MyObject();
obj1.SetValue(“名称”、“约翰”);
obj1.设定值(“年龄”,23岁);
MyObject obj2=新的MyObject();
obj2.SetValue(“名称”、“玛丽”);
obj2.设定值(“年龄”,24岁);
列表对象列表=新列表();
ObjList.Add(obj1);
ObjList.Add(obj2);
现在我们需要查询ObjList来查找某些条目。dynamiclinq()似乎很完美,但从我所看到的情况来看,它要求对象具有预定义的属性

我们希望执行以下查询:

ObjList.Where("Name == 'Mary' || Age < 24");
ObjList.Where(“Name==“Mary”|年龄<24岁”);
任何标记(如姓名、年龄)都应调用“GetValue”。有什么建议吗


显然,where语句完全由用户决定,并且不是固定的。

动态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");
ObjList.Where(“GetValue('Name')='Mary'| | GetValue('Age')<24”);
而且,如果解析器当前不允许这样做,您可以很容易地扩展它,使其允许这样做。

在C#4.0中,您可以让您的
MyObject
实现
idynamicmetadatadataprovider
接口,以便分别将属性标记解析为GetValue()和SetValue()。动态LINQ应该按照预期工作


请参见示例

哇,谢谢您的提示。实际上,看起来我可能会使用ExpandooObject来代替!