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.