अद्यतन 7/17/2012: जाहिरा तौर पर C # 5.0 के रूप में, foreach
नीचे वर्णित व्यवहार को बदल दिया गया है और " नेस्टेड लैम्ब्डा अभिव्यक्ति में एक पुनरावृत्ति चर का उपयोग foreach
अब अप्रत्याशित परिणाम नहीं देता है। " यह उत्तर C # ≥ 5.0 पर लागू नहीं होता है। ।
@ जॉन स्कीट और हर कोई जो फ़ॉरवर्ड कीवर्ड पसंद करता है।
5.0 से पहले C # में "foreach" के साथ समस्या यह है कि यह असंगत है कि कैसे "समझ के लिए समकक्ष" अन्य भाषाओं में काम करता है, और इसके साथ मैं कैसे काम करने की उम्मीद करूंगा (व्यक्तिगत राय यहां केवल इसलिए बताई गई है क्योंकि अन्य ने उनका उल्लेख किया है पठनीयता के संबंध में राय)। " संशोधित क्लोजर एक्सेस " के साथ-साथ " हानिकारक समझे जाने वाले लूप चर पर समापन " से संबंधित सभी प्रश्नों को देखें । यह केवल "हानिकारक" है क्योंकि जिस तरह से "foreach" C # में लागू किया गया है।
@Fredrik Kalseth के उत्तर में कार्यात्मक समतुल्य विस्तार विधि का उपयोग करके निम्नलिखित उदाहरण लें।
public static class Enumerables
{
public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
foreach (T item in @this)
{
action(item);
}
}
}
अतिविशिष्ट उदाहरण के लिए क्षमा याचना। मैं केवल ऑब्जर्वेबल का उपयोग कर रहा हूं क्योंकि यह पूरी तरह से ऐसा कुछ करने के लिए तैयार नहीं है। जाहिर है इस अवलोकन को बनाने के बेहतर तरीके हैं, मैं केवल एक बिंदु को प्रदर्शित करने का प्रयास कर रहा हूं। आमतौर पर अवलोकन योग्य सदस्यता वाला कोड एसिंक्रोनस रूप से निष्पादित किया जाता है और संभावित रूप से किसी अन्य थ्रेड में। यदि "फॉर्च्यूनर" का उपयोग किया जाता है, तो यह बहुत ही अजीब और संभावित गैर-नियतात्मक परिणाम उत्पन्न कर सकता है।
"ForEach" एक्सटेंशन विधि का उपयोग करके निम्नलिखित परीक्षण पास होता है:
[Test]
public void ForEachExtensionWin()
{
//Yes, I know there is an Observable.Range.
var values = Enumerable.Range(0, 10);
var observable = Observable.Create<Func<int>>(source =>
{
values.ForEach(value =>
source.OnNext(() => value));
source.OnCompleted();
return () => { };
});
//Simulate subscribing and evaluating Funcs
var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();
//Win
Assert.That(evaluatedObservable,
Is.EquivalentTo(values.ToList()));
}
निम्नलिखित त्रुटि के साथ विफल रहता है:
अपेक्षित: <0, 1, 2, 3, 4, 5, 6, 7, 8, 9> के बराबर: लेकिन था: <9, 9, 9, 9, 9, 9, 9, 9, 9>
[Test]
public void ForEachKeywordFail()
{
//Yes, I know there is an Observable.Range.
var values = Enumerable.Range(0, 10);
var observable = Observable.Create<Func<int>>(source =>
{
foreach (var value in values)
{
//If you have resharper, notice the warning
source.OnNext(() => value);
}
source.OnCompleted();
return () => { };
});
//Simulate subscribing and evaluating Funcs
var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();
//Fail
Assert.That(evaluatedObservable,
Is.EquivalentTo(values.ToList()));
}
ForEach()
।