c# على التمييز بين المكره وعداد




هل السجن اكراه (7)

"المتكررات هي ميزة جديدة في C # 2.0. مكرر هو طريقة ، الحصول على ملحق أو عامل يتيح لك دعم التكرار في الصف أو البنية دون الحاجة إلى تنفيذ واجهة IEnumerable بأكملها. بدلا من ذلك ، يمكنك توفير مجرد مكرر ، والذي ببساطة اجتياز بنيات البيانات في صفك.عندما يكتشف المحول البرمجي جهاز التكرار الخاص بك ، سيقوم تلقائيًا بإنشاء أساليب Current و MoveNext و Dispose لواجهة IEnumerable أو IEnumerable. " - ام msdn

سؤال مقابلة لمهمة .NET 3.5 هو "ما هو الفرق بين المكرر وعداد"؟

هذا هو التمييز الأساسي الذي يجب القيام به ، وماذا مع LINQ ، إلخ.

على أي حال ، ما هو الفرق؟ لا يبدو لي أن أجد تعريف ثابت على الشبكة. لا أخطئ ، يمكنني العثور على معنى المصطلحين ولكني حصلت على إجابات مختلفة قليلاً. ما هو أفضل إجابة للمقابلة؟

IMO مكرر "iterates" عبر مجموعة و يوفر العداد وظيفة تكرار ولكن يجب استدعاء هذا.

أيضا ، ويقال باستخدام الكلمات الرئيسية العائد لحفظ الدولة. ما هي بالضبط هذه الحالة؟ هل هناك مثال على هذه الفائدة التي تحدث؟


يتعامل التعداد مع الكائنات بينما يتعامل التكرار مع القيم فقط. يتم استخدام التعداد عندما نستخدم متجهات hashtable etc بينما يتم استخدام التكرار في حلقة loop إلخ. إنني لم أستخدم أبدًا الكلمة الرئيسية للعرض لذا لم أتمكن من إخبارك.


لفهم المكررات ، نحتاج أولاً إلى فهم العدادين.

العدّاد عبارة عن كائنات متخصصة تزود الفرد بالوسائل اللازمة للانتقال عبر قائمة مرتبة من العناصر في وقت واحد (يطلق على نفس النوع من الشيء أحيانًا اسم "المؤشر"). يوفر .NET framework اثنين من الواجهات الهامة المتعلقة العداد: IEnumerator و IEnumerable. الكائنات التي تقوم بتطبيق IEnumerator هي نفسها العدادات؛ يدعمون الأعضاء التاليين:

  • الخاصية Current ، والتي تشير إلى موضع في القائمة

  • الأسلوب MoveNext ، الذي ينقل العنصر الحالي الأول على طول القائمة

  • طريقة إعادة الضبط ، والتي تنقل العنصر الحالي إلى موضعه الأولي (والذي هو قبل العنصر الأول).

من ناحية أخرى ، فإن Iterаtors ينفّذ المعيار. قدم. NET 2.0 iterätortor ، الذي هو enumerаtor مترجم ، mаnifested. عندما يكون الكائن enumerаble عبارة عن GetEnumerаtor ، إما بشكل مباشر أو غير مباشر ، يقوم المحول البرمجي بتجميع وإرجاع كائن iterаtor مناسب. Optionlly ، يمكن أن يكون الجمع بين الكائن وتعدده.

العنصر الأساسي من كتلة iterаtor هو سندات العائد. هناك فرق واحد كبير بين iterаtors و enumerаtors: Iterаtors لا تنفذ طريقة إعادة تعيين. تحديد طريقة إعادة تعيين على аn а it it c c استثناء.

الهدف من التكرارات هو السماح بتنفيذ سهل من العدادين. إذا كانت هناك حاجة إلى إرجاع أحد العدادين أو فئة لا تعد ولا تحصى لقائمة مرتبة من العناصر ، فيتم كتابتها بحيث يتم إرجاع كل عنصر بالترتيب الصحيح باستخدام عبارة "العائد".


تعني كلمة "تكرار" تكرار بعض الخطوات ، بينما تعد تعدادًا لكل القيم في مجموعة من القيم. لذا فإن التعداد يتطلب عادةً نوعًا من التكرار.

بهذه الطريقة ، يعد التعداد حالة خاصة للتكرار حيث تحصل الخطوة على قيمة من مجموعة.

لاحظ "عادة" - يمكن أيضا أن يتم تنفيذ تعداد بشكل متكرر ، ولكن ترتبط ارتباطا وثيقا بالتكرار والتكرار بحيث لا يهمني هذا الاختلاف الطفيف.

يمكنك أيضًا تعداد قيم لا تخزنها بشكل صريح في مجموعة. على سبيل المثال ، يمكنك تعداد العدد الطبيعي ، أو الأعداد الأولية ، أو أيًا كان ، لكنك ستحسب هذه القيم أثناء التعداد ولا تسترجعها من مجموعة مادية. أنت تفهم هذه الحالة كتعداد مجموعة ظاهرية بقيمها المحددة بواسطة بعض المنطق.

أفترض أن ريد كوبسي حصل على هذه النقطة. في C # هناك طريقتان رئيسيتان لتعداد شيء ما.

  1. تنفيذ Enumerable وفئة تنفيذ IEnumerator
  2. تنفيذ مكرر مع بيان yield

الطريقة الأولى هي أصعب لتنفيذ واستخدام الكائنات لتعداد. الطريقة الثانية أسهل في التنفيذ وتستخدم الاستمرارية.


بما أنه لم يتم تقديم أمثلة ، فهذه واحدة مفيدة لي.

العداد هو كائن تحصل عليه عند استدعاء .GetEnumerator () على فئة أو نوع يقوم بتنفيذ واجهة IEnumerator. عند تنفيذ هذه الواجهة ، تكون قد أنشأت جميع الشفرات اللازمة لمستخدم التحويل لتمكينك من استخدام foreach "للتكرار" على مجموعتك.

لا تحصل على هذه الكلمة 'iterate' مشوشة مع المكرر ، فكل من Enumerator و iterator يسمحان لك بـ 'iterate' ، فالتعداد والتكرار هما في الأساس نفس العملية ، لكن يتم تنفيذهما بشكل مختلف. التعداد يعني أنك قمت بتوسعة واجهة IEnumerator التكرار يعني أنك قمت بإنشاء بنية iterator في صفك (كما هو موضح أدناه) ، وأنك تتصل بـ foreach في صفك ، وفي الوقت الذي يقوم فيه compilor تلقائيًا بإنشاء وظيفة العداد لك.

لاحظ أيضًا أنه لا يتعين عليك فعل القرفصاء مع العداد الخاص بك. يمكنك الاتصال MyClass.GetEnumerator() طوال اليوم ، وعدم القيام بأي شيء معها (على سبيل المثال:

IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator() ).

لاحظ أيضًا أن تركيب جهاز التكرار في صفك لا يتم استخدامه إلا عندما تستخدمه فعليًا ، أي أنك قمت foreach في الفصل الدراسي.

إليك مثال على msdn من msdn :

public class DaysOfTheWeek : System.Collections.IEnumerable
{

     string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

     //This is the iterator!!!
     public System.Collections.IEnumerator GetEnumerator()
     {
         for (int i = 0; i < days.Length; i++)
         {
             yield return days[i];
         }
     }

}

class TestDaysOfTheWeek
{
    static void Main()
    {
        // Create an instance of the collection class
        DaysOfTheWeek week = new DaysOfTheWeek();

        // Iterate with foreach - this is using the iterator!!! When the compiler
        //detects your iterator, it will automatically generate the Current, 
        //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface
        foreach (string day in week)
        {
            System.Console.Write(day + " ");
        }
    }
}
// Output: Sun Mon Tue Wed Thr Fri Sat

"في حين أن بيان foreach هو المستهلك من العداد ، مكرر هو منتج من العداد".

ما ورد أعلاه هو كيف "C # 5.0 في A NutShell" يفسر ذلك ، وكان مفيدا بالنسبة لي.

بمعنى آخر ، تستخدم العبارة foreach MoveNext () ، والخاصية الحالية لـ IEnumerator لتكرارها من خلال تسلسل ، بينما يتم استخدام المكرر لإنتاج تنفيذ IEnumerator الذي سيتم استخدامه بواسطة العبارة foreach. في C # ، عندما تكتب طريقة iterator تحتوي على بيان العائد ، سيقوم المترجم بإنشاء حساب خاص لك. وعندما تقوم بالتكرار خلال العناصر الموجودة في التسلسل ، ستقوم باستدعاء MoveNext () والخاصية الحالية للعداد الخاص. يتم تنفيذ هذه الطرق / الخصائص بواسطة التعليمة البرمجية الخاصة بك في طريقة الكادر الذي سيُطلق عليه بشكل متكرر لإعطاء قيم حتى لا تكون هناك قيم متبقية للإنتاج.

هذا هو فهمي لكيفية تعريف C # العدادين ، والمكررات.


ما يستدعي C # مكررًا أكثر شيوعًا (خارج C # world) يسمى وظيفة generator أو المولد (على سبيل المثال في Python). وظيفة المولد هي حالة متخصصة من coroutine . AC # iterator (generator) هو شكل خاص من العداد (نوع بيانات يقوم بتنفيذ واجهة IEnumerable ).

أنا لا أحب هذا الاستخدام لمصطلح iterator لمولد C # لأنه هو مجرد العداد كما هو مكرر. متأخرة جدا بالنسبة لشركة مايكروسوفت لتغيير رأيها على الرغم من.

على النقيض من ذلك ، اعتبر أنه في C ++ مكرر هي القيمة التي تستخدم في المقام الأول للوصول إلى العناصر المتسلسلة في مجموعة. يمكن أن يكون متقدمًا ، ويتم استدعاؤه لاسترداد قيمة ، واختباره لمعرفة ما إذا كان قد تم الوصول إلى نهاية المجموعة.







enumeration