您可以使用接口来创建一个针对已定义必要属性的接口的 Func。
例如:
interface IExpressionable {
string Language { get;set; }
string Name { get;set; }
}
class Genre : IExpressionable {
string Language {get;set;}
string Name {get;set;}
}
Genre genre = new Genre();
Expression<Func<IExpressionable, bool>> expression = CreateExpression(genre, lang, name);
expression = (g => g.Language == "en" && g.Name == "comedy")
这个概念的另一种实现方式是在你的接口上提供一个 GetLanguage 和 GetName 方法,这将强制订阅者实现基础方法以便根据他们自己的内部方法返回“语言”和“名称”。
interface IExpressionable {
string GetExpressionOne();
string GetExpressionTwo();
}
class Genre : IExpressionable {
string Language {get;set;}
string Name {get;set;}
public string GetExpressionOne() {
return Language;
}
public string GetExpressionOne() {
return Name;
}
}
class SomethingElse {
string Orange {get;set;}
string BananaPeel {get;set;}
public string GetExpressionOne() {
return Orange;
}
public string GetExpressionOne() {
return BananaPeel;
}
}
Genre genre = new Genre();
SomethingElse else = new SomethingElse();
Expression<Func<IExpressionable, bool>> expression = CreateExpression(genre, lang, name);
Expression<Func<IExpressionable, bool>> expression2 = CreateExpression(else, lang, name);
expression = (g => g.GetExpressionOne() == "en" && g.GetExpressionTwo() == "comedy");
从您上面的评论中编辑:@kaveman 我只有关键值,但是我可以通过使用一些自定义属性来反射获取关键属性。在这个例子中,Language和Name将被装饰为一个定义它们为关键属性的属性。
我的答案是完全避免这种想法。创建一个接口,定义你需要执行任何表达式所需的方法,并让实体继承它。你可以在接口上定义你的方法为“GetKeyOne”和“GetKeyTwo”。然后你的表达式就不必是动态的,你只需要定义当它与KeyOne和KeyTwo交互时表达式的行为,这在每个实现者中都有定义。