Bir MatchCollection üzerinde LINQ uzantısı yöntemi sözdizimini kullanma


92

Takip koduna sahibim:

MatchCollection matches = myRegEx.Matches(content);

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

LINQ uzantı yöntemi sözdizimini kullanarak bunu yapmanın bir yolu var mı?

Bunun gibi bir şey:

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

Yanıtlar:


196
using System.Linq;

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

IEnumerable <T> üzerinde sağlanan LINQ uzantısına erişmek için onu IEnumerablebir IEnumerable<Match>(IEnumerable <T>) ' ye dönüştürmeniz yeterlidir .


Buradaki her cevaba kim oy veriyor? Bu cevap benim olumlu oyumu alıyor, bilginler.
Kevin Kalitowski

+1 Bunun neden olumsuz oy verildiğini anlamaya çalışıyorum. Ben görmüyorum.
jason

Bunun doğru olduğu için nasıl oy verildiği konusunda gerçekten kafam karıştı
msarchet

1
Bu işe yarıyor, sadece using System.Linqbaşka olduğunuzdan emin olun, bir sözdizimi hatası verir
Ash Berlin-Taylor

1
Kafası karışan herkese teşekkür ederiz, CastC # 8.0'dan beri gerekli değildir, ancak kod sağlanmazsa önceki dil sürümlerinde derlenmez.
rvnlord

46

Açık bir aralık değişken türü belirttiğinizde , derleyici için bir çağrı ekler Cast<T>. Yani bu:

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

tam olarak eşdeğerdir:

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

şu şekilde de yazılabilir:

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

Bu durumda Castçağrı gereklidir çünkü MatchCollectionsadece uygular ICollectionve IEnumerabledeğil IEnumerable<T>. Hemen hemen tüm LINQ to Objects genişletme yöntemleri IEnumerable<T>, dikkate değer istisnalar Castve OfTypeher ikisi de "zayıf" tiplenmiş bir koleksiyonu (örneğin MatchCollection) jenerik haline dönüştürmek için kullanılır IEnumerable<T>- bu da daha sonra LINQ işlemlerine izin verir.



8

Bunu dene:

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

Referans için lütfen bakınız Enumerable.Cast:

An öğesinin öğelerini IEnumerablebelirtilen türe dönüştürür.

Temelde bu, bir'yi IEnumerablebir IEnumerable<T>.


+1 Bunun neden olumsuz oy verildiğini anlamaya çalışıyorum. Ben görmüyorum.
jason

@Jason: Büyük ihtimalle birisi cevabını artırmaya çalışıyordu.
Andrew Hare

3

Bunun gibi bir şey olacağını düşünüyorum:

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

1
Hayır. Bütün mesele şu ki, MatchCollectionsadece uygular IEnumerable. Kesinlikle yazılmış değil.
jason

2

Bunun gibi bir şey deneyebilirsiniz:

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

-1

DÜZENLE:

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

Ardından, bu uzantı yöntemini bir IEnumerable'a dönüştürmek için çağırabilmelisiniz:

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

Bu benimkinden daha iyi, Herhangi birinin bir yüklem aldığını hatırlamıyordum.
pstrjds

Hayır. Bütün mesele şu ki, MatchCollectionsadece uygular IEnumerable. Kesinlikle yazılmış değil.
jason

@Jason, IEnumberable.Cast <T> aracılığıyla bir IEnumberable <T> 'ye dönüştürülebilir olması dışında
msarchet

@msarchet: Evet, biliyorum, bu yüzden cevabınıza olumlu oy verdim. Bu cevap, düzenlemeden önce derlenmiş bile olmazdı.
jason
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.