מדריך C# | שימוש ב LINQ

אחד הדברים שאנחנו המתכנתים נתקלים בהם באופן כמעט יומיומי הוא השימוש ברשימות ומערכים.
מה שמשותף למערכים רשימות ועוד אובייקטים שמסודרים יחדיו אחד אחרי השני הוא שכולם מממשים את ממשק IEnumerable

*תנאי קדם למדריך: היכרות עם #C בסיסי ועם Lists.

מה זה IEnummerable

IEnummerable הוא interface בסיסי ונפוץ מאוד.
מימוש IEnumeable מאפשר לנו לעבור על איברי האובייקט שלנו, לסדר אותם, לסנן אותם או סתם לדלות מהם מידע.

דוגמה טובה פשוטה ונפוצה למימוש של IEnummerable היא המחלקה List.

מה ההבדל בין IEnummerable ל List?

בכדי שנבין את ההבדל בין השניים חשוב שנבין מה כל אחד נותן לנו ומתי נרצה להשתמש בכל אחד.

שני ההבדלים העיקריים:
  1. IEnummerable הוא ממשק ולכן לא ניתן ליצור ממנו עצם.
  2. IEnummerable הוא Read-Only - הכוונה, לא ניתן לבצע פעולות על הרשימה כל עוד היא IEnummerable.
דוגמה טובה לכך תהיה ליצור List מסוג IEnummerable ולנסות להוסיף אליו איבר:
IEnumerable<Person> persons = new List<Person>
                { new Person("Tomer", 22), new Person("Alon", 25), new Person("Shimon", 40) };
persons.Add(new Person("Asaf", 15));

נקבל שגיאת קומפילציה משום שממשק IEnummerable אינו מכיר את הפעולה Add (כי הוא read-only כמובן)

אך אם נמיר את persons שיצרנו ל List לערוך את ערכיו ולהוסיף להם כרצוננו.

List<Person> personsList = persons.ToList();
personsList.Add(new Person("Asaf", 15));

במילים אחרות, נשתמש ב IEnummerable בעיקר כאשר איננו רוצים לשנות את תוכן הרשימה אלא רק לגשת אליו.

מה זה foreach?

foreach היא לולאה המאפשרת לנו לעבור בין אברי ה IEnummerable שלנו ולבצע עליהם פעולות.

נחזור לדוגמת persons:
IEnumerable<Person> persons = new List<Person>
                { new Person("Tomer", 22), new Person("Alon", 25), new Person("Shimon", 40) };

לאחר שיצרנו את הרשימה נעבור בין איבריה ונדפיס אותם בצורה הבאה:

foreach(Person person in persons)
{
    Console.WriteLine($"{person.Name},{person.Age}")
}

כעת כשאנחנו יודעים כיצד לעבור על איברי רשימה ולבצע בם פעולות, נלמד כיצד לבצע לוגיקה מעט יותר מסובכת על הרשימה.

כאן LINQ נכנס לתמונה.

מה זה LINQ?

LINQ - Language Integrated Query, הוא רכיב פיתוח שהוצג לראשונה בגרסה 3.5 של תשתית NET. והיה אחד השינויים המרכזיים בה.

מה אפשר לעשות עם LINQ?

באמצעות LINQ ניתן לתשאל ולסנן כל מערך, רשימה, קובץ XML או בסיס נתונים שרק נרצה וכל זה בדרך פשוטה וקריאה מאוד.

איך לסנן רשימה באמצעות LINQ?

נתחיל בדוגמה פשוטה: סינון הרשימה persons שיצרנו קודם לרשימה של Person שגילם מעל גיל 23.

persons = persons.Where(person => person.Age > 23);

מה ראינו כאן?
קראנו לפעולה Where של ה-IEnummerable שלנו, הפעולה Where מקבלת predicate

predicate בקצרה, תפקידו לקבל אובייקט מסוים ובעבור אותו אובייקט לוודא האם תנאי שהוגדר מתקיים.

זאת נעשה באמצעות ביטוי lambda:
ניתן לראות בביטוי person => person.Age > 23 סימן "<=". זהו לא סימן "גדול שווה" זהו חץ.

האובייקט person זהו האובייקט שקיבל הpredicate, ובעבור ה-person שקיבל יחזיר true אם גיל ה-person גדול מ23 וfalse אחרת.

במילים אחרות, Where ירוץ על הרשימה persons, ובעבור כל person (כל שם יכל להנתן כאן) ברשימה יבדוק האם התנאי מתקיים ויכניס אותו לרשימה החדשה שלנו.

איך לסדר רשימה באמצעות LINQ?

הפעם נסדר את הרשימה persons כך שאיבריה יופיעו מהקטן לגדול לפי הגיל.

persons = persons.OrderBy(person => person.Age);

בדוגמה השתמשנו בפעולה OrderBy אשר מקבלת keySelector, במילים אחרות מאפיין של אובייקט, ומסדרת את כל האובייקטים לפי אותו מאפיין שקיבלה.

ניתן גם לבצע סינון כפול באופן הבא:

persons = persons.OrderBy(person => person.Age).ThenBy(person => person.Name);

כעת הרשימה person תסתדר לפי הגיל ולאחר שהגיל כבר מסודר, תסתדר גם לפי השמות.

פעולות נוספות שניתן לעשות באמצעות LINQ

סכימת מאפיין מסוים של איברי הרשימה:
int ageSum = persons.Sum(person => person.Age);

הפעולה Sum תקבל selector ותחזיר int שיסכום את ערכי הselector שקיבלה בעבור כל עצמי הרשימה.

הפיכת הסדר של איברי הרשימה:
persons.Reverse();

לסיכום

היום הכרנו את הממשק IEnummerable ואת השימוש בforeach ו LINQ עליו.

LINQ היא תשתית שלמה המכילה פונקציונליות רבה שסביר מאוד להניח שתענה על כל שאילתה שנרצה לבצע על רשימה.
הכוח של LINQ עצום ואני ממליץ בחום על השימוש בו, למען נוחות הכתיבה וקריאות הקוד.

אני קורא לך לפתוח Visual Studio ולהתחיל לנסות ולחקור את הפונקציונליות של LINQ בעצמך!

אם יש לך שאלות אל תתבייש!
גם לי הנושא לא היה ברור עד לא מזמן.

שאל בתגובות :)

תגובות

  1. מדריך מעולה גם לבעלי הידע הבסיסי!

    השבמחק
  2. מדריך ממש טוב תודה
    שאלו אותי השבוע שתי שאלות בראיון עבודה
    1. מה ההבדל בין where ל select במשפט linq מה יחזור בכל מקרה
    2.מה יחזור לי מ linq עם select עם נוסיף tolist ומה אם לא נוסיף בשני המקרים נקבל את זה למשתנה מסוג var
    אשמח להסבר תודה!

    השבמחק
    תשובות
    1. tolist זה כשרוצים להכניס את המידע לתוך רשימה ולא למשתנה אנונימי

      מחק
  3. אלוף! ממש עוזר, תודה רבה

    השבמחק
  4. שאלו אותי את השאלה הזאת:
    6. חברת תוכנות-ירושלים מחפשת עובדים מירושלים, חסרי נסיון, אך בתנאי שממוצע הציונים שלהם גדול מ 95, או שיש להם לפחות 3 ציונים מעל 90. הדפס את המועמדים הרלוונטיים.
    אשמח לעזרה

    השבמחק

הוסף רשומת תגובה

פוסטים פופולריים מהבלוג הזה

תכנות מונחה עצמים | Dependency Inversion Principle

מהם קבצי DLL ואיך להשתמש בהם?

מה ההבדל בין אוטומציה לפיתוח רגיל