Trova il metodo Any su un array di stringhe

c# expression-trees linq

Domanda

Dato

string[] stringArray = { "test1", "test2", "test3" };

allora questo torna vero:

bool doesContain = stringArray.Any(s => "testa test2 testc".Contains(s));

Il mio obiettivo finale è quello di fare di questo un albero di espressione linq. La domanda è: come posso ottenere le informazioni sul metodo di "Any" ? Quanto segue non funziona perché restituisce null.

MethodInfo info = typeof(string[]).GetMethod("Any", BindingFlags.Static | BindingFlags.Public);

Ulteriori spiegazioni:

Sto creando funzionalità di ricerca. Io uso EF e finora utilizzo gli alberi di espressione linq per creare un albero di espressione lambda dinamico. In questo caso ho una matrice di stringhe da cui dovrebbe verificarsi qualsiasi stringa in un campo di descrizione. L'espressione lambda di lavoro che entra nella clausola Where è:

c => stringArray.Any(s => c.Description.Contains(s));

Quindi, per rendere il corpo dell'espressione lambda ho bisogno di una chiamata a "Any" .

Codice finale:

Grazie alla risposta di I4V, la creazione di questa parte dell'albero delle espressioni ora appare come questa (e funziona):

//stringArray.Any(s => c.Description.Contains(s));
if (!String.IsNullOrEmpty(example.Description))
{
    string[] stringArray = example.Description.Split(' '); //split on spaces
    ParameterExpression stringExpression = Expression.Parameter(typeof(string), "s");
    Expression[] argumentArray = new Expression[] { stringExpression };

    Expression containsExpression = Expression.Call(
        Expression.Property(parameterExpression, "Description"),
        typeof(string).GetMethod("Contains"),
        argumentArray);

    Expression lambda = Expression.Lambda(containsExpression, stringExpression);

    Expression descriptionExpression = Expression.Call(
        null,
        typeof(Enumerable)
            .GetMethods()
            .Where(m => m.Name == "Any")
            .First(m => m.GetParameters().Count() == 2)
            .MakeGenericMethod(typeof(string)),
        Expression.Constant(stringArray),
        lambda);}

E poi descriptionExpression va in un albero di espressione lambda più grande.

Risposta accettata

Forse qualcosa del genere?

var mi = typeof(Enumerable)
            .GetMethods()
            .Where(m => m.Name == "Any")
            .First(m => m.GetParameters().Count() == 2)
            .MakeGenericMethod(typeof(string));

E puoi invocarlo come:

var result = mi.Invoke(null, new object[] { new string[] { "a", "b" }, 
                                           (Func<string, bool>)(x => x == "a") });

Risposta popolare

Puoi anche fare

// You cannot assign method group to an implicitly-typed local variable,
// but since you know you want to operate on strings, you can fill that in here:
Func<IEnumerable<string>, Func<string,bool>, bool> mi = Enumerable.Any;

mi.Invoke(new string[] { "a", "b" }, (Func<string,bool>)(x=>x=="a"))

E se stai lavorando con Linq alle Entità, potresti volere il sovraccarico IQueryable:

Func<IQueryable<string>, Expression<Func<string,bool>>, bool> mi = Queryable.Any;

mi.Invoke(new string[] { "a", "b" }.AsQueryable(), (Expression<Func<string,bool>>)(x=>x=="b"));


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché