यह करना चाहिए:
public static bool ContainsExactlyOneItem<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
// Check we've got at least one item
if (!iterator.MoveNext())
{
return false;
}
// Check we've got no more
return !iterator.MoveNext();
}
}
आप आगे इस छिपाना सकता है, लेकिन मैं आपको ऐसा करने के संकेत नहीं करते:
public static bool ContainsExactlyOneItem<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
return iterator.MoveNext() && !iterator.MoveNext();
}
}
यह की तरह है चाल जो फंकी है, लेकिन शायद उत्पादन कोड में इस्तेमाल नहीं किया जाना चाहिए। यह बस पर्याप्त स्पष्ट नहीं है। तथ्य यह है & & ऑपरेटर की एलएचएस में पक्ष प्रभाव के लिए आवश्यक है कि आरएचएस उचित रूप से काम करने के लिए सिर्फ बुरा है ... जबकि बहुत मज़ा;)
संपादित करें: मैं बस देखा है कि आप के लिए आया था बिल्कुल एक ही चीज़ के साथ लेकिन मनमाने ढंग से लंबाई के लिए। आपका अंतिम रिटर्न स्टेटमेंट गलत है - यह !en.MoveNext()
वापस होना चाहिए। CountEquals
की एक पुनरावर्ती प्रपत्र (इस का उपयोग नहीं करें कार्यात्मक प्रशंसकों के लिए अब और,:
public static bool CountEquals<T>(this IEnumerable<T> source, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count",
"count must not be negative");
}
// We don't rely on the optimizations in LINQ to Objects here, as
// they have changed between versions.
ICollection<T> genericCollection = source as ICollection<T>;
if (genericCollection != null)
{
return genericCollection.Count == count;
}
ICollection nonGenericCollection = source as ICollection;
if (nonGenericCollection != null)
{
return nonGenericCollection.Count == count;
}
// Okay, we're finally ready to do the actual work...
using (IEnumerator<T> iterator = source.GetEnumerator())
{
for (int i = 0; i < count; i++)
{
if (!iterator.MoveNext())
{
return false;
}
}
// Check we've got no more
return !iterator.MoveNext();
}
}
संपादित करें: यहाँ ICollection
/ICollection<T>
के लिए एक अच्छे नाम (IMO), तर्क की जाँच और अनुकूलन के साथ एक पूर्ण विधि है , यह केवल यहाँ गिगल्स के लिए है):
public static bool CountEquals<T>(this IEnumerable<T> source, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count",
"count must not be negative");
}
using (IEnumerator<T> iterator = source.GetEnumerator())
{
return IteratorCountEquals(iterator, count);
}
}
private static bool IteratorCountEquals<T>(IEnumerator<T> iterator, int count)
{
return count == 0 ? !iterator.MoveNext()
: iterator.MoveNext() && IteratorCountEquals(iterator, count - 1);
}
संपादित करें: एसक्यूएल के लिए LINQ की तरह कुछ के लिए ध्यान दें कि, आप सरल Count()
दृष्टिकोण का उपयोग करना चाहिए - क्योंकि यह है कि यह डेटाबेस के बजाय प्राप्त करने में कठिनाई के बाद किया जाना करने की अनुमति देंगे वास्तविक परिणाम।
मुझे लगता है कि मैंने अपने कोड में किए गए तर्क त्रुटि को * कम से कम * और * बिल्कुल * के संबंध में लोगों को फेंक दिया होगा। मुझे लगता है कि हम अब सबसे अच्छे समाधान पर पहुंचे हैं। – guhou
गणना() केवल संपूर्ण सूची को फिर से भर देगा यदि यह निर्धारित करता है कि उत्तीर्ण आईन्यूमेरेबल आईसीओलेक्शन पर नहीं डाला गया है। तो यदि आप एक सूची उदाहरण, या एक सरणी पास करते हैं, तो यह फिर से चालू नहीं होगा। –
मुझे लगता है कि यह सभी समयपूर्व अनुकूलन है। –