J'utilise le code ci-dessous pour exécuter les méthodes. Il fonctionne pour les méthodes standard de string
Par exemple StartsWith
Cependant, j'essaie d'utiliser plusieurs méthodes d'extension de chaînes de caractères, y compris une surcharge pour la méthode Contains
ce qui permet de ne pas tenir compte des majuscules et des minuscules :
var method = "Contains";
var args = new object[] { "@", StringComparison.OrdinalIgnoreCase };
// This works when called
var mi = m.Type.GetMethod(method, args.Select(a => a.GetType()).ToArray());
if (mi == null) {
// This does find the method, but causes an error on Expression.Call below
mi = typeof(Extensions).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(meth => meth.Name == method);
}
var c = args.Select(a => Expression.Constant(a, a.GetType()));
return Expression.Lambda<Func<T, bool>>(Expression.Call(m, mi, c), e);
L'erreur que je reçois est la suivante :
Une méthode statique nécessite une instance nulle, une méthode non statique nécessite une instance non nulle.
Comment résoudre ce problème ?
Pour référence, voici le Contains
extension :
public static bool Contains(this string source, string toCheck, StringComparison comp) {
return source.IndexOf(toCheck, comp) >= 0;
}
Gracias
EDIT
Mise à jour selon la réponse de Balazs, bien que j'obtienne maintenant l'erreur suivante :
L'expression de type 'System.Linq.Expressions.PropertyExpression' ne peut pas être utilisée pour le paramètre de type 'System.String' de la méthode 'Boolean Contains(System.String, System.String, System.StringComparison)'
Voici la méthode complète pour référence :
public static Expression<Func<T, bool>> Build(string member, IEnumerable<object> memberArgs, string method, params object[] args) {
var e = Expression.Parameter(_type, "e");
var memberInfo =
(MemberInfo) _type.GetField(member) ??
(MemberInfo) _type.GetProperty(member) ??
(MemberInfo) _type.GetMethod(member, (memberArgs ?? Enumerable.Empty<object>()).Select(p => p.GetType()).ToArray());
Expression m;
if (memberInfo.MemberType == MemberTypes.Method) {
var a = memberArgs.Select(p => Expression.Constant(p));
m = Expression.Call(e, (MethodInfo) memberInfo, a);
}
else {
m = Expression.MakeMemberAccess(e, memberInfo);
}
var mi = m.Type.GetMethod(method, args.Select(a => a.GetType()).ToArray());
var c = args.Select(a => Expression.Constant(a, a.GetType()));
MethodCallExpression call;
if (mi != null) {
call = Expression.Call(m, mi, c);
}
else {
mi = typeof(Extensions).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(meth => meth.Name == method);
var newArgsList = c.ToList<object>();
newArgsList.Insert(0, m);
c = newArgsList.Select(a => Expression.Constant(a, a.GetType()));
call = Expression.Call(null, mi, c);
}
return Expression.Lambda<Func<T, bool>>(call, e);
}