استفاده از Range ،Repeat و Empty در LINQ

یکشنبه 2 مهر 1396

در این مقاله ما نحوه استفاده از کلمات کلیدی Range، Repeat وEmpty را در LINQ دیده و تفاوت های آنها را شرح دهیم. همچنین در مورد Generation Operator نیز بحث خواهیم کرد.

استفاده از Range ،Repeat و Empty در LINQ

 اگر شما با #C کار کرده باشید قطعا با LINQ آشنا هستید چرا که مجموعه ای از روش های توسعه را برای شما فراهم میکند. در حالی که Select، Where، Any و سایر روشها بطور عمده شناخته شده هستند کلاس های استاتیک Enumerable سه method غیر پسوندی(non-extension) نیز به ما ارائه میکنند.

این به ما اجازه میدهد که بدون ایجاد لیست ها بصورت دستی و جمع آوری آنها با استفاده از حلقه نوعی توالی آرایه یا مجموعه را با استفاده از یک عبارت ساده ایجاد کنیم. در واقع به این معنی است که این methods یک توالی جدید ایجاد میکنند که interface مثل <T> IEnumerableبدون اینکه یک توالی مشابه پیش از آن ارائه شود implement شوند.

استفاده از Range

Range یک method استاتیک از کلاس Enumerable است و برای ایجاد مجموعه ای از اعداد دنباله دار استفاده میشود.

public static IEnumerable<int> Range(int start,int count)

Range فقط عدد صحیح را به عنوان پارامتر پذیرفته و شامل دو پارامتر است. در method فوق پارامتر اول نشاندهنده شروع عناصر از آن عدد صحیح است و پارامتر دوم طول دنباله را محدود میکند. اکنون با یک مثال ایده های بیشتری از قابلیت های آن خواهیم یافت.

IEnumerable < int > rangeSequence = Enumerable.Range(50, 8);  
Console.WriteLine("Total Count of Element / Index : " + rangeSequence.Count() + System.Environment.NewLine);  
for (int i = 0; i < rangeSequence.Count(); i++) {  
    Console.WriteLine("Value at index {0} : {1}", i, rangeSequence.ElementAtOrDefault(i));  
}  

خروجی کد

در نتیجه میبینید که مقدار دنباله از عنصر 50 آغاز و دنباله ای با 8 عنصر نمایش داده شده است. اکنون ما با range آشنا شده ایم. اکنون با مثال دیگری بیشتر با آن آشنا میشویم.

ما میخواهیم لیستی از 5 عدد اول را ببینیم و تعداد آیتم ها را با گام های خود در هر مرحله ضرب و نمایش دهیم.

var evens = Enumerable.Range(1, 5).Select(n => n * 2).ToList();  
foreach(var item in evens) {  
    Console.WriteLine("Even Number :" + item);  
}  

ما اکنون میتوانیم به طور مستقیم نتایج operator را به Tolist، Toarray، ToString یا Tolookup تبدیل کنیم. به عنوان مثال ما نتیجه را به list تبدیل کردیم.

نتیجه کد

شاید این سوال پیش بیاید که کد بالا چگونه کار؟
n=>n* 2 در واقع به صورت گام n ضرب در 2 (1*2,2*2,3*2,4*2,5*2) کار میکند. ما اشاره کردیم که عنصر شروع 1 است و باید 5 عنصر ایجاد شود. 

چگونه ما نتیجه integer را بصورت string میبینیم؟

IEnumerable < string > rangewithString = Enumerable.Range(1, 5).Select(i => (i * 10) + " " + OurLogic(i)).ToArray();  
foreach(var item in rangewithString) {  
    Console.WriteLine(item);  
}  
private static string OurLogic(int i) {  
    string result = string.Empty;  
    switch (i) {  
        case 1:  
            result = "1st";  
            break;  
        case 2:  
            result = "2nd";  
            break;  
        case 3:  
            result = "3rd";  
            break;  
        case 4:  
            result = "4th";  
            break;  
        case 5:  
            result = "5th";  
            break;  
    }  
    return result;  
}

نتیجه کد

در کد فوق دیدیم که چگونه یک action را در یک زمان مشخص تکرار کنیم. اکنون ما ایده روشنی از Range() داریم که برای تولید طیف وسیعی از اعداد integer  که از یک مقدار شروع و به تعداد مشخص تولید میشوند.

با این حال ما همواره در اعداد مثبت این عمل را انجام داده ایم اما اعداد منفی چگونه است؟

حالا Enumerable.Range از متد ArgumentOutOfRangeException  در صورتی که count منفی باشد یا start + count – 1 بزرگتر از int.MaxValue دور انداخته میشود.

استفاده از Repeat

متد Repeat برای تولید یک collection از نوع <T> Ienumerableبا تعداد مشخص است که همه مقادیر یک عنصر را دارا هستند.

public static IEnumerable < TResult > Repeat < TResult > (TResult element, int count)  

اولین پارامتر TResult element است که نشاندهنده مقداری است که تکرار میشود.
پارامتر دوم int count است که نشاندهنده تعداد دفعات تکرار عنص برای تکرار است. برای اینکه تصویر روشنی از این موضوع داشته باشید مثالی خواهیم زد.

IEnumerable<int> repeatColloction = Enumerable.Repeat<int>(10, 10);  
Console.WriteLine("Total Element Count: " + repeatColloction.Count());  
for (int i = 0; i < repeatColloction.Count(); i++)  
Console.WriteLine("Value at index {0} : {1}", i, repeatColloction.ElementAt(i));

خروجی کد

در اینجا میتوانید تعداد 10 عنصر را مشاهده نمایید که مقدار 10 را به عنوان پارامتر اولیه به آنها داده ایم و آن را 10 بار تکرار کرده ایم. اکنون ما همان method که برای Range استفاده کردیم بر روی تمام عناصر اعمال میکنیم.

IEnumerable < string > repeatwithString = Enumerable.Repeat(1, 5).Select(i => (i * 10) + " " + OurLogic(i)).ToArray();  
foreach(var item in repeatwithString) {  
    Console.WriteLine(item);  
}  
private static string OurLogic(int i) {  
    string result = string.Empty;  
    switch (i) {  
        case 1:  
            result = "1st";  
            break;  
        case 2:  
            result = "2nd";  
            break;  
        case 3:  
            result = "3rd";  
            break;  
        case 4:  
            result = "4th";  
            break;  
        case 5:  
            result = "5th";  
            break;  
    }  
    return result;  
}  

نتیجه کد

در اینجا مقدار (1*10) پنج بار بدست آمده  و نمایش داده میشود و متد OurLogic() برای توالی  هر عنصر است. باز هم ما جریان مثبت را دیده ایم جریان منفی در روش repeat چگونه است؟

IEnumerable<int> exceptionRepeat = Enumerable.Repeat(1, -3).ToList();

اکنون حالت استثنا را مشاهده کنید در متد Repeat زمانی که به ArgumentOutOfRangeException فرستاده میشود مقدار پارامتر دوم منفی است. حالا برای تولید یک توالی با مقدار تکراری ما تصویر روشنی از Repeat Method داریم.

استفاده از Empty

متد ()Empty فقط برای بازگرداندن یک collection خالی به یک نوع استفاده میشود.هیچ پارامتر استانداردی در این روش استفاده نمیشود ولی باید نوع T از نتیجه <T>IEnumerable باید ذکر شود.

public static IEnumerable<TResult> Empty<TResult>() 

Empty<TResult>() متد cache یک توالی خالی از نوع TResult است.

با یک مثال شروع میکنیم:

var emptystringCollection = Enumerable.Empty<string>();  
var emptyClass = Enumerable.Empty<TestClass>();  
Console.WriteLine("Count of String: {0} ", emptystringCollection.Count());  
Console.WriteLine("Type: {0} ", emptystringCollection.GetType().Name);  
Console.WriteLine("Count of TestClass: {0} ", emptyClass.Count());  
Console.WriteLine("Type: {0} ", emptyClass.GetType().Name);

نتیجه کد

از مزیت های اصلی empty این است که حتی اگر شما از آرایه یا لیست خالی استفاده نمایید آنها object هایی هستند که در حافظه ذخیره میشوند و Garbage Collector باید از آنها مراقبت کند. که این امر درواقع استفاده غیر ضروری از منابع است که در برنامه های بزرگ میتواند تاثیر قابل توجهی داشته باشد. Enumerable.Empty یک object در هر تماس ایجاد نمیکند بنابرین بارگذاری کمتری در GC خواهیم داشت.

تفاوت میان Range،  Repeat وEmpty 

آموزش سی شارپ

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 2k بازدید
  • 3 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید