2010-02-17 23 views
7

Son zamanlarda kendime LINQ öğretiyorum ve bunu çeşitli küçük bulmacalara uygulıyorum. Ancak, içine girdiğim sorunlardan biri, LINQ nesnelerinin yalnızca genel koleksiyonlarda çalıştığıdır. Jenerik olmayan bir koleksiyonu jenerik bir koleksiyona dönüştürmek için gizli bir hile/en iyi uygulama var mı?Genel olmayan koleksiyonları genel bir koleksiyona dönüştürmenin en iyi yolu nedir?

Geçerli uygulamam, jenerik olmayan koleksiyonu bir diziye kopyalar ve sonra bunun üzerinde çalışır, ancak daha iyi bir yol olup olmadığını merak ediyordum?

public static int maxSequence(string str) 
{ 
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    Match[] matchArr = new Match[matches.Count]; 
    matches.CopyTo(matchArr, 0); 
    return matchArr 
     .Select(match => match.Value.Length) 
     .OrderByDescending(len => len) 
     .First(); 
} 

cevap

10

basit yolu genellikle Cast uzatma yöntemidir: Bu ertelenmiş ve verilerinin akışları olduğunu

IEnumerable<Match> strongMatches = matches.Cast<Match>(); 

Not, bu nedenle gibi bir dolu "koleksiyonu" yok - Fakat LINQ sorguları için mükemmel bir veri kaynağı.

Yani tamamen Sorgunuzla dönüştürmek için: Eğer bir sorgu ifadesinde menzil değişkeni için türünü belirtirseniz

Cast otomatik olarak çağrılır

public static int MaxSequence(string str) 
{  
    return (from Match match in Regex.Matches(str, "H+|T+") 
      select match.Value.Length into matchLength 
      orderby matchLength descending 
      select matchLength).First(); 
} 

veya

Aslında
public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Select(match => match.Value.Length) 
        .OrderByDescending(len => len) 
        .First(); 
} 

OrderByDescending ve sonra First'u aramanıza gerek yoktur - sadece maksimum değeri istediğiniz gibi Max yöntemi sizi alır. Daha da iyisi, bu size bulmaya çalışıyorsanız değere kaynak elemanı türünden bir projeksiyon belirtmek o yüzden çok Select olmadan yapabilirsiniz sağlar:

public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Max(match => match.Value.Length); 
} 

Eğer bazı olan bir koleksiyon varsa Doğru türden elemanlar, ancak bazıları olmayabilir, bunun yerine OfType kullanabilirsiniz. Cast, "yanlış" türden bir öğe ile karşılaştığında bir istisna atar; OfType sadece onu atlar.

+0

Çok teşekkürler! Belgedeki bu yöntemi nasıl özlediğimi bilmiyorum, ama tam da aradığım şey bu! Ayrıca Max() kullanımındaki ipucu için teşekkürler – guhou

0
matches.Cast<Match>(); 
1

Dönüştürmek için IEnumerable numaralı telefondan Cast veya OfType'u kullanabilirsiniz. OfType öğesi dönüştürülemeyecek öğeleri atlayacaksa, Cast öğesi belirtilen türde yayınlanamazsa yasa dışı döküm atacaktır.

İlgili konular