ראינו בפעמים הקודמות קצת מהן Extension Methods ומה אפשר לעשות איתן.
בנוסף, בפעם האחרונה, גם ראינו שאפשר לשלוח delegate לExtension method לכל מיני שימושים.
בFramework 3.5 קיבלנו namespace שלם שנקרא System.Linq עם כל מיני Extension Methods שעובדים על כל IEnumerable
עוד בFramework 2.0 חשבו על הרעיון של לשלוח delegateים למתודות למטרות סינון, ולראיה ניתן לראות את הפונקציה הבאות בList
|
|
לא נסביר על כל מתודה ומתודה, אבל, למשל Exists מקבלת פרדיקט (פונקציה שמקבלת T ומחזירה בוליאני), ומחזירה אמת אם קיים איבר שמקיים אותו
FindAll מקבלת פרדיקט ומחזירה את כל האיברים שמקיימים אותו
TrueForAll מקבלת פרדיקט ומחזירה אמת אם כל איברי הרשימה מקיימים אותו
ForEach רצה על כל איברי הרשימה ומבצעת על כל אחד מהם פעולה
לגבי השאר, אני מניח שתוכלו לנחש לבד…
הבעיה בסיפור הזה היא שהמתודות האלה יושבות בתוך מחלקה מאוד ספציפית שנקרא List<T>.
מה הבעיה בזה? שאם אנחנו מעוניינים באותה פונקציונאליות עבור כל טיפוס אחר, למשל מערך או DataTable, אנחנו צריכים להעתיק את הפונקציונאליות לכל מחלקה שמעוניינת בפונקציונאליות. נוכל להכניס את המתודות האלה לממשק, אבל אז נצטרך לכתוב את הפונקציונאליות מחדש בכל מימוש של הממשק.
בגדול המימוש כאן הוא די זהה לחלוטין, לא משנה לאיזה טיפוס אנחנו מעוניינים לממש את הפונקציונאליות.
למשל תוכלו להסכים איתי שנוכל לממש לכל IEnumerable<T> את ForEach בצורה באה:
|
|
ואת TrueForAll בצורה הבאה:
|
|
לכן בד"כ נאלץ לשכפל קוד, מה שתמיד רע.
הפתרון: Extension methods. במקום שכל אחד יצטרך לשכפל פונקציונאליות, הומצאו Extension Methods שעובדים על IEnumerable<T>שמבצעים את אותו הדבר בדיוק, למשל יכולנו לכתוב את המתודה TrueForAll כך:
|
|
ראו גם טיפ מספר 84.
למען האמת כתבו לנו את המתודה הזאת (עם חתימה מעט שונה) בשם All בnamespace ששמו System.Linq. בנוסף כתבו לנו עוד אוסף שלם של Extension Methods שמספק פונקציונאליות אדירה ונוחה בטירוף.
אחת המתודות שלא נמצא שם לא משנה כמה קשה נחפש, היא מתודה ששקולה למתודת הForEach שראינו. הסיבה היא שאחד הרעיונות שעומד מאחורי LINQ באופן כללי הוא תכנות פונקציונאלי. בין השאר, אחד העקרונות של תכנות פונקציונאליות הוא אובייקטים שהם immutable וstateless. מאחר ובד"כ בForEach נבצע מניפולציה על האוסף שלנו, הוחלט שלא יהיה בשבילו Extension Method.
בגדול הnamespace הזה הוא namespace מאוד שימושי, ואנחנו עוד נכיר אותו לעומק.
שבוע של שפה מובנית שאילתא טוב