ফরচ বনাম সামুলিস্ট.ফোরএচ () {}


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

উভয়ের মধ্যে একটি গুরুত্বপূর্ণ এবং দরকারী, পার্থক্য রয়েছে।

কারণ .Each forসংগ্রহটি পুনরাবৃত্তি করার জন্য একটি লুপ ব্যবহার করে, এটি বৈধ (সম্পাদনা করুন। নেট 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
তবুও, আপনার পরিবর্তে কিছু তালিকা ব্যবহার করা উচিত। পরিবর্তে সমস্ত সরানো (x => x.RemoveMe)
মার্ক সিডাড

2
লিনকের সাথে, সমস্ত কিছু আরও ভাল করা যায়। আমি কেবল

2
সরানআল () তালিকা <T> এর তালিকার একটি পদ্ধতি।
মার্ক সিডেড

3
আপনি সম্ভবত এটি সম্পর্কে সচেতন, তবে লোকেরা এইভাবে আইটেমগুলি সরিয়ে ফেলা উচিত; আপনি যদি আইটেম এনটি মুছে ফেলেন তবে পুনরাবৃত্তি আইটেমের উপরে চলে যাবে (N + 1) এবং আপনি এটি আপনার প্রতিনিধিতে দেখতে পাবেন না বা এটি সরানোর কোনও সুযোগ পাবেন না, ঠিক যেমন আপনি নিজের জন্য লুপের জন্য এটি করেছিলেন।
এল জোরকো

9
আপনি যদি লুপটির জন্য তালিকার পেছনের দিকে ঘুরে দেখেন তবে কোনও সূচি-শিফ্ট সমস্যা ছাড়াই আপনি আইটেমগুলি সরাতে পারবেন।
এস তারেক Ç

78

আমাদের এখানে কিছু কোড ছিল (ভিএস ২০০৫ এবং সি # ২.০ তে) যেখানে পূর্ববর্তী ইঞ্জিনিয়াররা তাদের যে সমস্ত কোড লিখেছিল তার list.ForEach( delegate(item) { foo;});পরিবর্তে foreach(item in list) {foo; };তারা ব্যবহার করার পথ ছেড়ে চলে গেল । যেমন একটি ডেটা রিডার থেকে সারিগুলি পড়ার জন্য কোডের একটি ব্লক।

আমি এখনও জানি না যে তারা কেন এটি করেছে।

এর ত্রুটিগুলি হ'ল list.ForEach():

  • এটি সি # 2.0 তে আরও ভার্বোজ। যাইহোক, সি # 3 এর পরে, আপনি =>কিছু সুন্দর পরিবেশন করতে " " বাক্য গঠন করতে পারেন।

  • এটি কম পরিচিত। এই কোডটি বজায় রাখতে হবে এমন লোকেরা ভাববেন যে আপনি কেন এমনভাবে করেছিলেন। লেখককে চতুর হিসাবে দেখানো (বাকী কোডটির গুণাগুণটি এটিকে অবহিত করে তোলে) বাদ দেওয়ার কোনও কারণ নেই বলে সিদ্ধান্ত নিতে আমার কিছুটা সময় লেগেছে। এটি কম পাঠযোগ্যও ছিল, })প্রতিনিধি কোড ব্লকের শেষে " " দিয়ে।

  • বিল ওয়াগনারের বই "কার্যকর সি #: 50 কে আপনার সি উন্নত করার জন্য বিশেষ উপায়" যেখানে তিনি অন্যান্য লুপগুলিতে যেমন লুপগুলির জন্য বা তার চেয়ে বেশি পছন্দ করেন সে সম্পর্কে তিনি কথা বলেন - মূল বিষয়টি হ'ল আপনি কম্পাইলারটি নির্মাণের সর্বোত্তম উপায় সিদ্ধান্ত নিতে দিচ্ছেন লুপ সংকলকটির ভবিষ্যতের কোনও সংস্করণ যদি দ্রুত প্রযুক্তি ব্যবহার করতে পরিচালিত হয়, তবে আপনি নিজের কোড পরিবর্তন না করে ফোরচ এবং পুনর্নির্মাণের মাধ্যমে এটি বিনামূল্যে পাবেন।

  • একটি foreach(item in list)কনস্ট্রাক্ট আপনাকে ব্যবহার করতে দেয় breakবা আপনার continueযদি পুনরাবৃত্তি বা লুপ থেকে প্রস্থান করতে হয়। তবে আপনি তালিকাকে ফোরচ লুপের মধ্যে পরিবর্তন করতে পারবেন না।

আমি যে list.ForEachকিছুটা দ্রুত তা দেখে অবাক হয়েছি । তবে এটি সম্ভবত এটি জুড়ে ব্যবহারের একটি বৈধ কারণ নয়, এটি অকাল অপটিমাইজেশন হবে। যদি আপনার অ্যাপ্লিকেশন কোনও ডাটাবেস বা ওয়েব পরিষেবা ব্যবহার করে যা লুপ নিয়ন্ত্রণ নয়, প্রায় সর্বদা সময় যায় where এবং আপনি কি এটি একটি 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 =>"অপারেটরের সাথে আরও সুন্দর বা সংক্ষিপ্তভাবে কিছু করতে পারেন । এর মতো ক্ষেত্রে, ইতিমধ্যে একটি লিনকিউ এক্সটেনশন পদ্ধতি থাকতে পারে যা এর চেয়ে বেশি নির্দিষ্ট ForEach()। যদি দেখুন Where(), Select(), Any(), All(), Max()বা অন্যান্য অনেক LINQ পদ্ধতি এক না ইতিমধ্যে কি আপনি লুপ কাছ থেকে কি চান না।


কেবল কৌতূহলের জন্য ... মাইক্রোসফ্ট বাস্তবায়ন দেখুন ... রেফারেন্সসোর্স.মাইক্রোসফট
আলেকজান্দ্রে

17

মজা করার জন্য, আমি তালিকাটিকে প্রতিফলকের মধ্যে পপ করেছি এবং এটি সি #:

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]);
    }
}

একইভাবে, গণকের মধ্যে মুভনেক্সট যা পূর্বাভাস দ্বারা ব্যবহৃত হয় তা হ'ল:

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;
}

তালিকা.ফোর্চ প্রতিটি মুভনেক্সট-এর চেয়ে অনেক বেশি ছাঁটাই হয়েছে - অনেক কম প্রক্রিয়াজাতকরণ - সম্ভবত সম্ভবত কার্যকর কিছুতে জেআইটিকে ..

তদ্ব্যতীত, foreach () যাই হোক না কেন একটি নতুন গণক বরাদ্দ করবে। জিসি আপনার বন্ধু, তবে আপনি যদি একই বার্তা বারবার করে থাকেন তবে একই প্রতিনিধিটিকে পুনরায় ব্যবহার করার বিপরীতে এটি আরও নিক্ষেপযোগ্য বস্তু তৈরি করবে - কিন্তু - এটি সত্যই একটি সামঞ্জস্য ক্ষেত্রে। সাধারণ ব্যবহারে আপনি অল্প বা কোনও পার্থক্য দেখতে পাবেন।


1
আপনার কোনও গ্যারান্টি নেই যে ফোরচ দ্বারা উত্পন্ন কোডটি সংকলক সংস্করণের মধ্যে একই হবে। উত্পন্ন কোডটি ভবিষ্যতের সংস্করণে উন্নত হতে পারে।
অ্যান্টনি

1
.NET কোর হিসাবে 3.1 forEach এখনও দ্রুত।
জ্যাকমট

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();

তালিকা.ফোর্চা পদ্ধতিতে এই সমস্যা নেই। পুনরাবৃত্তির বর্তমান আইটেমটি বাইরের ল্যাম্বডায় একটি আর্গুমেন্ট হিসাবে মান দ্বারা পাস করা হয়, এবং তারপরে অভ্যন্তরীণ ল্যাম্বদা সঠিকভাবে নিজের যুক্তিতে সেই যুক্তিটি ক্যাপচার করে। সমস্যা সমাধান.

(দুঃখের সাথে আমি বিশ্বাস করি যে ফোরইচ কোনও এক্সটেনশন পদ্ধতির পরিবর্তে তালিকার একজন সদস্য, যদিও এটি আপনার নিজের পক্ষে নির্ধারণ করা সহজ, যাতে আপনার কাছে কোনও সুবিধার পরিমাণে এই সুবিধা রয়েছে))

দ্বিতীয়ত, ফরইচ পদ্ধতি পদ্ধতির একটি সীমাবদ্ধতা রয়েছে। আপনি যদি উৎপাদনের রিটার্ন ব্যবহার করে আইনিউমেন্টেবল প্রয়োগ করে থাকেন তবে ল্যাম্বডায় আপনি কোনও ফলন রিটার্ন করতে পারবেন না। সুতরাং রিটার্নের জিনিসগুলি সরবরাহের জন্য কোনও সংগ্রহের মধ্যে আইটেমগুলির মধ্য দিয়ে লুপিং করা এই পদ্ধতি দ্বারা সম্ভব নয়। আপনাকে ফরচ কিওয়ার্ডটি ব্যবহার করতে হবে এবং লুপের ভিতরে বর্তমান লুপ মানটির একটি অনুলিপি তৈরি করে ক্লোজার সমস্যাটি ঘিরে কাজ করতে হবে।

আরও এখানে


5
সমস্যা আপনার সাথে উল্লেখ foreach"fixed" হয় সি # 5. stackoverflow.com/questions/8898925/...
StriplingWarrior

13

আমার ধারণা someList.ForEach()কলটি সহজেই সমান্তরাল হয়ে উঠতে পারে যখন foreachসাধারণটি সমান্তরালভাবে চালানো খুব সহজ নয়। আপনি সহজেই বিভিন্ন কোরে বিভিন্ন আলাদা প্রতিনিধি চালাতে পারেন, এটি কোনও সাধারণের সাথে করা এতটা সহজ নয় foreach
শুধু আমার 2 সেন্ট


2
আমি মনে করি তিনি বোঝাতে চেয়েছিলেন যে রানটাইম ইঞ্জিন এটি স্বয়ংক্রিয়ভাবে সমান্তরাল করতে পারে। অন্যথায়, পূর্বে এবং। উভয়ই প্রতিটি ক্রিয়া প্রতিনিধিতে পুল থেকে একটি সুতোর সাহায্যে হাত দ্বারা সমান্তরাল করা যেতে পারে
ইসাক সাভো

@ ইস্ক কিন্তু এটি একটি ভুল ধারণা হবে। বেনামে পদ্ধতিতে কোনও স্থানীয় বা সদস্যকে উত্তোলন করা হলে রানটাইমটি 8 ইএসিলি হবে না) প্যারালাইলেজ করতে সক্ষম হবে
রুন এফএস

6

তারা যেমন বলেছে, শয়তানটি বিশদে রয়েছে ...

সংগ্রহের গণনা দুটি পদ্ধতির মধ্যে সবচেয়ে বড় পার্থক্য হ'ল foreachরাষ্ট্র বহন করে, যেখানে ForEach(x => { })নেই।

তবে কিছুটা গভীর খনন করতে দেয়, কারণ এমন কিছু বিষয় রয়েছে যা সম্পর্কে আপনার সচেতন হওয়া উচিত যা আপনার সিদ্ধান্তকে প্রভাবিত করতে পারে, এবং এমন কিছু বিষয় রয়েছে যা উভয় ক্ষেত্রেই কোডিংয়ের সময় আপনাকে সচেতন হওয়া উচিত।

List<T>আচরণ পর্যবেক্ষণ করতে আমাদের সামান্য পরীক্ষায় ব্যবহার করতে দেয় । এই পরীক্ষার জন্য, আমি। নেট 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. সংগ্রহের অনুলিপি একটি অগভীর অনুলিপি।

এটি অবশ্যই কোনওভাবেই থ্রেড নিরাপদ নয়। যেমন উপরে উল্লিখিত ছিল, পুনরাবৃত্তি করার সময় সংগ্রহ পরিবর্তন করা কেবল খারাপ মোজো mo

কিন্তু পুনরাবৃত্তির সময় সংগ্রহের সাথে আমাদের বাহিরের মাধ্যমে পুনরুত্থানের সময় সংগ্রহটি কীভাবে অবৈধ হয়ে উঠবে সে সম্পর্কে কী বলা যায়? সেরা অনুশীলনগুলি ক্রিয়াকলাপ এবং পুনরাবৃত্তির সময় সংগ্রহটির সংস্করণকরণ এবং অন্তর্নিহিত সংগ্রহ কখন পরিবর্তন হবে তা সনাক্ত করতে সংস্করণগুলি পরীক্ষা করার পরামর্শ দেয়।

এখানে জিনিসগুলি সত্যিই দুর্বল হয়ে উঠেছে's মাইক্রোসফ্ট ডকুমেন্টেশন অনুযায়ী:

যদি সংযোজনে পরিবর্তনগুলি করা হয়, যেমন উপাদানগুলি যোগ করা, সংশোধন করা, বা মুছতে, তবে গণকের আচরণ নির্ধারিত।

ভাল, যে কি মানে? উদাহরণস্বরূপ, কেবলমাত্র List<T>প্রয়োগগুলি ব্যতিক্রম হ্যান্ডলিংয়ের অর্থ এই নয় যে কার্যকর করা সমস্ত সংগ্রহগুলি IList<T>একই কাজ করবে। এটি লিসকভ সাবস্টিটিউশন নীতিমালার সুস্পষ্ট লঙ্ঘন বলে মনে হচ্ছে:

একটি সুপার ক্লাসের অবজেক্টগুলি অ্যাপ্লিকেশনটি ভঙ্গ না করে তার সাবক্লাসের অবজেক্টগুলির সাথে প্রতিস্থাপনযোগ্য হবে।

আরেকটি সমস্যা হ'ল গণকের অবশ্যই প্রয়োগ করতে হবে 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 সমস্যা নেই অনাথ পুনরাবৃত্তিকারীদের সাথে ডিল ...

হ্যাঁ, আমি বলেছিলাম পুনরাবৃত্তিকারীরা ... কখনও কখনও এটির পক্ষে সুবিধাজনক। মনে করুন আপনি একটি ডেটাবেস কার্সারের অনুরূপ কিছু বজায় রাখতে চান ... সম্ভবত একাধিক 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

ফোরইচ ফাংশন জেনেরিক ক্লাস তালিকার সদস্য।

আমি অভ্যন্তরীণ কোড পুনরুত্পাদন করতে নিম্নলিখিত এক্সটেনশন তৈরি করেছি:

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

পুরো ফরইচ স্কোপ (প্রতিনিধি ফাংশন) কোডকে একক লাইন হিসাবে চিহ্নিত করা হয় (ফাংশনটি কল করা), এবং আপনি ব্রেকপয়েন্ট বা কোডটিতে পদক্ষেপ স্থাপন করতে পারবেন না। যদি একটি অবিবাহিত ব্যতিক্রম ঘটে তবে পুরো ব্লকটি চিহ্নিত থাকে।


2

List.ForEach () আরও কার্যকরী বলে মনে করা হয়।

List.ForEach()আপনি কি করতে চান বলে। foreach(item in list)আপনি ঠিক কীভাবে এটি করতে চান তাও বলেছেন। এটি ভবিষ্যতে কীভাবে অংশ নিচ্ছে List.ForEachতার বাস্তবায়ন পরিবর্তন করতে মুক্ত করে । উদাহরণস্বরূপ, নেট একটি অনুমানের ভবিষ্যতের সংস্করণ নেট সর্বদা চলতে পারেList.ForEach একটি অনুমানের সমান্তরালভাবে , এই ধারনা অনুযায়ী এই মুহুর্তে প্রত্যেকের কাছে বেশিরভাগ সিপিইউ কোর থাকে যা সাধারণত অলস থাকে।

অন্যদিকে, foreach (item in list)আপনাকে লুপের উপরে আরও কিছুটা নিয়ন্ত্রণ দেয়। উদাহরণস্বরূপ, আপনি জানেন যে আইটেমগুলি একরকম ক্রমিক ক্রমে পুনরাবৃত্তি হবে এবং কোনও আইটেম কিছু শর্ত পূরণ করলে আপনি সহজেই মাঝখানে ভেঙে যেতে পারেন।


এই ইস্যুতে আরও কিছু সাম্প্রতিক মন্তব্য এখানে পাওয়া যায়:

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


1

আপনি যে দ্বিতীয় উপায়ে দেখিয়েছেন তালিকার প্রতিটি উপাদানগুলির জন্য ডেলিগেট পদ্ধতিটি কার্যকর করতে একটি এক্সটেনশন পদ্ধতি ব্যবহার করে।

এইভাবে, আপনার আর একটি প্রতিনিধি (= পদ্ধতি) কল রয়েছে।

অতিরিক্তভাবে, একটি লুপের জন্য তালিকাটি পুনরাবৃত্তি করার সম্ভাবনা রয়েছে ।


1

একটি বিষয় থেকে সাবধান হওয়াটি হ'ল জেনেরিক থেকে কীভাবে প্রস্থান করা যায় Forএক প্রতিটি পদ্ধতি - এই আলোচনাটি দেখুন । যদিও লিঙ্কটি বলে মনে হচ্ছে যে এই পথটি সবচেয়ে দ্রুত। নিশ্চিত নয় কেন - আপনি মনে করেন যে তারা একবার সংকলিত হয়ে গেছে ...


0

একটি উপায় আছে, আমি আমার অ্যাপ্লিকেশনটিতে এটি সম্পন্ন করেছি:

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

আপনি foreach থেকে আপনার আইটেম হিসাবে ব্যবহার করতে পারেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.