Yanıtlar:
LINQ kullanabiliyorsanız şunları kullanabilirsiniz:
var e = enumerable.First();
Numaralandırılabilir boşsa bu bir istisna atar: bu durumda şunları kullanabilirsiniz:
var e = enumerable.FirstOrDefault();
FirstOrDefault()döner default(T)numaralandırılabilir boşsa olacak, nullbaşvuru türleri ya da değer türleri için varsayılan 'sıfır değeri' için.
LINQ kullanamıyorsanız, yaklaşımınız teknik olarak doğrudur ve ilk sonucu almak için GetEnumeratorve MoveNextyöntemlerini kullanarak bir numaralandırıcı oluşturmaktan farklı değildir (bu örnek numaralandırılabilir bir değerdir IEnumerable<Elem>):
Elem e = myDefault;
using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
if (enumer.MoveNext()) e = enumer.Current;
}
Joel Coehoorn söz .Single()yorumlarda; numaralandırılacak öğenizin tam olarak bir öğe içermesini bekliyorsanız bu da işe yarayacaktır - ancak boş veya bir öğeden daha büyükse bir istisna atar. SingleOrDefault()Bu senaryoyu benzer şekilde kapsayan karşılık gelen bir yöntem vardır FirstOrDefault(). Ancak, David B şöyle açıklıyor:SingleOrDefault() , sayılabilirin birden fazla öğe içerdiği durumlarda hala bir istisna .
Düzenleme: Marc Gravell , IEnumeratorkullandıktan sonra nesnemi atmam gerektiğini işaret ettiğin için teşekkürler - usingBu kalıbı uygulamak için anahtar kelimeyi görüntülemek için LINQ olmayan örneği düzenledim .
.NET 2.0 kullanıyorsanız ve LINQ'ya erişiminiz yoksa:
static T First<T>(IEnumerable<T> items)
{
using(IEnumerator<T> iter = items.GetEnumerator())
{
iter.MoveNext();
return iter.Current;
}
}
Bu, aradığınızı yapmalıdır ... jenerik ilaç kullanır, böylece her tür IEnumerable'da ilk öğeyi alırsınız.
Öyle söyle:
List<string> items = new List<string>() { "A", "B", "C", "D", "E" };
string firstItem = First<string>(items);
Veya
int[] items = new int[] { 1, 2, 3, 4, 5 };
int firstItem = First<int>(items);
.NET 3.5'in IEnumerable.ElementAt () uzantısı yöntemini taklit edecek kadar kolayca değiştirebilirsiniz:
static T ElementAt<T>(IEnumerable<T> items, int index)
{
using(IEnumerator<T> iter = items.GetEnumerator())
{
for (int i = 0; i <= index; i++, iter.MoveNext()) ;
return iter.Current;
}
}
Böyle çağırmak:
int[] items = { 1, 2, 3, 4, 5 };
int elemIdx = 3;
int item = ElementAt<int>(items, elemIdx);
Eğer Tabii do LINQ erişebilir, sonra iyi cevaplar bol zaten yayınlanmıştır var ...
Hangi .Net sürümünü kullandığınızı belirtmediniz.
3.5'e sahip olduğunuzu varsayarsak, başka bir yol ElementAt yöntemidir:
var e = enumerable.ElementAt(0);
Elem e = enumerable.FirstOrDefault();
//do something with e
Daha önce de belirtildiği gibi FirstOrDefault veya bir foreach döngüsü kullanın. Bir numaralandırıcıyı manuel olarak getirmek ve Akım'ı çağırmaktan kaçınılmalıdır. foreach, IDisposable uygularsa, numaralandırıcıyı sizin için atacaktır. MoveNext ve Current çağrılarını manuel olarak atmanız gerekir (eğer uygulanabilirse).
IEnumerable'ınız bunu göstermezse <T>ve Linq başarısız olursa, yansıma kullanarak bir yöntem yazabilirsiniz:
public static T GetEnumeratedItem<T>(Object items, int index) where T : class
{
T item = null;
if (items != null)
{
System.Reflection.MethodInfo mi = items.GetType()
.GetMethod("GetEnumerator");
if (mi != null)
{
object o = mi.Invoke(items, null);
if (o != null)
{
System.Reflection.MethodInfo mn = o.GetType()
.GetMethod("MoveNext");
if (mn != null)
{
object next = mn.Invoke(o, null);
while (next != null && next.ToString() == "True")
{
if (index < 1)
{
System.Reflection.PropertyInfo pi = o
.GetType().GetProperty("Current");
if (pi != null) item = pi
.GetValue(o, null) as T;
break;
}
index--;
}
}
}
}
}
return item;
}
ayrıca size ith öğesini veren daha genel sürümü de deneyebilirsiniz
enumerable.ElementAtOrDefault (i));
Umarım yardımcı olur