जवाबों:
यदि आप LINQ का उपयोग कर सकते हैं तो आप उपयोग कर सकते हैं:
var e = enumerable.First();
यह एक अपवाद फेंक देगा, हालांकि अगर गणना योग्य खाली है: जिस स्थिति में आप उपयोग कर सकते हैं:
var e = enumerable.FirstOrDefault();
FirstOrDefault()default(T)अगर वापसी योग्य है, जो nullसंदर्भ प्रकारों के लिए या डिफ़ॉल्ट प्रकारों के लिए डिफ़ॉल्ट 'शून्य-मान' के लिए होगी।
यदि आप LINQ का उपयोग नहीं कर सकते हैं, तो आपका दृष्टिकोण तकनीकी रूप से सही है और पहला परिणाम प्राप्त करने के तरीकों GetEnumeratorऔर MoveNextविधियों का उपयोग करके एक एन्यूमरेटर बनाने से अलग नहीं है (यह उदाहरण मान लेता है कि ए IEnumerable<Elem>) उपयुक्त है:
Elem e = myDefault;
using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
if (enumer.MoveNext()) e = enumer.Current;
}
जोएल कोएहॉर्न ने .Single()टिप्पणियों में उल्लेख किया है; यह भी काम करेगा, यदि आप अपने गणना करने योग्य से एक तत्व को शामिल करने की उम्मीद कर रहे हैं - हालांकि यह एक अपवाद को फेंक देगा यदि यह एक तत्व से या तो खाली है या बड़ा है। एक समान SingleOrDefault()विधि है जो इस परिदृश्य को इसी तरह से कवर करती है FirstOrDefault()। हालांकि, डेविड बी बताते हैं कि SingleOrDefault()अभी भी उस मामले में एक अपवाद को फेंक सकते हैं जहां गणना करने योग्य में एक से अधिक आइटम होते हैं।
संपादित करें: मार्क ग्रेवेल को यह इंगित करने के लिए कि मुझे IEnumeratorइसका उपयोग करने के बाद अपनी वस्तु का निपटान करने की आवश्यकता है - मैंने usingइस पैटर्न को लागू करने के लिए कीवर्ड प्रदर्शित करने के लिए गैर-LINQ उदाहरण संपादित किया है ।
बस मामले में आप .NET 2.0 का उपयोग कर रहे हैं और LINQ तक पहुंच नहीं है:
static T First<T>(IEnumerable<T> items)
{
using(IEnumerator<T> iter = items.GetEnumerator())
{
iter.MoveNext();
return iter.Current;
}
}
यह वही करना चाहिए जो आप खोज रहे हैं ... यह जेनेरिक का उपयोग करता है ताकि आप किसी भी प्रकार IEnumerable पर पहला आइटम प्राप्त कर सकें।
इसे ऐसे कॉल करें:
List<string> items = new List<string>() { "A", "B", "C", "D", "E" };
string firstItem = First<string>(items);
या
int[] items = new int[] { 1, 2, 3, 4, 5 };
int firstItem = First<int>(items);
आप इसे आसानी से संशोधित कर सकते हैं। .NET 3.5 का IEnumerable.ElementAt () एक्सटेंशन विधि की नकल करने के लिए पर्याप्त है:
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;
}
}
इसे इस तरह से कॉल करना:
int[] items = { 1, 2, 3, 4, 5 };
int elemIdx = 3;
int item = ElementAt<int>(items, elemIdx);
बेशक, यदि आपके पास LINQ तक पहुंच है, तो पहले से ही बहुत सारे अच्छे उत्तर हैं ...
खैर, आपने यह निर्दिष्ट नहीं किया कि आप किस .Net के किस संस्करण का उपयोग कर रहे हैं।
मान लें कि आपके पास 3.5 है, तो एक और तरीका एलीमेंट विधि है:
var e = enumerable.ElementAt(0);
Elem e = enumerable.FirstOrDefault();
//do something with e
पहले से बताए गए अनुसार FirstOrDefault या एक foreach पाश का उपयोग करें। एक एन्यूमरेटर को मैन्युअल रूप से लाने और करंट से बचने से बचना चाहिए। यदि यह IDis प्रयोज्य लागू करता है, तो foreach आपके लिए आपके एन्यूमरेटर को निष्क्रिय कर देगा। MoveNext और Current को कॉल करते समय आपको इसे मैन्युअल रूप से डिस्पोज़ करना होगा (यदि aplicable)।
यदि आपका IEnumerable इसे उजागर नहीं करता है <T>और Linq विफल रहता है, तो आप प्रतिबिंब का उपयोग करके एक विधि लिख सकते हैं:
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;
}
आप अधिक सामान्य संस्करण भी आज़मा सकते हैं जो आपको ith तत्व देता है
enumerable.ElementAtOrDefault (i));
आशा करता हूँ की ये काम करेगा