سلام
نمیدانم، منظورتان را از بخش کدهای قسمت انتهایی سوال تان متوجه نشدم، یعنی درکل مشکل تان با IEnumerable ها است؟
توضیحاتی میدهم، ببینید کافی است یا نه...
جفت واسط IEnumerable و IEnumerator پشتیبانی (پارتی بازی!) های خاصی در دات نت دارند.
یکی از این موارد حلقه foreach است.
درواقع کلمه کلیدی foreach فقط روی اشیایی که IEnumerable دارند، کار میکند.
کلمه کلیدی پارتی بازی دیگر yield است که امکان پیاده سازی(implementing) سریع و ساده دو واسط فوق را میدهد.
ولی امکان پیاده سازی عادی و طبق روش معمول این واسط ها هم وجود دارد.
اول به تعریف دو واسط IEnumerable و IEnumerator دقت کنید.
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
واسط اصلی IEnumerable فقط تولیدکننده/سازنده/newکننده IEnumerator است.
(فکر کنید ببینید چرا برای این کار به دو واسط نیاز داریم؟!)
واسط دوم IEnumerator یک شمارنده است/یک کرسر/یک مکان نما به موقعیت خاصی در یک فهرست...
هربار MoveNext میکنید و عنصر بعدی را در Current تحویل میگیرید.
با تفکر MoveNext ای هم میتوان فهرست های ایندکسی و آرایه را پیمایش کرد و هم فهرست های پیوندی که هیچ ایندکسی ندارند، حتی خوانش های دیتابیس (fetch) کافی است بتوان داده ها را یکی یکی پیمایش کرد...
دقیق تر به تعریف واسط دقت کنید، پیچیده نیست، نگاه کنید متوجه میشود، اصول ساده ای دارد و در عین حال قدرتمند است.
برای درک IEnumerable شاید بهتر باشد پارتی بازی هایی که گفتیم را حذف کنیم...
مرحله دوم اجازه دهید پخش ساده تر را بازکنیم، اجازه دهید ببینیم foreach عزیز ، واقعاً به چه چیز تبدیل میشود.
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
درقسمت سوم بیایید خود پیاده سازی دو واسط را دستی و با کدهای عادی انجام دهیم.
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
دونکته در کد فوق وجود دارد...
اول آنکه در کل کد مسخره ای است! چون خود آرایه ها واسط IEnumerable را دارند! این یک جور دوباره کاری بی منطق است.
دوم آنکه برای کم کردن کدهای اضافه و شفافیت بیشتر از نسخه غیر جنریک استفاده کردم.
و اما کد معادل دو سه خط فوق بدون پارتی بازی yield ...
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر درست دقت کنید، متوجه میشوید، چطور حلقه for دستور قبلی در ذات MyEnumerator شکسته شده.
و یک مثال دیگر، بیایید تابع Where در Linq را خودمان بنویسیم.
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
و بدون yield آن:
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
امیدوارم با تحلیل و بازخوانی و دقت در کدهای فوق به جواب هایتان برسید.
اگر بطور کل مسئله و سوال تان چیز دیگری بوده، بیشتر توضیح دهید که منظور تان چیست.
موفق باشید.