C #: ienumerator في بيان باستخدام
-
06-09-2019 - |
سؤال
كنت فضولي لمعرفة كيف SingleOrFallback
تم تنفيذ الطريقة في morelinq. واكتشف شيئا لم أره من قبل:
public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
{
source.ThrowIfNull("source");
fallback.ThrowIfNull("fallback");
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return fallback();
}
T first = iterator.Current;
if (iterator.MoveNext())
{
throw new InvalidOperationException();
}
return first;
}
}
لماذا هو IEnumerator<T>
في using
بيان؟ هل هذا شيء يجب التفكير فيه عند استخدام foreach
على IEnumerable<T>
أيضا؟
سؤال جانبي: ماذا تفعل هذه الطريقة بالضبط؟ هل تقوم بإرجاع عنصر التراجع كلما كان التسلسل المصدر لا يحتوي على عنصر واحد بالضبط؟
المحلول
IEnumerator<T>
يمتد IDisposable
, ، وانت ايضا ينبغي لديك في بيان باستخدام. foreach
هل هذا تلقائيا. (غير عامة IEnumerator
لا تمديد IDisposable
لكن مترجم C # لا يزال يولد رمز للاتصال Dispose
مشروط. كان هذا أحد التغييرات (القليل) بين C # 1.0 و 1.2، حيث 1.2 هو الشحن الإصدار مع .NET 1.1، لسبب ما.)
ها هي مقال شرح لماذا هذا مهم في سياق كتل المؤتمر.
أما فيما يتعلق بالطريقة:
- إذا كان التسلسل فارغا، فقم بإرجاع عنصر الغطاء
- إذا كان التسلسل يحتوي على عنصر واحد بالضبط، فأعده
- إذا كان التسلسل يحتوي على أكثر من عنصر واحد، رمي استثناء
ملاحظة: من الجميل أن نرى Morelinq يحصل على بعض الاهتمام :)
نصائح أخرى
سيتصرف بعض العدادات بشكل سيء إذا لم يتم استدعاء التخلص منها؛ هذا صحيح تماما بالنسبة للأشخاص غير العامين مثل تلك العامة (يتطلب الأمراء غير العامين (لا يتطلب الأمر من الشفرة إما أن يكتب Duck-Type Dispose أو إلحاقا آخر إلى غير قابل للانهيار ثم اتصل ب Nonisable.Dispose). إنه أمر جيد كمسألة عادة لضمان التخلص من كائنات ienumerator؛ أود أن أعتبر أنه من الضروري صحيحة أي روتين يقبل نظام ienumerable من نوع غير معروف.