سؤال

بصرف النظر عن (IEnumerable Returns GetEnumerator() ، يعد IEnumerble ضروريًا لـ "foreach")

تسمح لنا الطريقتان التاليتان تقريبًا بالتكرار على المجموعة

ميزة واحد على الآخر؟

static void Main()
{
    IEnumerator<int> em = MyEnumerator<int>(new int[] { 1, 2, 3, 4 });
    IEnumerator<int> e = Collection<int>
                        (new int[] { 1, 2, 3, 4 }).GetEnumerator();

    while (em.MoveNext())
    {
        Console.WriteLine(em.Current);
    }

    while (e.MoveNext())
    {
        Console.WriteLine(e.Current);
    }
    Console.ReadKey(true);
}

النهج 1

 public static IEnumerator<T> MyEnumerator<T>(T[] vals )

 {
     T[] some = vals;

     foreach (var v in some)
     {
       yield return v;
     }
}

النهج 2

public static IEnumerable<T> Collection<T>(T[] vals)
     {
         T[] some = vals;

         foreach (var v in some)
         {
             yield return v;
         }
     }
هل كانت مفيدة؟

المحلول

والفرق الرئيسي هو أن معظم واجهات برمجة التطبيقات (API) تدعم إدخال IEnumerable<T> ولكن ليس من IEnumerator<T>.

عليك أيضًا أن تتذكر استدعاء Reset() عند استخدامه بينما يكون بناء الجملة أكثر وضوحًا في IEnumerable<T> (اتصل وحسب GetEnumerator مرة أخرى).راجع أيضًا تعليق إريك ليبر حول كون إعادة التعيين فكرة سيئة؛إذا لم يتم تنفيذ إعادة التعيين في ملفك IEnumerator<T> أو أنه أصبح عدادًا لمرة واحدة فقط (عديم الفائدة جدًا في كثير من الحالات).

قد يكون الاختلاف الآخر هو أنه يمكن أن يكون لديك IEnumerable<T> التي يمكن تعدادها من عدة سلاسل رسائل في نفس الوقت ولكن IEnumerator<T> قم بتخزين موضع واحد في البيانات المذكورة (تخيل أ RandomEnumerable أو RangeEnumerable).

لذا فإن الاستنتاج هو ذلك IEnumerable<T> أكثر تنوعًا، ولكن على أي حال إذا كان لديك وظيفة ترجع ملف IEnumerator<T> توليد IEnumerable<T> من حوله بسيط.

class EnumeratorWrapper<T> : IEnumerable<T>
{
    Func<IEnumerator<T>> m_generator;
    public EnumeratorWrapper(Func<IEnumerator<T>> generator)
    {
        m_generator = generator;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return m_generator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return m_generator();
    }
}

فقط من أجل تناسق واجهة برمجة التطبيقات (API) باستخدام IEnumerable<T> يبدو الحل الأفضل بالنسبة لي.

لكن المشكلة مع Reset() في IEnumerator<T> اجعله حلاً غير قابل للاستخدام على أي حال، لذلك IEnumerable<T> هو الطريق للذهاب.

نصائح أخرى

صححني إذا كنت مخطئًا ولكن الفرق الوحيد هو الفرق بين IEnumerable و IEnumerator وبما أنك قلت على وجه التحديد أنك لا تسأل عن الفرق، فكلاهما جيد ...

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