foreach vs someList.ForEach () {}


167

स्पष्ट रूप से एक संग्रह पर पुनरावृति करने के कई तरीके हैं। जिज्ञासु अगर कोई मतभेद हैं, या आप एक से दूसरे तरीके का उपयोग क्यों करेंगे।

पहला प्रकार:

List<string> someList = <some way to init>
foreach(string s in someList) {
   <process the string>
}

अन्य रास्ता:

List<string> someList = <some way to init>
someList.ForEach(delegate(string s) {
    <process the string>
});

मुझे लगता है कि मैं अपने ऊपर इस्तेमाल होने वाले गुमनाम डेलीगेट के बजाय अपने सिर के ऊपर से हट जाऊंगा, आपके पास एक पुन: प्रयोज्य प्रतिनिधि होगा जो आपको मिल सकता है ...


जवाबों:


134

दोनों के बीच एक महत्वपूर्ण और उपयोगी, भेद है।

क्योंकि .ForEach forसंग्रह को पुनरावृत्त करने के लिए एक लूप का उपयोग करता है , यह मान्य है (संपादित करें: .net 4.5 से पहले - कार्यान्वयन बदल गया और वे दोनों फेंक देते हैं):

someList.ForEach(x => { if(x.RemoveMe) someList.Remove(x); }); 

जबकि foreachएक एन्यूमरेटर का उपयोग करता है, इसलिए यह मान्य नहीं है:

foreach(var item in someList)
  if(item.RemoveMe) someList.Remove(item);

tl; dr: इस कोड को अपने आवेदन में न डालें!

ये उदाहरण सर्वोत्तम अभ्यास नहीं हैं, वे केवल ForEach()और के बीच के मतभेदों को प्रदर्शित करने के लिए हैं foreach

एक forलूप के भीतर एक सूची से आइटम हटाने के दुष्प्रभाव हो सकते हैं। इस सवाल पर टिप्पणियों में सबसे आम वर्णित है।

आम तौर पर, यदि आप एक सूची से कई वस्तुओं को निकालना चाहते हैं, तो आप वास्तविक निष्कासन से किन वस्तुओं को निकालना है, इसका निर्धारण अलग करना चाहेंगे। यह आपके कोड को कॉम्पैक्ट नहीं रखता है, लेकिन यह गारंटी देता है कि आप किसी भी आइटम को याद नहीं करते हैं।


35
फिर भी, आपको इसके बजाय कुछList.RemoveAll (x => x.RemoveMe) का उपयोग करना चाहिए
Cidade

2
Linq के साथ, सभी चीजें बेहतर तरीके से की जा सकती हैं। मैं सिर्फ foreach के भीतर संग्रह को संशोधित करने का एक उदाहरण दिखा रहा था ...

2
RemoveAll () List <T> पर एक विधि है।
मार्क सिडेड

3
आप शायद इसके बारे में जानते हैं, लेकिन लोगों को इस तरह से आइटम हटाने से सावधान रहना चाहिए; यदि आप आइटम N को हटाते हैं, तो पुनरावृत्ति आइटम (N + 1) पर छोड़ देगी और आप इसे अपने प्रतिनिधि में नहीं देख पाएंगे या इसे निकालने का मौका नहीं मिलेगा, जैसे कि आपने लूप के लिए स्वयं में ऐसा किया था।
एल जर्को

9
यदि आप सूची को लूप के लिए पीछे की ओर से जोड़ते हैं, तो आप बिना किसी इंडेक्स-शिफ्ट की समस्याओं के आइटम हटा सकते हैं।
एस। तारिक inetin

78

हमारे यहां (VS2005 और C # 2.0 में) कुछ कोड थे, जहां पिछले इंजीनियर अपने लिखे गए सभी कोड के list.ForEach( delegate(item) { foo;});बजाय उपयोग करने के foreach(item in list) {foo; };लिए अपने रास्ते से चले गए थे । उदाहरण के लिए डेटारेडर से पंक्तियों को पढ़ने के लिए कोड का एक ब्लॉक।

मुझे अभी भी ठीक से पता नहीं है कि उन्होंने ऐसा क्यों किया।

की कमियां list.ForEach()हैं:

  • यह C # 2.0 में अधिक क्रिया है। हालाँकि, C # 3 के बाद, आप =>कुछ अच्छी तरह से अभिव्यक्ति बनाने के लिए " " सिंटैक्स का उपयोग कर सकते हैं ।

  • यह कम परिचित है। इस कोड को बनाए रखने वाले लोगों को आश्चर्य होगा कि आपने ऐसा क्यों किया। मुझे यह तय करने में थोड़ी देर लगी कि कोई कारण नहीं था, शायद लेखक को चतुर बनाने के अलावा (बाकी कोड की गुणवत्ता कम थी)। यह भी कम पठनीय था, })प्रतिनिधि कोड ब्लॉक के अंत में " " था।

  • बिल वैगनर की पुस्तक "इफेक्टिव सी #: 50 सीजनल इंप्रूव्ड टू योर सी #" भी देखें, जहां वह इस बारे में बात करता है कि फॉरवर्ड को अन्य लूप्स के लिए पसंद क्यों किया जाता है, जैसे कि लूप्स - मुख्य बिंदु यह है कि आप कंपाइलर को बनाने का सबसे अच्छा तरीका तय करने दे रहे हैं। सूचित करते रहना। यदि कंपाइलर का भविष्य का संस्करण एक तेज़ तकनीक का उपयोग करने का प्रबंधन करता है, तो आपको अपना कोड बदलने के बजाय, फ़ॉरचेक और पुनर्निर्माण का उपयोग करके मुफ्त में मिलेगा।

  • एक foreach(item in list)निर्माण आपको उपयोग करने की अनुमति देता है breakया continueयदि आपको पुनरावृत्ति या लूप से बाहर निकलने की आवश्यकता होती है। लेकिन आप सूची को फ़ॉरेस्ट लूप के अंदर नहीं बदल सकते।

मैं यह देखकर हैरान हूं कि list.ForEachयह थोड़ा तेज है। लेकिन यह संभवत: इसका उपयोग करने का एक वैध कारण नहीं है, यह समय से पहले का अनुकूलन होगा। यदि आपका एप्लिकेशन डेटाबेस या वेब सेवा का उपयोग करता है, जो कि लूप नियंत्रण नहीं है, तो लगभग हमेशा वही होता है जहां समय जाता है। और क्या आपने इसे forलूप के खिलाफ भी बेंचमार्क किया है? list.ForEachतेजी से कि आंतरिक रूप से उपयोग कर रहा है और एक के कारण हो सकता forआवरण के बिना पाश भी तेजी से होगा।

मैं असहमत हूं कि list.ForEach(delegate)संस्करण किसी भी महत्वपूर्ण तरीके से "अधिक कार्यात्मक" है। यह एक फ़ंक्शन को फ़ंक्शन करता है, लेकिन परिणाम या प्रोग्राम संगठन में कोई बड़ा अंतर नहीं है।

मुझे नहीं लगता कि foreach(item in list)"यह कहता है कि आप इसे कैसे चाहते हैं" - एक for(int 1 = 0; i < count; i++)लूप ऐसा करता है, एक foreachलूप कंपाइलर पर नियंत्रण का विकल्प छोड़ देता है।

मेरी भावना एक नई परियोजना पर, foreach(item in list)सामान्य उपयोग का पालन करने के लिए और पठनीयता के लिए अधिकांश छोरों का उपयोग करने के लिए है, और list.Foreach()केवल छोटे ब्लॉकों के लिए उपयोग करें , जब आप सी # 3 " =>" ऑपरेटर के साथ कुछ और अधिक सुरुचिपूर्ण ढंग से या कॉम्पैक्ट रूप से कर सकते हैं । इस तरह के मामलों में, पहले से ही एक LINQ एक्सटेंशन विधि हो सकती है जो इससे अधिक विशिष्ट है ForEach()। अगर देखें Where(), Select(), Any(), All(), Max()या कई अन्य LINQ तरीकों में से एक नहीं है जो पहले से आपके पाश से चाहते हैं।


बस जिज्ञासा ... Microsoft क्रियान्वयन पर नजर ... के लिए referencesource.microsoft.com/#mscorlib/system/collections/...
एलेक्जेंडर

17

मज़े के लिए, मैंने सूची को परावर्तक में पॉप किया और यह परिणामी C # है:

public void ForEach(Action<T> action)
{
    if (action == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    for (int i = 0; i < this._size; i++)
    {
        action(this._items[i]);
    }
}

इसी तरह, Enumerator में MoveNext जो कि foreach द्वारा उपयोग किया जाता है वह है:

public bool MoveNext()
{
    if (this.version != this.list._version)
    {
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
    }
    if (this.index < this.list._size)
    {
        this.current = this.list._items[this.index];
        this.index++;
        return true;
    }
    this.index = this.list._size + 1;
    this.current = default(T);
    return false;
}

List.ForEach MoveNext की तुलना में बहुत अधिक नीचे छंटनी की गई है - बहुत कम प्रसंस्करण - अधिक संभावना है कि कुछ कुशल में JIT ..

इसके अलावा, foreach () एक नया एन्यूमरेटर आवंटित करेगा चाहे कोई भी हो। GC आपका मित्र है, लेकिन यदि आप एक ही फॉर्च्यूनर को बार-बार कर रहे हैं, तो यह अधिक विचलित वस्तुओं को बना देगा, जैसा कि एक ही प्रतिनिधि को पुन: उपयोग करने का विरोध करता है - लेकिन - यह वास्तव में एक फ्रिंज केस है। विशिष्ट उपयोग में आप कम या कोई अंतर नहीं देखेंगे।


1
आपको इसकी कोई गारंटी नहीं है कि संकलक संस्करणों के बीच फॉर्च्यूनर द्वारा उत्पन्न कोड समान होगा। उत्पन्न कोड भविष्य के संस्करण द्वारा सुधारा जा सकता है।
एंथनी

1
.NET Core 3.1 के रूप में अभी भी तेजी से आगे बढ़ रहा है।
कटहल

13

मैं दो अस्पष्ट-ईश चीजों को जानता हूं जो उन्हें अलग बनाती हैं। मुझे जाओ!

सबसे पहले, सूची में प्रत्येक आइटम के लिए एक प्रतिनिधि बनाने का क्लासिक बग है। यदि आप फॉर्च्यूसर कीवर्ड का उपयोग करते हैं, तो आपके सभी प्रतिनिधि सूची के अंतिम आइटम का जिक्र कर सकते हैं:

    // A list of actions to execute later
    List<Action> actions = new List<Action>();

    // Numbers 0 to 9
    List<int> numbers = Enumerable.Range(0, 10).ToList();

    // Store an action that prints each number (WRONG!)
    foreach (int number in numbers)
        actions.Add(() => Console.WriteLine(number));

    // Run the actions, we actually print 10 copies of "9"
    foreach (Action action in actions)
        action();

    // So try again
    actions.Clear();

    // Store an action that prints each number (RIGHT!)
    numbers.ForEach(number =>
        actions.Add(() => Console.WriteLine(number)));

    // Run the actions
    foreach (Action action in actions)
        action();

List.ForEach विधि में यह समस्या नहीं है। पुनरावृत्ति की वर्तमान वस्तु को बाहरी लैम्ब्डा के तर्क के रूप में मान के द्वारा पारित किया जाता है, और फिर आंतरिक लैम्ब्डा उस तर्क को अपने स्वयं के बंद होने में सही ढंग से पकड़ लेता है। समस्या सुलझ गयी।

(दुख की बात है कि मेरा मानना ​​है कि ForEach एक विस्तार विधि के बजाय सूची का एक सदस्य है, हालांकि इसे स्वयं परिभाषित करना आसान है, इसलिए आपके पास किसी भी प्रकार पर यह सुविधा है।)

दूसरे, ForEach पद्धति दृष्टिकोण में एक सीमा है। यदि आप यील्ड रिटर्न का उपयोग करके IEnumerable को लागू कर रहे हैं, तो आप लैम्ब्डा के अंदर यील्ड रिटर्न नहीं कर सकते। तो रिटर्न में चीजों को इकट्ठा करने के लिए एक संग्रह में वस्तुओं के माध्यम से लूपिंग इस विधि से संभव नहीं है। आपको लूप के अंदर वर्तमान लूप मान की एक प्रतिलिपि मैन्युअल रूप से बनाकर फ़ॉरवर्ड कीवर्ड का उपयोग करना होगा और क्लोज़र समस्या के आसपास काम करना होगा।

यहां अधिक


5
समस्या आप के साथ उल्लेख foreach"निर्धारित" है सी में # 5. stackoverflow.com/questions/8898925/...
StriplingWarrior

13

मुझे लगता है कि someList.ForEach()कॉल को आसानी से समानांतर किया जा सकता है जबकि सामान्य foreachयह समानांतर चलाने के लिए आसान नहीं है। आप अलग-अलग कोर पर कई अलग-अलग प्रतिनिधियों को आसानी से चला सकते हैं, जो एक सामान्य के साथ करना आसान नहीं है foreach
बस मेरे 2 सेंट


2
मुझे लगता है कि उनका मतलब था कि रनटाइम इंजन अपने आप इसे समानांतर कर सकता है। अन्यथा, दोनों फोर्क और .ForEach को प्रत्येक एक्शन डेलीगेट में पूल से एक धागे का उपयोग करके हाथ से समानांतर किया जा सकता है
Isak Savo

@ इस्क लेकिन यह एक गलत धारणा होगी। अगर अनाम विधि किसी स्थानीय या सदस्य को रनटाइम 8easily नहीं फहराएगी) तो पार्लेलाइज़ करने में सक्षम होगी
Rune FS

6

जैसा कि वे कहते हैं, शैतान विवरण में है ...

संग्रह गणना के दो तरीकों के बीच सबसे बड़ा अंतर यह है कि foreachराज्य ForEach(x => { })करता है , जबकि नहीं करता है।

लेकिन खुदाई को थोड़ा और गहरा करने दें, क्योंकि कुछ ऐसी चीजें हैं जिनके बारे में आपको पता होना चाहिए कि आपके निर्णय को प्रभावित कर सकते हैं, और कुछ ऐसे मामले हैं जिनके बारे में आपको पता होना चाहिए कि किसी भी मामले के लिए कोडिंग करते समय।

List<T>व्यवहार का निरीक्षण करने के लिए हमारे छोटे से प्रयोग में मदद करता है। इस प्रयोग के लिए, मैं .NET 4.7.2 का उपयोग कर रहा हूं:

var names = new List<string>
{
    "Henry",
    "Shirley",
    "Ann",
    "Peter",
    "Nancy"
};

foreachपहले के साथ इस पर पुनरावृति देता है :

foreach (var name in names)
{
    Console.WriteLine(name);
}

हम इसमें विस्तार कर सकते हैं:

using (var enumerator = names.GetEnumerator())
{

}

हाथ में प्रगणक के साथ, कवर के तहत हम देख रहे हैं:

public List<T>.Enumerator GetEnumerator()
{
  return new List<T>.Enumerator(this);
}
    internal Enumerator(List<T> list)
{
  this.list = list;
  this.index = 0;
  this.version = list._version;
  this.current = default (T);
}

public bool MoveNext()
{
  List<T> list = this.list;
  if (this.version != list._version || (uint) this.index >= (uint) list._size)
    return this.MoveNextRare();
  this.current = list._items[this.index];
  ++this.index;
  return true;
}

object IEnumerator.Current
{
  {
    if (this.index == 0 || this.index == this.list._size + 1)
      ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
    return (object) this.Current;
  }
}

दो चीजें तत्काल स्पष्ट हो जाती हैं:

  1. हमें अंतर्निहित संग्रह के अंतरंग ज्ञान के साथ एक राज्य वस्तु दी जाती है।
  2. संग्रह की प्रति उथली प्रति है।

यह निश्चित रूप से किसी भी तरह से धागा सुरक्षित नहीं है। जैसा कि ऊपर बताया गया था, पुनरावृत्ति करते हुए संग्रह को बदलना केवल खराब मोजो है।

लेकिन पुनरावृत्ति के दौरान संग्रह के साथ अमान्य होने की समस्या के बारे में क्या है कि हमारे बाहर के लोग पुनरावृत्ति के दौरान संग्रह के साथ मिल रहे हैं? सर्वश्रेष्ठ प्रथाओं से पता चलता है कि संचालन और पुनरावृत्ति के दौरान संग्रह को संस्करणबद्ध करना, और अंतर्निहित संग्रह में परिवर्तन होने पर पता लगाने के लिए संस्करणों की जांच करना।

यहां वह चीजें हैं जहां चीजें वास्तव में मुखर हैं। Microsoft दस्तावेज़ के अनुसार:

यदि संग्रह में परिवर्तन किए जाते हैं, जैसे कि तत्वों को जोड़ना, संशोधित करना या हटाना, एन्यूमरेटर का व्यवहार अपरिभाषित है।

खैर, इसका क्या मतलब है? उदाहरण के माध्यम से, सिर्फ इसलिए List<T>कि अपवाद अपवाद को लागू करने का मतलब यह नहीं है कि लागू करने वाले सभी संग्रह IList<T>समान होंगे। यह Liskov प्रतिस्थापन सिद्धांत का स्पष्ट उल्लंघन प्रतीत होता है:

एक सुपरक्लास की वस्तुएं आवेदन को तोड़े बिना उसके उपवर्गों की वस्तुओं से बदली जा सकेंगी।

एक और समस्या यह है कि प्रगणक को लागू करना चाहिए IDisposable- इसका मतलब है कि संभावित मेमोरी लीक का एक अन्य स्रोत, न केवल अगर कॉलर इसे गलत करता है, लेकिन यदि लेखक Disposeपैटर्न को सही तरीके से लागू नहीं करता है।

अंत में, हमारे पास एक जीवन भर का मुद्दा है ... क्या होता है अगर पुनरावृत्ति मान्य है, लेकिन अंतर्निहित संग्रह चला गया है? अब हम क्या थे का एक स्नैपशॉट ... जब आप एक संग्रह और इसके पुनरावृत्तियों के जीवनकाल को अलग करते हैं, तो आप परेशानी पूछ रहे हैं।

अब जांच करें ForEach(x => { }):

names.ForEach(name =>
{

});

इसका विस्तार होता है:

public void ForEach(Action<T> action)
{
  if (action == null)
    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
  int version = this._version;
  for (int index = 0; index < this._size && (version == this._version || !BinaryCompatibility.TargetsAtLeast_Desktop_V4_5); ++index)
    action(this._items[index]);
  if (version == this._version || !BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
    return;
  ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}

महत्वपूर्ण नोट निम्नलिखित है:

for (int index = 0; index < this._size && ... ; ++index) action(this._items[index]);

यह कोड किसी भी एन्यूमरेटर (कुछ भी नहीं Dispose) को आवंटित नहीं करता है , और पुनरावृत्ति करते समय विराम नहीं देता है ।

ध्यान दें कि यह अंतर्निहित संग्रह की उथली प्रतिलिपि भी करता है, लेकिन संग्रह अब समय में एक स्नैपशॉट है। यदि लेखक संग्रह को बदलने या 'बासी' के लिए एक चेक को सही ढंग से लागू नहीं करता है, तो स्नैपशॉट अभी भी मान्य है।

यह किसी भी तरह से आपको आजीवन मुद्दों की समस्या से बचाता नहीं है ... यदि अंतर्निहित संग्रह गायब हो जाता है, तो अब आपके पास एक उथली प्रति है जो इंगित करता है कि क्या था ... लेकिन कम से कम आपको कोई Disposeसमस्या नहीं है अनाथ iterators पर सौदा ...

हां, मैंने कहा कि पुनरावृत्तियों ... कभी-कभी राज्य के लिए इसका लाभकारी होता है। मान लीजिए कि आप एक डेटाबेस कर्सर के लिए कुछ समान बनाए रखना चाहते हैं ... शायद कई foreachशैली Iterator<T>का रास्ता तय करना है। मैं व्यक्तिगत रूप से डिजाइन की इस शैली को नापसंद करता हूं क्योंकि बहुत सारे जीवनकाल के मुद्दे हैं, और आप उन संग्रह के लेखकों की अच्छी कृतियों पर भरोसा करते हैं जो आप पर भरोसा कर रहे हैं (जब तक कि आप सचमुच खरोंच से खुद को सब कुछ नहीं लिखते)।

हमेशा एक तीसरा विकल्प होता है ...

for (var i = 0; i < names.Count; i++)
{
    Console.WriteLine(names[i]);
}

यह सेक्सी नहीं है, लेकिन इसके दांत मिले ( टॉम क्रूज और फिल्म द फर्म से माफी )

यह आपकी पसंद है, लेकिन अब आप जानते हैं और यह एक सूचित किया जा सकता है।


5

आप अनाम प्रतिनिधि को नाम दे सकते हैं :-)

और आप दूसरा लिख ​​सकते हैं:

someList.ForEach(s => s.ToUpper())

जिसे मैं पसंद करता हूं, और बहुत सारे टाइपिंग बचाता है।

जैसा कि जोआचिम कहते हैं, समानांतरता दूसरे रूप में लागू करना आसान है।


2

पर्दे के पीछे, अनाम प्रतिनिधि एक वास्तविक विधि में बदल जाता है ताकि आप दूसरी पसंद के साथ कुछ ओवरहेड कर सकें यदि कंपाइलर फ़ंक्शन को इनलाइन करने के लिए नहीं चुनते हैं। इसके अतिरिक्त, अनाम प्रतिनिधि प्रतिनिधि के शरीर द्वारा संदर्भित किसी भी स्थानीय चर को इस तथ्य को छिपाने के लिए संकलक चाल के कारण प्रकृति में बदल जाएगा कि यह एक नई विधि के लिए संकलित हो जाता है। यहाँ पर अधिक जानकारी कैसे सी # यह जादू करता है:

http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx


2

ForEach फ़ंक्शन सामान्य वर्ग सूची का सदस्य है।

मैंने आंतरिक कोड को पुन: उत्पन्न करने के लिए निम्नलिखित एक्सटेंशन बनाया है:

public static class MyExtension<T>
    {
        public static void MyForEach(this IEnumerable<T> collection, Action<T> action)
        {
            foreach (T item in collection)
                action.Invoke(item);
        }
    }

तो अंत हम एक सामान्य foreach (या यदि आप चाहते हैं के लिए एक पाश) का उपयोग कर रहे हैं।

दूसरी ओर, एक प्रतिनिधि समारोह का उपयोग एक फ़ंक्शन को परिभाषित करने का सिर्फ एक और तरीका है, यह कोड:

delegate(string s) {
    <process the string>
}

के बराबर है:

private static void myFunction(string s, <other variables...>)
{
   <process the string>
}

या लेबाडा अभिव्यक्ति का उपयोग कर:

(s) => <process the string>

2

पूरे ForEach गुंजाइश (प्रतिनिधि फ़ंक्शन) को कोड की एक पंक्ति (फ़ंक्शन को कॉल करना) के रूप में माना जाता है, और आप कोड में ब्रेकपॉइंट या चरण सेट नहीं कर सकते। यदि एक अखंड अपवाद होता है, तो पूरे ब्लॉक को चिह्नित किया जाता है।


2

List.ForEach () को अधिक कार्यात्मक माना जाता है।

List.ForEach()कहता है कि तुम क्या चाहते हो। foreach(item in list)यह भी कहता है कि आप इसे कैसे चाहते हैं। यह भविष्य में कैसे भाग List.ForEachके कार्यान्वयन को बदलने के लिए स्वतंत्र छोड़ देता है । उदाहरण के लिए, .Net का एक काल्पनिक भविष्य संस्करण हमेशा समानांतर में चल सकता है , इस धारणा के तहत कि इस बिंदु पर सभी के पास कई सीपीयू कोर हैं जो आम तौर पर बेकार बैठे हैं। List.ForEach

दूसरी ओर, foreach (item in list)आपको लूप पर थोड़ा अधिक नियंत्रण देता है। उदाहरण के लिए, आप जानते हैं कि वस्तुओं को किसी प्रकार के अनुक्रमिक क्रम में पुनरावृत्त किया जाएगा, और यदि कोई वस्तु किसी शर्त को पूरा करती है, तो आप आसानी से बीच में ही तोड़ सकते हैं।


इस मुद्दे पर कुछ और हालिया टिप्पणियां यहां उपलब्ध हैं:

https://stackoverflow.com/a/529197/3043


1

दूसरा तरीका जो आपने दिखाया था वह सूची में प्रत्येक तत्व के लिए प्रतिनिधि विधि को निष्पादित करने के लिए एक एक्सटेंशन विधि का उपयोग करता है।

इस तरह, आपके पास एक और प्रतिनिधि (= विधि) कॉल है।

इसके अतिरिक्त, लूप के लिए सूची को पुनरावृत्त करने की संभावना है ।


1

सावधान रहने की एक बात यह है कि जेनेरिक। वर्क विधि से कैसे बाहर निकलें - यह चर्चा देखें । हालांकि लिंक से लगता है कि यह रास्ता सबसे तेज़ है। यकीन नहीं क्यों - आपको लगता है कि वे एक बार संकलित होने के बराबर होंगे ...


0

एक तरीका है, मैंने इसे अपने ऐप में किया है:

List<string> someList = <some way to init>
someList.ForEach(s => <your actions>);

आप अपने आइटम के रूप में फोरच से उपयोग कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.