Sie können es selbst machen etwas einfacher. Anstatt die Methode Contains
zu verwenden, die interessanterweise die StringComparison
nicht unterstützt, die als Parameter übergeben werden soll, können Sie die Methode IndexOf
verwenden.
Sie können es wie so implementieren:
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
);
}
Der Trick dabei ist, dass ich die IndexOf
Methode mit einem GreaterThanOrEqual
Anruf mit einem Wert von 0
Das am Ende gibt für einen Test kombinieren Klasse folgender Ausdruck
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
Ein Beispiel, können Sie hier auf den dotnetfiddle finden, aber ich fügte auch den vollständigen Code bel ow
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; }
}
}
Ausgänge:
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
Results: Test,test,TEST,Contains test
Total results: 4
Was haben Sie bisher versuchen? Wo steckst du fest? – Icepickle
Ich habe versucht, diesen Code zu schreiben jede List.it filtern arbeitet aber auf Groß –
private static Expression GetPropertyExpression (Property stütze, Parameterexpression paramExpr, ConstantExpression valueExpr) \t { \t \t var memberAcc = Expression.MakeMemberAccess (paramExpr, Prop); \t \t // Console.WriteLine (memberAcc); \t \t var containsMember = typeof (string) .GetMethod ("Enthält"); \t \t var toLower = typeof (String) .GetMethod ("ToLower", neu [] {typeof (string)}); \t \t var ttt = Expression.Call (memberAcc, containsMember, valueExpr); \t \t Rückgabe Expression.Call (memberAcc, enthältMember, WertExpr); \t} –