Utilizzo della sintassi del metodo di estensione LINQ su MatchCollection


92

Ho il codice seguente:

MatchCollection matches = myRegEx.Matches(content);

bool result = (from Match m in matches
               where m.Groups["name"].Value.Length > 128
               select m).Any();

C'è un modo per farlo usando la sintassi del metodo di estensione LINQ?

Qualcosa come questo:

bool result = matches.Any(x => ... );

Risposte:


192
using System.Linq;

matches.Cast<Match>().Any(x => x.Groups["name"].Value.Length > 128)

Devi solo convertirlo da un IEnumerablea un IEnumerable<Match>(IEnumerable <T>) per ottenere l'accesso all'estensione LINQ fornita su IEnumerable <T>.


Chi vota ogni risposta qui? Questa risposta ottiene il mio voto positivo, cognrats.
Kevin Kalitowski

+1 Sto cercando di capire perché questo è stato svalutato. Non lo vedo.
jason

Sono davvero confuso su come sia stato votato perché è corretto
msarchet

1
Funziona, assicurati solo di essere using System.Linqaltrimenti darà un errore di sintassi
Ash Berlin-Taylor

1
Grazie a chiunque sia confuso, Castnon è necessario da C # 8.0, ma il codice non verrà compilato nelle versioni in lingue precedenti se non viene fornito.
rvnlord

46

Quando si specifica un tipo di variabile di intervallo esplicito , il compilatore inserisce una chiamata a Cast<T>. Così questo:

bool result = (from Match m in matches
               where m.Groups["name"].Value.Length > 128
               select m).Any();

è esattamente equivalente a:

bool result = matches.Cast<Match>()
                     .Where(m => m.Groups["name"].Value.Length > 128)
                     .Any();

che può anche essere scritto come:

bool result = matches.Cast<Match>()
                     .Any(m => m.Groups["name"].Value.Length > 128);

In questo caso la Castchiamata è richiesta perché MatchCollectionimplementa solo ICollectione IEnumerable, no IEnumerable<T>. Quasi tutti i metodi di estensione LINQ to Objects sono destinati IEnumerable<T>, con le notevoli eccezioni di Caste OfType, entrambi utilizzati per convertire una raccolta di tipo "debole" (come MatchCollection) in una generica IEnumerable<T>, il che consente quindi ulteriori operazioni LINQ.



8

Prova questo:

var matches = myRegEx.Matches(content).Cast<Match>();

Per riferimento, vedere Enumerable.Cast:

Converte gli elementi di un IEnumerablenel tipo specificato.

Fondamentalmente è un modo per trasformare un IEnumerablein un file IEnumerable<T>.


+1 Sto cercando di capire perché questo è stato svalutato. Non lo vedo.
jason

@ Jason: Molto probabilmente qualcuno stava cercando di aumentare la propria risposta.
Andrew Hare

3

Penso che sarebbe qualcosa del genere:

bool result = matches.Cast<Match>().Any(m => m.Groups["name"].Value.Length > 128);

1
No. Il punto è che MatchCollectionsolo implementa IEnumerable. Non è fortemente tipizzato.
Jason

2

Puoi provare qualcosa di simile:

List<Match> matchList = matches.Cast<Match>().Where(m => m.Groups["name"].Value.Length > 128).ToList();

-1

MODIFICARE:

 public static IEnumerable<T> AsEnumerable<T>(this IEnumerable enumerable)
 {
      foreach(object item in enumerable)
          yield return (T)item;
 }

Quindi dovresti essere in grado di chiamare questo metodo di estensione per trasformarlo in un IEnumerable:

 matches.AsEnumerable<Match>().Any(x => x.Groups["name"].Value.Length > 128);

Questo è meglio del mio, non ricordavo che Any prendesse un predicato.
pstrjds

No. Il punto è che MatchCollectionsolo implementa IEnumerable. Non è fortemente tipizzato.
Jason

@ Jason tranne che è Castable a un IEnumberable <T> tramite IEnumberable.Cast <T>
msarchet

@msarchet: Sì, lo so, motivo per cui ho votato positivamente la tua risposta. Questa risposta, prima della modifica, non sarebbe stata nemmeno compilata.
jason
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.