Linq'de Cast () ve Oftype () ne zaman kullanılır?


211

Linq'te IEnumerablebir tür döküm türünün farkındayım Arraylistve hangi durumlarda bunları kullanacağımı merak ediyorum?

Örneğin

IEnumerable<string> someCollection = arrayList.OfType<string>()

veya

IEnumerable<string> someCollection = arrayList.Cast<string>()

Bu iki yöntem arasındaki fark nedir ve her bir vakayı nereye uygulamalıyım?

Yanıtlar:


322

OfType- yalnızca x türüne güvenli bir şekilde atılabilecek öğeleri döndürün.
Cast- tüm öğeleri x türüne dökmeye çalışacaktır. eğer bazıları bu tipten değilseInvalidCastException


Örneğin DÜZENLE :

object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }

1
bunun için şerefe. Her ikisini de önceden denedim, ancak her ikisinin de beklenen tipte unsurları vardı, bu yüzden neden farkı göremedim.

6
@SLaks Cast<T>, koleksiyonun yalnızca tür Töğeler içerdiğinden emin olduğunuzda kullanmanız gerektiğini doğru bir şekilde belirtir . tip kontrolü OfType<T>nedeniyle daha yavaştır is. Toplama türdeyse IEnumerable<T>, Cast<T>basitçe bütün koleksiyonunu kullanacaklar IEnumerable<T>ve önlemek onu numaralandırılırken; OfType<T>hala numaralandırılacak. ref: stackoverflow.com/questions/11430570/…
hIpPy

23
Hatta durumlarda .Cast<string>()bu sayılan zaman atmaz, o değil eşdeğerdir .OfType<string>(). Bunun nedeni, nulldeğerlerin her zaman atlanmasıdır .OfType<TResult>(). Bir örnek: new System.Collections.ArrayList { "abc", "def", null, "ghi", }.OfType<string>().Count()sadece verecek 3; ile benzer ifade ile .Cast<string>()değerlendirilir 4.
Jeppe Stig Nielsen

1
başka bir deyişle, 'as' ve 'cast' operatörleri arasındaki fark gibi bir şey
faza

111

http://solutionizing.net/2009/01/18/linq-tip-enumerable-oftype/

Temel olarak, Cast () şu şekilde uygulanır:

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}

Açık bir döküm kullanmak iyi performans gösterir, ancak döküm başarısız olursa InvalidCastException ile sonuçlanır. Bu fikir üzerinde daha az etkili ama kullanışlı bir varyasyon OfType ():

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T)
      yield return (T) o;
}

Döndürülen numaralandırma yalnızca belirtilen türe güvenli bir şekilde dökülebilen öğeler içerecektir.


38

Cast<string>()Tüm öğelerin strings olduğunu biliyorsanız aramalısınız .
Bazıları dize değilse, bir istisna alırsınız.

OfType<string>()Bazı öğelerin olmadığını stringve bu öğeleri istemediğinizi biliyorsanız aramalısınız .
Bazıları dize değilse, yeni dizede olmazlar IEnumerable<string>.


1
Bu cevap (şu anda) hangi yöntemi kullanacağına ilişkin açık bir tavsiye veren tek cevaptır.
CodeFox

4

Diğer LINQ işlevlerinden farklı Cast(Of T)olarak kullanılabileceğine dikkat edilmelidir IEnumerable, bu nedenle genel olmayan bir koleksiyonda veya gibi bir listede LINQ kullanmanız gereken bir durum ArrayListvarsa, LINQ'nun çalışabileceği Cast(Of T)bir IEnumerable(Of T)yere yayın yapmak için kullanabilirsiniz.


2

Cast()koleksiyonun tüm öğelerini yayınlamaya çalışır (ve öğe yanlış türdeyse bir istisna atar) ve OfType()yalnızca uygun türdeki öğeleri döndürür.


2

OfTypeyalnızca belirtilen türde öğeleri döndürmek için öğelere filtre uygular. Castbir öğe hedef türüne yayınlanamazsa kilitlenir.


2

Cast<T>tüm öğeleri verilen türe yayınlamaya çalışacaktır T. Bu oyuncu başarısız olabilir veya bir istisna atabilir. OfType<T>orijinal koleksiyonun bir alt kümesini döndürür ve yalnızca türdeki nesneleri döndürür T.

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.