Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.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#_Asp.net_.net_Linq_Lambda - Fatal编程技术网

C# 创建动态表达式树

C# 创建动态表达式树,c#,asp.net,.net,linq,lambda,C#,Asp.net,.net,Linq,Lambda,如何将这个Lambda转换为C中的表达式树# 到目前为止我已经试过了 private static Expression GetPropertyExpression(PropertyInfo prop, ParameterExpression paramExpr, ConstantExpression valueExpr) { var memberAcc = Expression.MakeMemberAccess(paramExpr, prop); Console.Write

如何将这个Lambda转换为C中的表达式树#

到目前为止我已经试过了

private static Expression GetPropertyExpression(PropertyInfo prop, ParameterExpression paramExpr, ConstantExpression valueExpr) { 
    var memberAcc = Expression.MakeMemberAccess(paramExpr, prop); 
    Console.WriteLine(memberAcc); 
    var containsMember = typeof(string).GetMethod("Contains"); 
    var toLower= typeof(String).GetMethod("ToLower",new [] {typeof(string)}); 
    var ttt=Expression.Call(memberAcc,containsMember, valueExpr); 
    return Expression.Call(memberAcc,containsMember, valueExpr); 
}

你可以自己稍微简单一点。您可以使用
IndexOf
方法,而不是使用
Contains
方法,该方法不支持作为参数传递的
StringComparison

您可以这样实现它:

public static Expression<Func<T, bool>> ContainsValue<T>(string fieldName, string val) {
    var type = typeof(T);
    var member = Expression.Parameter(type, "param");
    var memberExpression = Expression.PropertyOrField( member, fieldName);
    var targetMethod = memberExpression.Type.GetMethod( "IndexOf", new Type[] { typeof(string), typeof(StringComparison) } );
    var methodCallExpression = Expression.Call( memberExpression, targetMethod, Expression.Constant(val), Expression.Constant( StringComparison.CurrentCultureIgnoreCase ) );

    return Expression.Lambda<Func<T, bool>>( 
        Expression.AndAlso(
            Expression.NotEqual(memberExpression, Expression.Constant(null)), 
            Expression.GreaterThanOrEqual( methodCallExpression, Expression.Constant(0) )
        ), 
        member
    );
}
您可以在上找到一个示例,但我也在下面添加了完整的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public class Program
{
    public static Expression<Func<T, bool>> ContainsValue<T>(string fieldName, string val) {
        var type = typeof(T);
        var member = Expression.Parameter(type, "param");
        var memberExpression = Expression.PropertyOrField( member, fieldName);
        var targetMethod = memberExpression.Type.GetMethod( "IndexOf", new Type[] { typeof(string), typeof(StringComparison) } );
        var methodCallExpression = Expression.Call( memberExpression, targetMethod, Expression.Constant(val), Expression.Constant( StringComparison.CurrentCultureIgnoreCase ) );

        return Expression.Lambda<Func<T, bool>>( 
            Expression.AndAlso(
                Expression.NotEqual(memberExpression, Expression.Constant(null)), 
                Expression.GreaterThanOrEqual( methodCallExpression, Expression.Constant(0) )
            ), 
            member
        );
    }

    public static void Main()
    {
        var items = new List<Test>() {
            new Test() { Parameter = "Alpha" },
            new Test(),
            new Test() { Parameter = "Test" },
            new Test() { Parameter = "test" },
            new Test() { Parameter = "TEST" },
            new Test() { Parameter = "Contains test" }
        };
        var expr = ContainsValue<Test>("Parameter",  "test");
        // you can see the body here
        Console.WriteLine( expr.Body );
        // and the result
        var results = items.Where( expr.Compile() ).Select(t => t.Parameter).ToList();
        Console.WriteLine( "Results: {0}", string.Join( ",", results ));
        Console.WriteLine( "Total results: {0}", results.Count );
    }

    public class Test {
        public string Parameter { get;set; }
    }
}

到目前为止你尝试了什么?你被困在哪里了?我一直在尝试编写此代码来筛选任何列表。它可以在大写的私有静态表达式GetPropertyExpression(PropertyInfo-prop,ParameterExpression-ParameterExpr,ConstantExpression-valueExpr){var memberAcc=Expression.MakeMemberAccess(ParameterExpr,prop);//Console.WriteLine(memberAcc);var containsMember=typeof(string).GetMethod(“Contains”);var toLower=typeof(string).GetMethod(“toLower”,new[]{typeof(string)});var ttt=Expression.Call(memberAcc,containsMember,valuexpr);return Expression.Call(memberAcc,containsMember,valuexpr);}请将代码添加到问题中,而不是在注释中,至少在那里你可以用一种好的方式格式化它(使用你问题下的链接)谢谢Icepickle,我希望它能用于具有常见数据类型的类,如字符串、小数、双精度等。目前,它工作得很好,但在字符串字段上only@EmmanuelOgoma这当然是可能的,因为有许多不同的表达方式。然而,他们没有包含方法,例如,还有很多事情要做。根据您希望在以后如何组合表达式,这可能是相当多的工作;)这个lambda可以工作,但我不知道如何创建它的表达式。注意名为x=>x.FieldName的Tostring方法=null&&x.FieldName.Tostring().ToLower().Contains(param)@EmmanuelOgoma我认为您将其简化了一点,但当然,从您的问题来看,很难了解您的上下文。或者我认为它很复杂:)如果你愿意,我们可以考虑你的要求
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public class Program
{
    public static Expression<Func<T, bool>> ContainsValue<T>(string fieldName, string val) {
        var type = typeof(T);
        var member = Expression.Parameter(type, "param");
        var memberExpression = Expression.PropertyOrField( member, fieldName);
        var targetMethod = memberExpression.Type.GetMethod( "IndexOf", new Type[] { typeof(string), typeof(StringComparison) } );
        var methodCallExpression = Expression.Call( memberExpression, targetMethod, Expression.Constant(val), Expression.Constant( StringComparison.CurrentCultureIgnoreCase ) );

        return Expression.Lambda<Func<T, bool>>( 
            Expression.AndAlso(
                Expression.NotEqual(memberExpression, Expression.Constant(null)), 
                Expression.GreaterThanOrEqual( methodCallExpression, Expression.Constant(0) )
            ), 
            member
        );
    }

    public static void Main()
    {
        var items = new List<Test>() {
            new Test() { Parameter = "Alpha" },
            new Test(),
            new Test() { Parameter = "Test" },
            new Test() { Parameter = "test" },
            new Test() { Parameter = "TEST" },
            new Test() { Parameter = "Contains test" }
        };
        var expr = ContainsValue<Test>("Parameter",  "test");
        // you can see the body here
        Console.WriteLine( expr.Body );
        // and the result
        var results = items.Where( expr.Compile() ).Select(t => t.Parameter).ToList();
        Console.WriteLine( "Results: {0}", string.Join( ",", results ));
        Console.WriteLine( "Total results: {0}", results.Count );
    }

    public class Test {
        public string Parameter { get;set; }
    }
}
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
Results: Test,test,TEST,Contains test
Total results: 4