Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回表达式<&燃气轮机;使用各种类属性_C#_.net_Linq_Lambda - Fatal编程技术网

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);
...