467
0

Extension Methods – הופך את הקוד שלכם לנקי, קריא ואיכותי

467
זמן קריאה: 3 דקות

בפוסט הנ”ל ארחיב על הפיצ’ר “פונקציות הרחבה” (Extension methods),

בסוף 2007, כחלק מגרסת C# 3.0 יצאו לעולם כמה מהפיצ’רים הטובים ביותר בשפה.

בעיני רבים זו הגרסה בה השפה עשתה קפיצת מדרגה ענקית שסגרה פער בינה לבין המתחרה הבכירה Java.

הפיצ’רים המפורסמים שהתווספו הם:
  •  LINQ
  • Lambda Epressions
  • Expressions trees
  • Anonymous types
  • Extension methods

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

מדובר בפיצ’ר שיהפוך את הקוד שלכם להרבה יותר נקי, קריא ואיכותי.

מספיק רק להסתכל על הדוגמא הבאה כדי להבין את הכוח הרב שטמון בפיצ’ר הזה:

				
					
public IEnumerable<User> WithExtensionMethods(List<User> Users)
{
    return Users
        .Where(u => u.Age > 20 && u.Age < 30)
        .Where(u => u.Gender == "Female")
        .OrderBy(u => u.Transactions);
}
 
public IEnumerable<User> WithoutExtensionMethods(List<User> Users)
{
    return Enumerable.OrderBy(Enumerable.Where(
        Enumerable.Where(Users, u => u.Gender == "Female"), 
        u=> u.Age > 30 && u.Age < 40), //where
        u=> u.Transactions); //orderBy
}
 
				
			
איזה קוד קריא יותר? מה יותר אלגנטי?
לא יודע מה איתכם אבל אני לא הייתי רוצה להיות זה שצריך להבין את הקוד המסורבל כמו זה שלמטה, תסכימו איתי שזה נראה כמו בלאגן אחד גדול.

איך מייצרים הרחבה?

כל מה שצריך לעשות זה לייצר פונקציה סטטית איפשהו בקוד, לא חייב שיהיה קשר למיקום של האובייקט אותו אנחנו מרחיבים, נדאג שהפרמטר שלה יכיל את המילה ‘this’,

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

במקרה של הדוגמא הבאה הוספתי פונקציה שיודעת לבדוק האם המייל חוקי, אך בעצם הרחבתי את “string” ובכל מקום שנשתמש במחרוזות בקוד תהיה יכולת של בדיקת מייל בדיוק כמו כל פונקציה שאתם מכירים כבר על מחרוזות.

				
					   public static class StringExtension
   {
     // Extension Method for string type
     public static bool IsValidEmail(this string str)
     {
        var result = Regex.IsMatch(str, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
        return result;
     }
   }
				
			
				
					
    class Program
    {
       static void Main(string[] args)
       {
          string mail = "admin@codetime.co.il";
          var result = mail.IsValidEmail();
          Console.Write($"Is valid: {result}");
          Console.ReadLine();
       }
    }
				
			

דוגמא נוספת – 

נרצה לממש פונקציה שתבדוק לנו האם המחרוזת מכילה רק מספרים או במילים אחרות – האם ניתן להפוך אותה ממחרוזת לint

				
					public static bool ToInt(this string value)
{
    return int.TryParse(value, out var _);
}
				
			

ניצור מחרוזת וכעת נוכל להפעיל את ההרחבה החדשה שיצרנו:

				
					var sValue = "1465";
if (sValue.ToInt())
{
    // Do something
}
				
			

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

מתי ולמה להשתמש בהרחבות?

  1. לשמור על הקיים – אם יש לכם מחלקה שמסיבה כזו או אחרת לא תרצו לשנות אותו יותר – בזכות הפיצ’ר הזה תוכלו להוסיף למחלקה פונקציות מבלי לרשת אותה או לערוך אותה.
  2. DRY – אחד העקרונות החשובים ב-Clean Code נקרא DRY  אם אתה מוצא את עצמך כותב את אותו הקוד שוב ושוב, תשקול להפוך את הקוד הזה להרחבה כדי למנוע ממך לחזור על אותו קוד לעתים קרובות.
  3. רלוונטיות – השתמש בשיטת הרחבה כאשר הפונקציונליות באמת רלוונטית
    לדוגמה, שיטת הרחבה date.AddDays(int numDays) שמרחיבה את DateTime היא מאוד הגיונית ולרוונטית. אבל לעומת זאת המקרה ההפוך days.AddToDate(date) (שמרחיב int) יהיה הרבה פחות רלוונטי ונכון.
  4. הרחבת מחלקה קיימת – לא ניתן הוסיף קוד למחלקה מקומפלת, במיוחד כשאין ברשותנו את קוד המקור שלה.
    בזכות Extension method תוכלו להרחיב כל טיפוס שרק עולה לכם בראש (למשל כמו string, DateTime, FileInfo)
  5. סדר וארגון – כשהקוד נראה מסורבל ובא לנו שהדברים ייראו טוב בעין זה לגמרי סיבה מוצדקת להשתמש בהרחבות, בדיוק כמו בדוגמא שהבאתי למעלה.
אמיר שטיימן
WRITEN BY

אמיר שטיימן

Backend Engineer @Cynet
ביום יום מפתח Backend בסביבת SaaS, מיקרו סרביסים בשילוב של מערכות מבוזרות. בזמני הפנוי - לומד ומשתדרג בעולם התוכנה, אוהד מכבי חיפה, פלייסטיישן ובירה עם חברים :)
Linkedin | Twitter

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *