Verwenden der Syntax der LINQ-Erweiterungsmethode für eine MatchCollection


91

Ich habe folgenden Code:

MatchCollection matches = myRegEx.Matches(content);

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

Gibt es eine Möglichkeit, dies mithilfe der Syntax der LINQ-Erweiterungsmethode zu tun?

Etwas wie das:

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

Antworten:


190
using System.Linq;

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

Sie müssen es nur von einem IEnumerablein einen IEnumerable<Match>(IEnumerable <T>) konvertieren , um Zugriff auf die auf IEnumerable <T> bereitgestellte LINQ-Erweiterung zu erhalten.


Wer stimmt hier nicht über jede Antwort ab? Diese Antwort wird positiv bewertet, Cognrats.
Kevin Kalitowski

+1 Ich versuche herauszufinden, warum dies abgelehnt wurde. Ich sehe es nicht.
Jason

Ich bin wirklich verwirrt darüber, wie dies
abgelehnt wurde,

Viele Antworten wurden abgelehnt. Ich habe eine ähnliche Antwort gegeben, aber eine, von der ich hoffe, dass sie etwas voller ist.
Jon Skeet

1
Dies funktioniert, stellen Sie nur sicher, dass Sie using System.Linqein Syntaxfehler sind
Ash Berlin-Taylor

46

Wenn Sie einen expliziten Bereichsvariablentyp angeben , fügt der Compiler einen Aufruf an ein Cast<T>. Also das:

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

ist genau gleichbedeutend mit:

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

was auch geschrieben werden kann als:

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

In diesem Fall ist der CastAufruf erforderlich, da MatchCollectionnur ICollectionund IEnumerablenicht implementiert wird IEnumerable<T>. Fast alle LINQ to Objects-Erweiterungsmethoden zielen darauf ab IEnumerable<T>, mit den bemerkenswerten Ausnahmen von Castund OfType, die beide verwendet werden, um eine "schwach" typisierte Sammlung (z. B. MatchCollection) in eine generische umzuwandeln IEnumerable<T>- was dann weitere LINQ-Operationen ermöglicht.



7

Versuche dies:

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

Als Referenz siehe Enumerable.Cast:

Konvertiert die Elemente von IEnumerablein den angegebenen Typ.

Im Grunde ist es eine Möglichkeit, aus einem IEnumerableein zu machen IEnumerable<T>.


+1 Ich versuche herauszufinden, warum dies abgelehnt wurde. Ich sehe es nicht.
Jason

@ Jason: Höchstwahrscheinlich hat jemand versucht, seine Antwort zu verbessern.
Andrew Hare

2

Ich denke, es wäre ungefähr so:

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

1
Nein, der springende Punkt ist, dass MatchCollectionnur implementiert IEnumerable. Es ist nicht stark typisiert.
Jason

2

Sie können so etwas ausprobieren:

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

-2

BEARBEITEN:

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

Dann sollten Sie diese Erweiterungsmethode aufrufen können, um sie in eine IEnumerable umzuwandeln:

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

Das ist besser als meins, ich habe mich nicht daran erinnert, dass Any ein Prädikat genommen hat.
pstrjds

Nein, der springende Punkt ist, dass MatchCollectionnur implementiert IEnumerable. Es ist nicht stark typisiert.
Jason

@ Jason mit der Ausnahme, dass es über IEnumberable in eine IEnumberable <T> umgewandelt werden kann. Cast <T>
msarchet

@msarchet: Ja, ich weiß, deshalb habe ich deine Antwort positiv bewertet. Diese Antwort hätte vor der Bearbeitung nicht einmal kompiliert.
Jason
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.