مقدمه‌ای بر LINQ

رفتار خاص متدهای کلاس

در نسخه C#3 ویژگی جدیدی به نام Extension Method اضافه شد، که با استفاده از آن می‌توان برای یک کلاس یک متد توسعه داده شده تعریف کرد، فرض کنید کلاسی از پیش نوشته شده و قصد داریم این کلاس، رفتاری خاص از خود نشان دهد، ولی از طرفی به کد کلاس نیز دسترسی نداریم، آن وقت است که این ویژگی به کمک‌مان می‌آید.
کد خبر: ۳۸۷۱۹۲

برای تعریف یک متد توسعه داده باید یک کلاس static و سپس در آن متد خود که static هم باید باشد، تعریف کنیم. پارامتر اول این متد با کلمه کلیدی this شروع می‌شود و به کلاسی که قرار است این متد به آن اضافه شود، ارجاع داده می‌شود، مانند این کد:

public static iExtension{

public static void ToDo(this string param){

}

}

همان‌طور که از کد داده شده مشخص است، این کد یک متد به نام ToDo به آن اضافه می‌کند. همین قابلیت به کمک LINQ آمده تا بتوان با آن راحت‌تر کار کرد. LINQ روی یک مجموعه داده فعالیت می‌کند. ما می‌دانیم که تمامی‌مجموعه‌های داده در دات نت. اینترفیس «IEnumerable«T» را پیاده کردند، (T نوع داده را مشخص می‌کند مثلا «IEnumerable«int)، پس می‌توانیم بگوییم که هر متدی که برای این اینترفیس به صورت متد افزوده تعریف شود، می‌تواند روی همه مجموعه‌های داده‌ای کاربرد داشته باشد.

برنامه‌نویسان دات‌نت تعدادی متد را برای این اینترفیس پیاده کردند و ما قصد داریم چندتا از آنها را بررسی کنیم. به این متدها اصطلاحا «عملگرهای جستجو» (Query Operators) می‌گویند. اولین عملگری که قصد داریم آن را بررسی کنیم where نام دارد و شکل کلی آن به صورت زیر است:

public static IEnumerable«T» Where«T»(

this IEnumerable«T» source,

Func«T, bool» predicate);

به عملگر Func توجه کنید. Func یک delegate است و یک متد را نشان می‌دهد که یک T می‌گیرد (T به نوع داده‌های ذخیره شده در source اشاره می‌کند) و یک مقدار bool را به صورت زیر برمی‌گرداند:

public bool Check(T type) {

return type is string};

این متد مشخص می‌کند که type از نوع string است یا خیر. می‌توان اشاره‌گر این تابع را به predicate در عملگرwhere داد، در نتیجه کدی به صورت زیر نوشته می‌شود:

Func«string,bool» checker =

Check;

string[] names = {«a»,»b»};

names.Where(checker);

کد تولید شده کمی حالت پیچیده به خود گرفته است، برنامه‌نویس‌های دات‌نت فکر اینجا را هم کرده‌اند و این امکان را به ما داده‌اند که بتوانیم کد ساده‌تری بنویسیم. می‌توان کد بالا را با استفاده از عبارت لامبدا بازنویسی کرد:

string[] names = {«a»,»b»};

names.Where(name =» name is string);

همان‌طور که می‌بینیم کد به مراتب کوچک‌تری به دست آمد. حال متوجه شدیم که عملگر where دقیقا چه کاری انجام می‌دهد، یک شرط را برای یک مجموعه اعمال می‌کند و داده‌هایی که در این شرط صدق می‌کنند را برمی‌گرداند:

عملگر بعدی Select نام دارد و تعریف آن به این صورت است:

public static IEnumerable«S» Select«T, S»(

this IEnumerable«T» source,

Func«T, S» selector);

این عملگر تقریبا شبیه به where است، ولی با این تفاوت که این عملگر روی داده‌هایی از نوع T اعمال می‌شود و مجموعه‌ای از نوع S برمی‌گرداند.

توجه داشته باشید که S هر مقداری می‌تواند داشته باشد، باز برمی‌گردیم به یک ویژگی جدید در C#3.0 به نام Anonymous Type یعنی داده‌هایی که در یک لحظه به وجود می‌آیند و هیچ ساختار مشخصی ندارند، بلکه نشان دهنده یک مدل دیتا هستند. این نوع داده در حین اجرا به وجود می‌آید. به مثال زیر توجه کنید:

names.Select(name=»new { Name = name});

این کد بــــرای هر عضو از مجمـــــوعه names یک Anonymous type برمی‌گرداند، این نوع کلاسی شامل یک ویژگی به نام Name است، اما ما این نوع داده را نمی‌شناسیم پس چگونه باید به کامپایلر بگوییم نوع داده چیست؟ برای این کار از کلمه کلیدی var به این صورت استفاده می‌کنیم:

var res = names.Select(name=»new { Name = name });

عملگر بعدی که قصد داریم آن را توضیح دهیم OrderBy است:

public static IOrderedSequence«T» OrderBy«T, K»(

this IEnumerable«T» source,

Func«T, K» keySelector);

این عملگر داده‌هایی از نوع T را بر اساس متد K صورت می‌کند، مانند مثال زیر:

names.OrderBy(name=»name);

امیربهاالدین سبط‌الشیخ

newsQrCode
ارسال نظرات در انتظار بررسی: ۰ انتشار یافته: ۰

نیازمندی ها