PDA

نسخه کامل مشاهده نسخه کامل : شبیه سازی ساده نوع داده برگشتی در سی شارپ



Life24
02-04-2018, 03:31
با سلام،
ما در این فرصت عید چند تا سول پرسیدیم و مزاحم دوستان شدیم . :n40:
من نمیفهمم این نوع داده برگشتی چجور هست؟ درسته میشه با var از دست این موضوع خلاص شد اما دو دلیل داشت. یکی بفهمیم پشت پرده چه خبر هست و این قضیه جور پیاده شده و دیگری اگر بخواهیم این داده رو برای متد یا کلاس دیگر بفرستیم با var امکان نداشت و نوع داده مشخص رو نیاز داره.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
یا مثلا

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


یعنی میشه این قطعه کد ساده رو که نوشتم لطفا اصلاحش کنید تا درک کنیم نوع داده برگشتی به شکل بالا چگونه پیاده سازی شده...ممنون
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

_H2_
03-04-2018, 10:35
سلام
نمیدانم، منظورتان را از بخش کدهای قسمت انتهایی سوال تان متوجه نشدم، یعنی درکل مشکل تان با 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 آن:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

امیدوارم با تحلیل و بازخوانی و دقت در کدهای فوق به جواب هایتان برسید.
اگر بطور کل مسئله و سوال تان چیز دیگری بوده، بیشتر توضیح دهید که منظور تان چیست.
موفق باشید.