سوف C# الاستفادة من الفروق بين أنواع التعداد ، مثل C++ التكرار?

StackOverflow https://stackoverflow.com/questions/1634934

  •  06-07-2019
  •  | 
  •  

سؤال

لقد تم التفكير في IEnumerator.Reset() الأسلوب.قرأت في وثائق MSDN أن هناك COM إمكانية التشغيل المتداخل.C++ مبرمج يبدو لي وكأنه IEnumerator الذي يدعم Reset هو ما يمكن أن أسميه إلى الأمام مكرر, بينما IEnumerator والتي لا تدعم Reset هو حقا إدخال مكرر.

حتى الجزء الأول من السؤال هو هل هذا الفهم صحيح ؟

الجزء الثاني من سؤالي هو هل سيكون من أي فائدة في C# إذا كان هناك تمييز بين المدخلات التكرار و إلى الأمام التكرار (أو "التعداد" إذا كنت تفضل ذلك)?فإنه لا تساعد في القضاء على بعض الارتباك بين المبرمجين ، مثل تلك الموجودة في هذه حتى السؤال عن الاستنساخ التكرار?

تحرير:توضيح إلى الأمام الإدخال التكرار.إدخال مكرر فقط الضمانات التي يمكن أن تعداد أعضاء مجموعة (أو من وظيفة مولد أو تيار الإدخال) مرة واحدة فقط.هذا هو بالضبط كيف IEnumerator يعمل في C#.ما إذا كان أو لا يمكن تعداد مرة ثانية ، يتم تحديد ما إذا كان أو لا Reset معتمد.إلى الأمام التكرار لا يكون هذا التقييد.يمكن تعداد أكثر من الأعضاء في كثير من الأحيان كما تريد.

بعض C# المبرمجين لا underestand السبب IEnumerator لا يمكن أن تستخدم بشكل موثوق في smartbase الخوارزمية.النظر في الحالة التالية:

void PrintContents(IEnumerator<int> xs)
{
  while (iter.MoveNext())
    Console.WriteLine(iter.Current); 
  iter.Reset();
  while (iter.MoveNext())
    Console.WriteLine(iter.Current); 
}

إذا نحن ندعو PrintContents في هذا السياق, لا مشكلة:

List<int> ys = new List<int>() { 1, 2, 3 }
PrintContents(ys.GetEnumerator()); 

ومع ذلك ننظر في ما يلي:

IEnumerable<int> GenerateInts() {   
  System.Random rnd = new System.Random();
  for (int i=0; i < 10; ++i)
    yield return Rnd.Next();
}

PrintContents(GenerateInts());

إذا كان IEnumerator دعم Reset, وبعبارة أخرى دعم متعدد تمر الخوارزميات ، ثم في كل مرة يتحرك على جمع ستكون مختلفة.هذا من شأنه أن يكون غير مرغوب فيه ، لأنه سيكون من المستغرب السلوك.هذا المثال هو قليلا مزورة ، ولكن ذلك لا يحدث في العالم الحقيقي (على سبيل المثالالقراءة من ملف تيارات).

هل كانت مفيدة؟

المحلول

مسألة مثيرة للاهتمام.اعتقد أن من دورة C# هل فائدة.ومع ذلك ، فإنه لن يكون من السهل إضافة.

التمييز موجود في C++ لأنها أكثر مرونة نوع النظام.في C#, لم يكن لديك قوية عامة طريقة استنساخ الكائنات ، وهو أمر ضروري لتمثيل إلى الأمام التكرار (دعم متعددة تمرير التكرار).وبطبيعة الحال على هذا أن تكون مفيدة حقا, سوف تحتاج أيضا إلى دعم ثنائي الاتجاه و الوصول العشوائي التكرار/التعداد.و للحصول على كل منهم يعمل بسلاسة, انت حقا تحتاج إلى نوع من البط-كتابة مثل C++ القوالب.

في نهاية المطاف نطاقات من اثنين من المفاهيم مختلفة.

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

في C#, عدادات ليس من المفترض أن تفعل الكثير جدا.في نهاية المطاف هم فقط مصممة لتمكنك من تشغيل من خلال التسلسل الخطي الطريقة.

أما بالنسبة Reset(), فمن المقبول على نطاق واسع أنه كان من الخطأ أن إضافة ذلك في المقام الأول.لو نجحت و تم تنفيذها بشكل صحيح ثم يمكنك أن تقول الخاصة بك العداد مماثلة إلى الأمام التكرار ، ولكن بشكل عام من الأفضل أن نتجاهل أنها خطأ.ثم جميع عدادات مماثلة فقط إلى إدخال التكرار.

للأسف.

نصائح أخرى

Reset كان خطأ كبيرا.أدعو الاشكالات على Reset.في رأيي, الطريقة الصحيحة للتفكير التمييز تقومون بين "إلى الأمام التكرار" و "إدخال التكرار" في .صافي نوع نظام التمييز بين IEnumerable<T> و IEnumerator<T>.

انظر أيضا هذا الجواب, حيث مايكروسوفت إريك ليبرت (غير رسمي باستغلال لا شك وجهة نظري فقط أنه شخص مع مزيد من التفويض من يجب أن تجعل الادعاء بأن هذا كان خطأ تصميم) يجعل نقطة مماثلة في التعليقات.أيضا انظر أيضا له بلوق رهيبة.

قادمة من C# منظور:

كنت تقريبا لم تستخدم IEnumerator مباشرة.عادة ما كنت تفعل foreach البيان الذي يتوقع IEnumerable.

IEnumerable _myCollection;
...
foreach (var item in _myCollection) { /* Do something */ }

لا تمر حول IEnumerator إما.إذا كنت ترغب في اجتياز جمع الذي يحتاج إلى التكرار ، يمكنك تمرير IEnumerable.منذ IEnumerable لديه وظيفة واحدة ، والتي ترجع IEnumerator, ، ويمكن استخدامه تكرار جمع عدة مرات (متعددة يمر).

هناك حاجة Reset() الدالة على IEnumerator لأنه إذا كنت تريد أن تبدأ من جديد, كنت مجرد رمي بعيدا القديم (المهملة) والحصول على واحدة جديدة.

على .NET framework سوف تستفيد كثيرا إذا كانت هناك وسيلة تسأل IEnumerator<T> حول ما القدرات التي يمكن أن تدعم ما الوعود التي يمكن أن تجعل.هذه الميزات قد تكون مفيدة أيضا في IEnumerable<T>, ولكن أن تكون قادرة على طرح الأسئلة من العداد تسمح التعليمات البرمجية التي يمكن أن تتلقى العداد من أغلفة مثل ReadOnlyCollection استخدام الأساسية جمع في تحسين الطرق دون الحاجة إلى إشراك المجمع.

أي العداد عن المجموعة التي هي قادرة على أن تكون المذكورة في مجملها و ليست كبيرة جدا, واحد يمكن أن تنتج من ذلك IEnumerable<T> التي من شأنها أن تسفر دائما نفس تسلسل البنود (على وجه التحديد مجموعة من البنود المتبقية في العداد) من خلال قراءة كامل المحتوى إلى مجموعة والتخلص منها ونبذ العداد و الحصول على العدادين من مجموعة (باستخدام ذلك في المكان الأصلي تخلى العداد), التفاف مجموعة في ReadOnlyCollection<T>, ويعود ذلك.على الرغم من أن هذا النهج سوف تعمل مع أي نوع من enumerable جمع تلبية المعايير المذكورة أعلاه ، سيكون فظيعة غير فعالة مع معظمهم.وجود وسائل يسأل العداد تسفر عن باقي محتويات غير قابل للتغيير IEnumerable<T> تسمح العديد من أنواع عدادات أداء أشار إلى العمل بشكل أكثر كفاءة.

أنا لا أعتقد ذلك.أسميه IEnumerable إلى الأمام مكرر و إدخال مكرر.فإنه لا يسمح لك أن تذهب إلى الوراء ، أو تعديل الأساسية جمع.مع إضافة foreach الكلمة التكرار تقريبا غير فكر أكثر من مرة.

الرأي:الفرق بين المدخلات التكرار (على كل واحد) مقابلإخراج التكرار (لا شيء إلى كل واحد) هو تافهة جدا لتبرير إضافة إلى الإطار.أيضا ، من أجل القيام الناتج مكرر, سوف تحتاج إلى تمرير تفويض مكرر.إدخال مكرر يبدو أكثر طبيعية C# المبرمجين.

هناك أيضا IList<T> إذا كان مبرمج يريد الوصول العشوائي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top