Extension Method

סגור באמצעות טופס זה תוכלו לספר ולהמליץ לחבריכם..
שם השולח:
כתובת דוא"ל של השולח:
שם המקבל:
שלח לכתובת דוא"ל:
הוסף הערה:
החל מהגרסה השלישית של C# ניתן להגדיר הרחבות למחלקות, להוסיף להן פונקציונאליות נוספת על הקיים גם כאשר הקוד שלהן אינו ברשותנו וגם כאשר לא ניתן להשתמש בהורשה. ההרחבות הללו נקראות Extension Methods.
 
Extension Method Extension Method
 
מאת: ארז קלר

הורדת דוגמאות קודהורדת דוגמאות קוד

לא ניתן הוסיף קוד למחלקה מקומפלת, בטח כשאין ברשותנו את קוד המקור שלה.
הקביעה הזו, אני מניח, לא מפילה אף אחד מהכיסא.
האם אפשרי להוסיף מתודה לטיפוס Int32 אשר מקבלת מחרוזת נומרית וממירה אותה למספר שלם?
כיצד ניתן להוסיף למחלקהString  מתודה אשר מקבלת מספר וממירה אותו למחרוזת?
נסו להוסיף מתודה המוסיפה התנהגות זהה לכל המחלקות בתוכנית, למשל, לשמור בקובץ את תוכנה, מישהו הצליח?
הקוד של המחלקות הללו לא קיים ברשותנו, אנו משתמשים רק בקוד המקומפל, הורשה לא תמיד אפשרית, בחלקן המחלקות מוגדרות כSealed -.
לעיתים היכולת להרחיב את הפונקציונאליות של מחלקה קיימת מאוד עוזרת.
החל מהגרסה השלישית של  C# ניתן להגדיר הרחבות למחלקות, להוסיף להן פונקציונאליות נוספת על הקיים גם כאשר הקוד שלהן אינו ברשותנו וגם כאשר לא ניתן להשתמש בהורשה.
ההרחבות הללו נקראות Extension Methods.
השימוש ב- Extension Method אינו משנה בפועל את הטיפוס המקורי, אלא מרחיב את הפונקציונאליות ובכך את היכולות של הטיפוס, יש פה מעין הטעיה, "ללכת בלי ולהרגיש עם".
ההרחבה תקפה רק בפרויקט הנוכחי בה נכתבות המתודות הללו.

הגדרת Extension Method

Extension Methods ממומשות כמתודות סטאטיות המוגדרות במחלקות סטאטיות.
הן מזוהות כך על ידי המילה השמורה this לפני הפרמטר הראשון שלה.
כאשר משתמשים בהן אין שום הבדל בינן לבין קריאה למתודה מקורית של הטיפוס.
דוגמה ראשונה, נרחיב את הפונקציונליות של int, מעתה נוכל באמצעות הטיפוס int להדפיס בצבע את תוכנו של המופע:
 1  : static class ExtensionMethods 
 2  : { 
 3  :     public static void WriteLine(this int num, ConsoleColor color) 
 4  :     { 
 5  :         ConsoleColor original = Console.ForegroundColor; 
 6  :         Console.ForegroundColor = color; 
 7  :         Console.WriteLine(num); 
 8  :         Console.ForegroundColor = original; 
 9  :     } 
 10 : } 
 11 : class Program 
 12 : { 
 13 :     static void Main(string[] args) 
 14 :     { 
 15 :         int num = 12; 
 16 :         num.WriteLine(ConsoleColor.Yellow); 
 17 :     } 
 18 : } 
נתחיל בהגדרת מחלקה סטאטית (שורה 1) בתוכה מוגדרות מתודות סטטיות שיהוו הרחבה למחלקות קיימות.
בשורה 3 מוגדרת המתודה הסטטית הראשונה - WriteLine, הפרמטר הראשון שלה הוא this int num, המשמעות של this הוא שהמתודה תהיה הרחבה לטיפוס int.
מעתה נוכל להשתמש בה כאילו היא חלק אינטגרלי מ-int.
דוגמה לשימוש נוכל לראות בשורה 16, נראה כמתודה רגילה של int.
פלט:
פלט תוכנית דוגמה

בדוגמה השנייה נרחיב את היכולת של String ונוסיף לה יכולת לזהות האם ערכה הוא מחרוזת נומרית:
 1  : static class ExtensionMethods 
 2  : { 
 3  :     public static bool IsNumeric(this string s) 
 4  :     { 
 5  :         double output; 
 6  :         return double.TryParse(s, out output); 
 7  :     } 
 8  : } 
 9  : class Program 
 10 : { 
 11 :     static void Main(string[] args) 
 12 :     { 
 13 :         string str1 = "123.222"; 
 14 :         if (str1.IsNumeric()) 
 15 :         { 
 16 :             Console.WriteLine("str1 is numeric"); 
 17 :         } 
 18 :     } 
 19 : } 
כמו בדוגמה הקודמת, גם כאן המחלקה הסטטית ExtensionMethod מכילה מתודה סטטית שהפרמטר הראשון שלה מתחיל ב-this ואחריו string ולכן המתודה מהווה הרחבה לטיפוס String.
פלט:
פלט תוכנית דוגמה

הדוגמה השלישית היא הרחבה הרבה יותר רחבה, היא מקיפה את כל הטיפוסים בתוכנית.
נרחיב ונוסיף פונקציונליות למחלקה Object, ומכיוון שכולם יורשים את Object כולם ירשו ממנה גם את ההרחבה:
 1  : class Person 
 2  : { 
 3  :     public string FirstName { get; set; } 
 4  :     public string LastName { get; set; } 
 5  :     public byte Age { get; set; } 
 6  :     public void Print() 
 7  :     { 
 8  :         Console.WriteLine(LastName + "," + FirstName + "," + Age); 
 9  :     } 
 10 :     public override string ToString() 
 11 :     { 
 12 :         return string.Format("Last name: {0}, First name: {1}, Age: {2}", LastName, FirstName, Age); 
 13 :     } 
 14 : } 
 15 : static class ExtensionMethods 
 16 : { 
 17 :     public static void PrintToFile(this object obj, string file_name) 
 18 :     { 
 19 :         System.IO.TextWriter tw = System.IO.File.AppendText(file_name); 
 20 :         tw.WriteLine(obj.ToString()); 
 21 :         tw.Close(); 
 22 :     } 
 23 : } 
 24 : class Program 
 25 : { 
 26 :     static void Main(string[] args) 
 27 :     { 
 28 :         string str = "Hello extension method!"; 
 29 :         str.PrintToFile("test.txt"); 
 30 :         int num = 1234; 
 31 :         num.PrintToFile("test.txt"); 
 32 :         num = 5678; 
 33 :         num.PrintToFile("test.txt"); 
 34 :         Person p = new Person() { FirstName = "Moshe", LastName = "Israeli", Age = 42 }; 
 35 :         p.PrintToFile("test.txt"); 
 36 :         DayOfWeek day = DayOfWeek.Monday; 
 37 :         day.PrintToFile("test.txt"); 
 38 :     } 
 39 : } 
לטובת הדוגמה התווספה מחלקה חדשה הנקראת Person (שורה 1).
בשורה 17 בתוך המחלקה הסטטית ExtensionMethods הוספנו מתודה סטטית חדשה, הפרמטר הראשון שלה הוא this object obj, המשמעות שלה היא שההרחבה תקפה ל-Object אבל גם לאלו שיורשות את Object שזה למעשה כל המחלקות ב-.NET Framework כולל אלו שאנו מוסיפים (כמו Person לדוגמה).
Main מדגימה את שימוש במתודה הזו על int על String ועל Person ואפילו על enum DayOfWeek המוגדר במרחב השמות System (גם הוא יורש מן הסתם את Object),
תוכלו להוסיף ולהשתמש בה בכל טיפוס אחר במערכת.
הקובץ test.txt:



כל הזכויות שמורות למחבר ©