C# 返回表达式<&燃气轮机;使用各种类属性
我有这样的想法:C# 返回表达式<&燃气轮机;使用各种类属性,c#,.net,linq,lambda,C#,.net,Linq,Lambda,我有这样的想法: public Expression<Func<Message, bool>> FilterData() { switch (this.operatorEnum) { case FilterParameterOperatorEnum.EqualTo: return message => !string.IsNullOrEmpty(message.Body) &&
public Expression<Func<Message, bool>> FilterData()
{
switch (this.operatorEnum)
{
case FilterParameterOperatorEnum.EqualTo:
return message => !string.IsNullOrEmpty(message.Body) &&
message.Body
.Equals(this.value, StringComparison.InvariantCultureIgnoreCase);
case FilterParameterOperatorEnum.NotEqualTo:
return message => !string.IsNullOrEmpty(message.Body) &&
!message.Body
.Equals(this.value, StringComparison.InvariantCultureIgnoreCase);
case FilterParameterOperatorEnum.Contains:
return message =>
!string.IsNullOrEmpty(message.Body) &&
message.Body.IndexOf(this.value,
StringComparison.InvariantCultureIgnoreCase) >= 0;
case FilterParameterOperatorEnum.DoesNotContain:
return message =>
!string.IsNullOrEmpty(message.Body) &&
message.Body.IndexOf(this.value,
StringComparison.InvariantCultureIgnoreCase) == -1;
}
}
公共表达式过滤器数据()
{
开关(this.operatorEnum)
{
案例过滤器参数OperatorEnum.EqualTo:
返回消息=>!string.IsNullOrEmpty(message.Body)&&
消息,正文
.Equals(this.value,StringComparison.InvariantCultureIgnoreCase);
案例过滤器参数OperatorEnum.NotEqualTo:
返回消息=>!string.IsNullOrEmpty(message.Body)&&
!message.Body
.Equals(this.value,StringComparison.InvariantCultureIgnoreCase);
案例过滤器ParameterOperatorEnum.包含:
返回消息=>
!string.IsNullOrEmpty(message.Body)&&
message.Body.IndexOf(this.value,
StringComparison.InvariantCultureInogoreCase)>=0;
案例过滤器参数OperatorEnum.DoetContain:
返回消息=>
!string.IsNullOrEmpty(message.Body)&&
message.Body.IndexOf(this.value,
StringComparison.InvariantCultureInogoreCase)=-1;
}
}
正如您所看到的,这是在Message.Body
现在,我想在Message
类的其他字符串属性上做同样的事情,我不想重复所有的代码
有没有办法通过某种方式传递属性来实现这一点?只需更改函数以接收属性而不是消息 或者,很难再为属性名传递一个参数,然后使用反射选择它 仅编辑一个选项,而不是更改所有选项
public Func<Message, string, bool> FilterData()
{
return (message, propName) =>
{
var prop = message.GetType().GetProperty(propName);
if(prop != null){
var propValue = (string)prop.GetValue(message,null);
return !string.IsNullOrEmpty(propValue) && ...;
}
return false;
};
}
public Func FilterData()
{
返回(消息、propName)=>
{
var prop=message.GetType().GetProperty(propName);
如果(prop!=null){
var propValue=(字符串)prop.GetValue(消息,null);
return!string.IsNullOrEmpty(propValue)&&&。。。;
}
返回false;
};
}
将检索属性值的表达式合并到单独的lambda表达式中:
public Expression<Func<Message, bool>> FilterData(Func<Message, string> retrievePropValueFunc)
要访问
Body
属性,请将message=>message.Body
传递给retrievePropValueFunc
参数;如您所见,您也可以修改它以传递不同的lambda表达式来检索其他属性。您可以尝试完全手动组合表达式,这将使您能够将属性名称指定为字符串。这不是一个完整的解决方案,也未经测试,但它可能会让您了解我的意思:
var parameter = Expression.Parameter(typeof(Message), "o");
var getname = Expression.Property(parameter, "Body");
var isnullorempty = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, getname));
var compare = Expression.Equal(getname, Expression.Constant("thisvalue"));
var combined = Expression.And(isnullorempty, compare);
var lambda = Expression.Lambda(combined, parameter);
因此,您可以将函数更改为接受“Body”作为参数,然后在末尾将lambda强制转换为:
expression<func<Message, bool>>
表达式
但是,我可能没有完全正确地创建lambda的语法。一种非常快速而肮脏的方法可能是
枚举
加上某种魔法:
public enum FilterTarget { Body, AnyOtherProp };
public Expression<Func<Message, bool>> FilterData(FilterTarget filterTarget)
{
string toBeFiltered = string.Empty;
switch(filterTarget)
{
case FilterTarget.Body :
{ toBeFiltered = message.Body; } break;
case FilterTarget.AnyOtherProp :
{ toBeFiltered = message.AnyOtherProp; } break;
default:
{
throw new ArgumentException(
string.Format("Unsupported property {0}", filterTarget.ToString()
);
}
}
switch (this.operatorEnum)
{
case FilterParameterOperatorEnum.EqualTo:
return message => !string.IsNullOrEmpty(toBeFiltered) &&
toBeFiltered.Equals(this.value, StringComparison.InvariantCultureIgnoreCase);
/* CUT: other cases are similar */
}
}
FilterData的主体是什么样子的?要正确执行此操作,在检查
prop
是否为null
之后,还应确保prop.CanRead
为true
。retrievePropValueFunc
是否也需要是表达式
“LINQ to实体中不支持LINQ表达式节点类型'Invoke'。“@SteveGreatrex如果它是一个expression@Jon我认为错误消息是因为它使用函数而不是表达式。我不确定,但是您可以使用上面的代码retrievePropValueFunc(message)
调用表达式,就像调用函数一样,它不会编译
public enum FilterTarget { Body, AnyOtherProp };
public Expression<Func<Message, bool>> FilterData(FilterTarget filterTarget)
{
string toBeFiltered = string.Empty;
switch(filterTarget)
{
case FilterTarget.Body :
{ toBeFiltered = message.Body; } break;
case FilterTarget.AnyOtherProp :
{ toBeFiltered = message.AnyOtherProp; } break;
default:
{
throw new ArgumentException(
string.Format("Unsupported property {0}", filterTarget.ToString()
);
}
}
switch (this.operatorEnum)
{
case FilterParameterOperatorEnum.EqualTo:
return message => !string.IsNullOrEmpty(toBeFiltered) &&
toBeFiltered.Equals(this.value, StringComparison.InvariantCultureIgnoreCase);
/* CUT: other cases are similar */
}
}
var aFilterDataResult = FilterData(FilterTarget.Body);
var anotherFilterDataResult = FilterData(FilterTarget.AnyOtherProp);
...