فرض کنید در حال کدنویسی هستید و قصد دارید تا در یک تابع یک لیست کاملی را برگشت دهید، در این صورت حتما از کلمه کلیدی "return" برای این کار استفاده خواهید کرد. قطعه کد زیر را در نظر داشته باشید:
public static List<Book> FetchBookList()
{
var list = new List<Book>();
list.Add(new Book() { Title = "C# How to Program", Price = 19.99F});
list.Add(new Book() { Title = "Machine Learning with Python", Price = 22.99F });
list.Add(new Book() { Title = "Python for AI", Price = 13.99F });
list.Add(new Book() { Title = "Javascript tutorial", Price = 16.99F });
return list;
}
در کد بالا متغیر list شامل 4 شی از نوع Book هستند که 2 خصیصه (Property) با نام های Title و Price دارد. در آخر، کل این لیست با سینتکس return برگشت داده میشود. البته ساخته شدن list بالا چند میلی ثانیه بیشتر طول نمیکشد. تصور کنید لیست برگشتی شامل هزاران آبجکت است که قرار است از دیتابیس خوانده شود و یا از اینترنت دانلود شود، در این صورت منتظر ماندن برای تکمیل شدن لیست ممکن است برای استفادهکنندگان برنامه نوشته شده آزاردهنده باشد، در این موارد استفاده از yield بهکارمان میآید.
به طور خلاصه با استفاده از yield میتوان به انجام پیمایش یا Iteration بهصورت Stateful بر روی یک Collection پرداخت. در yield، بهمحض ساخته شدن یک آیتم میتوان آن را برگشت داد یا به اصطلاح، آیتمها را از تولید به مصرف رساند. کد نوشته شده در بالا بهوسیله yield به صورت زیر بازنویسی میشود:
public static IEnumerable<Book> FetchBookListWithYield()
{
var _list = new List<Book>();
yield return new Book() { Title = "C# How to Program", Price = 19.99F };
yield return new Book() { Title = "Machine Learning with Python", Price = 22.99F };
yield return new Book() { Title = "Python for AI", Price = 13.99F };
yield return new Book() { Title = "Javascript tutorial", Price = 16.99F };
}
دقت داشته باشید که بهجای استفاده از List<Book> از IEnumerable<Book> استفاده شده است، همچنین خبری از برگشت دادن یک لیست نیست. در این کد بهازای ساخته شدن هر آبجکت از نوع Book، یک برگشت صورت میپذیرد. با توجه به اینکه خروجی از نوع IEnumerable است، از تابع نوشته شده در بالا میتوان به صورت زیر در برنامه استفاده کرد:
static void Main(string[] args)
{
foreach (Book book in FechBookListWithYield())
{
Console.Write(book.Title + " " + book.Price + "\n");
}
// output
// C# How to Program 19.99
// Machine Learning with Python 22.99
// Python for AI 13.99
// Javascript tutorial 16.99
Console.ReadKey();
}
مثالی دیگر از yield در زبان سی شارپ
در این قسمت میخواهیم یک مثال دیگری از کاربرد yield return را بررسی کنیم. کد زیر را در نظر بگیرید:
public static IEnumerable<int> Multiply(int number, int range)
{
int result = 1;
for (int i = 1; i range; i++)
{
result = result * number;
yield return result;
}
}
static void Main(string[] args)
{
foreach(int i in Multiply(2, 15))
{
Console.Write("{0} ", i);
}
Console.ReadKey();
// output
// 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
}
در این کد، تابع Multiply یک عدد (Number) و یک دامنه (Range) گرفته و به تعداد دامنه، عدد را به طور متوالی با خودش ضرب میکند؛ بعد از انجام هر ضرب با مقدار قبلی تابع، نتیجه که در متغیر result ذخیره شده است را yield return میکند تا در منطق برنامه بتوان از آن استفاده کرد. نکته حائز اهمیت در این برنامه، توانایی استفاده از مقادیر ساخته شده، قبل از ساخته شدن عددهای جدید میباشد، بهعنوان مثال قبل از ایجاد شدن عدد 16384، عدد 8192 برگشت داده میشود.
دوره برنامه نویسی سی شارپ
نمونه فیلمهایی از جلسات برنامه نویسی سی شارپ
نکاتی پیرامون yield در C#
هنگام استفاده از yield return در سی شارپ موارد زیر را بهخاطر داشته باشید:
- از کلیدواژه ref و out در تعریف پارامترهای متد و خصیصهها نمیتوان استفاده کرد.
- عبارت yield میتواند به دو صورت yield return و yield break تعریف شود.
- توابعی که از yield استفاده میکنند باید مقدار برگشتی یا Return Type آنها از نوع IEnumerable یا IEnumerator باشد.
- در زبان C#، از عبارت yield return میتوان در داخل بلاک try درون try-finally نیز استفاده کرد اما نمیتوان در داخل try-catch از آن استفاده کرد.
- از عبارت yield return نمیتوان درون متدهای بینام یا Anonymous Methodها و همچنین داخل Unsafe Blockها استفاده کرد.
- از yield break میتوان در بلوکهای Try-Catch استفاده کرد اما در بلوک finally خیر.
نمونه فیلمهای دورههای مهارتی
جمعبندی
در این مقاله به بررسی مفهوم کلمه کلیدی yield در زبان برنامه نویسی C# با ذکر چند نمونه مثال پرداختیم، همچنین نکاتی را که هنگام برنامهنویسی و استفاده از yield return باید در نظر داشته باشید نیز گردآوری شده و در پایان مقاله نوشته شده است.
چرا از yield return در سی شارپ استفاده کنیم؟
هنگام استفاده از عبارت "yield return" در داخل یک حلقه، نیازی نیست یک مجموعه موقت برای ذخیره دادهها قبل از Return کردن ایجاد کنید.
تفاوت بین return و yield در سی شارپ چیست؟
yield return متفاوت از دستور return عادی است، زیرا در حالی که مقداری را از تابع برمیگرداند، "Book" را روی آن تابع نمیبندد.