با سلام با یکی دیگر از آموزش های LINQ در C# در خدمت شما هستیم در این بخش قصد داریم Conversion operators را بررسی کنیم.
همان طور که از نام آن مشخص است از این اپراتور ها برای تبدیل انواع لیست و مجموعه به سایر اشیا استفاده می شود.
انواع اپراتور های conversion عبارت اند از:
TOLIST
TOARRAY
TOLOOKUP
CAST
ASENUMERABLE
ToDictionary
در جدول زیر خلاصه ای از کاربرد هر یک از اپراتور های conversion آورده شده است:
کاربرد | نام اپراتور |
این اپراتور یک مجموعه ای از داده ها را به لیست تبدیل می کند. | ToList |
این اپراتور یک مجموعه ای از داده ها را به آرایه تبدیل می کند. | ToArray |
توسط این اپراتور می توان محتویات یک مجموعه داده را به صورت Key و Element استخراج کرد. | ToLookup |
این اپراتور به نوعی عملیات Cast را انجام می دهد. | Cast |
از این اپراتور برای تبدیل داده ها به نوع Enumerable استفاده می شود. | AsEnumerable |
توسط این اپراتور می توان اطلاعات یک منبع داده را به صورت Key و Value استخراج کرد. | ToDictionary |
کاربرد این متد در تبدیل داده های یک منبع به نوع داده ی لیست است که الگوی استفاده از آن به صورت زیر است:
List<string> result = obj.ToList();
در بین <>
باید نوع داده ی اولیه که قرار است به لیست تبدیل شود قرار بگیرد. مثلا در این الگو فرض شده نوع داده obj
از نوع string
است.
به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace LINQExamples { class Program { static void Main(string[] args) { string[] countries = { "US", "UK", "India", "Russia", "China", "Australia", "Iran" }; List<string> result = countries.ToList(); foreach (string s in result) { Console.WriteLine(s); } Console.WriteLine("Type of countries: " + countries.GetType()); Console.WriteLine("Type of result: "+result.GetType()); Console.ReadLine(); } } }
در این مثال ساده یک آرایه از جنس string
تعریف شده که در ادامه با استفاده از متد ToList
قصد داریم آن را به لیست تبدیل کنیم بدیهی است که نوع داده ی result
لیستی با داده هایی از جنس string
خواهد بود.
به منظور اطمینان از انجام تبدیل با استفاده از متد GetType
نوع اشیای countries
و result
را در آخر چاپ نموده ایم که خروجی آن به صورت زیر است:
پیاده سازی کد به روش Query به صورت زیر است:
List<string> result = (from x in countries select x).ToList();
توجه: کاربرد اصلی این متد در مبحث LINQ to SQL و Entity Framework است، به همین منظور بررسی دقیق تر آن را به بعد موکول می کنیم.
این متد نیز اطلاعات گرفته شده از منبع داده را به آرایه تبدیل می کند که الگوی استفاده از آن به صورت زیر است:
string[] arrayname= obj.ToArray();
به نوع string[]
توجه کنید که به نوع obj
بستگی دارد. مثلا در این الگو فرض شده نوع داده ی obj
یک لیست با نوع داده ی string
است.
به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace LINQExamples { class Program { static void Main(string[] args) { List<int> num = new List<int> {1,2,3,4,5,6,7,8,9 }; int[] arraynum = num.ToArray(); foreach (int s in arraynum) { Console.WriteLine(s); } Console.WriteLine("Type of num: " + num.GetType()); Console.WriteLine("Type of arraynum: " + arraynum.GetType()); Console.ReadLine(); } } }
در این مثال یک لیست با نوع داده ی int
تعریف شده که با استفاده از متد ToArray
آن را به آرایه ای از نوع int
تبدیل کرده ایم. مانند مثال قبلی در این مثال نیز نوع هر دو شئ را در پایان چاپ کرده ایم.
روش Query:
int[] arraynum = (from m in num select m).ToArray();
توجه: کاربرد اصلی این متد در مبحث LINQ to SQL و Entity Eramework است، به همین منظور بررسی دقیق تر آن را به بعد موکول می کنیم.
با استفاده از این متد می توان به نوعی مقادیر یک منبع داده را به صورت Key و Element استخراج کرد. توضیح کاربرد این متد را در قالب مثال بررسی می کنیم.
به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace LINQExamples { class Program { static void Main(string[] args) { List<Employee> objEmployee = new List<Employee>() { new Employee(){ Name="Ashish Sharma", Department="Marketing", Country="India"}, new Employee(){ Name="John Smith", Department="IT", Country="Australia"}, new Employee(){ Name="Kim Jong", Department="Sales", Country="China"}, new Employee(){ Name="Marcia Adams", Department="HR", Country="USA"}, new Employee(){ Name="John Doe", Department="Operations", Country="Canada"} }; var emp = objEmployee.ToLookup(x => x.Department); Console.WriteLine("Grouping Employees by Department"); Console.WriteLine("---------------------------------"); foreach (var KeyValurPair in emp) { Console.WriteLine(KeyValurPair.Key); // Lookup employees by Department foreach (var item in emp[KeyValurPair.Key]) { Console.WriteLine("\t" + item.Name + "\t" + item.Country); } } Console.ReadLine(); } } class Employee { public string Name { get; set; } public string Department { get; set; } public string Country { get; set; } } }
یک لیست با نوع داده ی کلاس Employee
در اختیار داریم که با اعضایی مشخص پر شده است. توجه داشته باشید این کلاس دارای سه فید Name و Department و Country است، در این مثال قصد داریم هر شخص را بر اساس فیلد Department دسته بندی کنیم. حالا مراحل زیر را قدم به قدم انجام دهید:
کد بالا را بدون تغییر در IDE خود بنویسید و نشانگر موس را بر روی کلمه ی var
قرار دهید و به مقدار TKey
و TElement
دقت کنید، نوع TKey
که در این مثال از نوع string
است که در واقع همان نوع داده ی فیلد Department است که به صورت (ToLookup(x => x.Department
نوشته شده است. به نوع داده ی TElement
دقت کنید که از نوع کلاس Employee
است.
حالا نوبت به دسترسی به مقادیر Key و Element است. foreach
اول را در نظر بگیرید که نام شئ پیماشگر آن KeyValurPair
(دلخواه) انتخاب شده و به محض نوشتن آن اولین کلمه ای که برای آن پیشنهاد می شود Key
است، بنابراین با استفاده از کلمه ی Key
دقیقا به مقدار Key آن دسترسی پیدا می کنیم. حالا به foreach
دوم توجه کنید و موس را بر روی پیمایشگر حلقه نگه دارید تا مشاهده کنید که نوع آن در واقع کلاس Employee
است، پس برای دسترسی به مقدار Element به صورت [emp[KeyValurPair.Key
عمل می کنیم. در خط بعد نیز با استفاده از item
که به نوعی شئ از کلاس Employee
است به تمامی فیلد های آن دسترسی داریم برنامه را اجرا و خروجی را مشاهده کنید.
روش Query:
var emp = from y in objEmployee.ToLookup(x =>x.Department) select y;
برای آشنایی بیشتر با این متد به مثال دوم توجه کنید:
using System; using System.Linq; using System.Collections.Generic; namespace LINQExamples { class Program { static void Main(string[] args) { List<string> NumList = new List<string>() { "One","Two", "Three", "Four","Five", "Six", "seven" }; ILookup<int,string> Num = NumList.ToLookup(x =>x.Length); foreach (var item in Num) { Console.WriteLine("Length: "+item.Key); foreach (var item2 in Num[item.Key]) { Console.WriteLine("\t"+"The number: "+item2); } } Console.ReadKey(); } } }
هدف ما در این مثال ساده، دسته بندی کلمات موجود در لیست بر اساس طول رشته است.
به قسمت <ILookup<int,string
توجه کنید در این مثال تصمیم گرفتیم که به جای کلمه ی var
از نوع داده اصلی استفاده کنیم. توجه داشته باشید در این مثال جنس داده ی Key از نوع int
(طول رشته) و جنس داده ی Element از نوع string
(اعضای لیست) است. به طور کلی عملیاتی که در داخل متد ToLookup
انجام می پذیرد باعث دستیابی ما به Key می شود.
در این مثال بخصوص، مقدار Key برابر با طول رشته است و مقدار Element برابر با کلمات موجود در آرایه است. برای دستیابی به مقادیر key و Element در حلقه های موجود مانند مثال قبل عمل می کنیم. برنامه را اجرا و خروجی را مشاهده کنید.
روش Query:
ILookup<int, string> Num = (from z in NumList select z).ToLookup(x => x.Length);
کاربرد این متد برای تبدیل نوع داده ها استفاده می شود که عملیات تبدیل باید بر اساس قوانین خاصی صورت بگیرد وگرنه باعث پرتاب خطا خواهد شد.
الگوی استفاده از آن به صورت زیر است:
IEnumerable<string> result = obj.Cast<string>();
داده result
همیشه از نوع IEnumerable
خواهد بود و فقط لازم است نوع داده ی مقصد در متد Cast
و IEnumerable
در داخل <>
نوشته شود. لازم به ذکر است که متد Cast
هیچگونه پارامتر ورودی ندارد و فقط به صورت Generic استفاده می شود.
به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; using System.Collections; namespace LINQExamples { class Program { static void Main(string[] args) { List<Object> obj = new List<Object>(); obj.Add(2.25); obj.Add(4.3); obj.Add(7.3); obj.Add(13.75); IEnumerable<double> result = obj.Cast<double>(); foreach (var item in result) { Console.WriteLine(item); } Console.WriteLine(obj.GetType()); Console.WriteLine(result.GetType()); Console.ReadLine(); } } }
نوع اطلاعات موجود در List
همگی از نوع Object
هستند. هدف ما در این مثال تبدیل Object
به double
است که این کار توسط متد Cast
انجام خواهد شد.
روش Query:
IEnumerable<double> result = from x in obj.Cast<double>() select x;
از این متد برای تبدیل داده ها به Enumerable استفاده می شود که الگوی استفاده از آن به صورت زیر است:
var result = Objname.AsEnumerable();
متد AsEnumerable
پارامتر ورودی ندارد و کاربرد آن بسیار ساده است. به مثال زیر توجه کنید:
using System; using System.Linq; using System.Collections.Generic; using System.Collections; namespace LINQExamples { class Program { static void Main(string[] args) { string[] array = new string[] {"Name","Lastname","Email","Password" }; IEnumerable result = array.AsEnumerable(); foreach (var number in result) { Console.WriteLine(number); } Console.ReadLine(); } } }
در این مثال یک آرایه string
در اختیار داریم که با استفاده از متد AsEnumerable
آن را به نوع IEnumerable
تبدیل کرده ایم. خروجی این کد همان اعضای آرایه است فقط نوع دستیابی به آن ها متفاوت است.
اگر با کلاس Dictionary
در C# آشنایی داشته باشید می دانید که این کلاس توانایی ایجاد Key های یکتا برای مقادیر مختلف را دارد. کاربرد متد ToDictionary
دقیقا به همین منظور است. اجازه دهید توضیحات این متد مهم را بر روی یک مثال بررسی کنیم.
مثال:
using System; using System.Linq; using System.Collections.Generic; using System.Collections; namespace LINQExamples { class Program { static void Main(string[] args) { List<Student> objStudent = new List<Student>() { new Student() { Id=1,Name = "Suresh Dasari", Gender = "Male",Location="Chennai" }, new Student() { Id=2,Name = "Rohini Alavala", Gender = "Female", Location="Chennai" }, new Student() { Id=3,Name = "Praveen Alavala", Gender = "Male",Location="Bangalore" }, new Student() { Id=4,Name = "Sateesh Alavala", Gender = "Male", Location ="Vizag"}, new Student() { Id=5,Name = "Madhav Sai", Gender = "Male", Location="Nagpur"} }; Dictionary<int,string> result= objStudent.ToDictionary(x => x.Id, x => x.Name); foreach (var stud in student) { Console.WriteLine(stud.Key + "\t" + stud.Value); } Console.ReadLine(); } } class Student { public int Id { get; set; } public string Name { get; set; } public string Gender { get; set; } public string Location { get; set; } } }
در ابتدا یک لیست با نوع داده ی کلاس Student
در اختیار داریم که با مقادیر مناسب و با توجه به Property های کلاس Student
آن را پر کرده ایم. هدف اصلی ما در این مثال قرار دادن فیلد ID
به عنوان Key و فیلد Name
به عنوان Value است.
توجه داشته باشید نوع دو فیلد مذکور به ترتیب int
و string
است به همین خاطر نوع داده ی result
به صورت <Dictionary<int,string
تعریف شده است. اگر نشانگر موس را بر روی Dictionary نگه دارید، خواهید دید که مقدار اول قرار گرفته شده در <,>
حکم Key را دارد و مقدار دوم Value است.
در مرحله ی بعد توسط شئ objStudent
متد ToDictionary
را فراخوانی می کنیم. در این مثال قصد داشتیم ID
را به عنوان Key انتخاب کنیم به همین دلیل در جایگاه پارامتر اول قرار می گیرد و بعد از آن مقدار Value باید قرار بگیرد. برای چاپ مقادیر کافی است با استفاده از یک حلقه به مقادیر Key و Value دست پیدا کنیم و آن ها را در خروجی چاپ کنیم. کد را اجرا و خروجی آن را مشاهده کنید.
روش Query:
Dictionary<int, string> result = (from x in objStudent select x).ToDictionary(x => x.Id, x => x.Name);
حالا سعی کنید در کد بالا تغییرات زیر را انجام دهید:
Dictionary<string, string> result = (from x in objStudent select x).ToDictionary(x => x.Location, x => x.Name);
برنامه را اجرا و خطای آن را بررسی کنید. همان طور که می دانید مقدار Key حتما باید یکتا باشد. در این مورد فیلد Location
به عنوان Key در نظر گرفته شد در حالی که مقادیر آن دارای تکرار است به همین دلیل اجرای برنامه با خطا همراه می شود اما در مورد Value این قضیه صحت ندارد و با وجود مقادیر تکراری برنامه بدون خطا اجرا خواهد شد.
این بخش از آموزش هم به پایان رسید توجه داشته باشید دو متد ToDictionary
و ToLookup
بسیار کاربردی و مهم هستند پس لازم است با استفاده از آن ها مثال های بیشتری حل کنید چون در مبحث LINQ to SQL بسیار کاربردی خواهد بود. تعداد کمی از متد های پایه در مبحث LINQ باقی مانده است که در جلسه بعدی مهم ترین و کاربردی ترین آن ها را بررسی خواهیم کرد.
موفق باشید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.