DCSIMG
C# 4.0 Part 10 - Optional Parameters - Behind The Scenes - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

C# 4.0 Part 10 - Optional Parameters - Behind The Scenes

 

פספסתי את הפוסט של מוצאי שבת, (אולי אני אכתוב היום שניים).
 
בכל מקרה אנחנו רוצים לדעת מה קורה מאחורי הקלעים כשמשתמשים ב - Optional Parameters.
 
למעשה מייקרוסופט משתמשים בשני Attributes שקיימים כבר המון זמן. הראשון הוא - System.Runtime.InteropServices.OptionalAttribute והשני הוא - System.Runtime.InteropServices.DefaultParameterValueAttribute, למעשה הקוד הבא:
 

    static void Add(int id, string name = "", float age = 0)

    {

    }

 
מתרנדר לקוד הבא:
 

    static void Add(int id,

                    [Optional, DefaultParameterValue("")] string name,

                    [Optional, DefaultParameterValue(0)] float age)

    {

    }

 
ולמעשה אפשר להשתמש עם ה - Attributes האלו לבד וזה יעבוד באותו צורה.
 
יותר מכך - כשמגדירים משתנה כלשהו לברירת המחדל שלו, כלומר הקוד הבא:
 

    static void Add(DateTime dt1 = new DateTime(),

                    DateTime dt2 = default(DateTime),

                    int i = 0,

                    Person p = null)

    {

    }

 
 
אפשר גם לכתוב את הקוד הבא:
 

    static void Add1([Optional] DateTime dt1,

                    [Optional] DateTime dt2,

                    [Optional] int i,

                    [Optional] Person p)

    {

    }

 
 
שימוש רק ב - Attribute של Optional ללא שימוש ב - DefaultParameterValue נותן את ערך ברירת המחדל.
 
 
מה זה נותן לנו שאנחנו יודעים שאפשר להשתמש ישירות ב - attribute במקום לכתוב ערך כלשהו.
קודם כל אני חושב שתמיד חשוב לדעת איך הדברים עובדים מאחורה, שנית ישנם כמה דברים שאפשר לעשות רק עם ה - attributes ולא באמצעות השמה.
 
הראשון - בהגדרה של מתודה חייבים לכתוב קודם את כל הפרמטרים שהם חובה, כלומר הקוד הבא אינו חוקי
 

    static void Add(string name = "shlomo", int id)

    {

    }

 
ויחזיר את הודעת השגיאה:
 
Optional parameters must appear after all required parameters
 
לעומת זאת הקוד הבא:
 

    static void Add([Optional, DefaultParameterValue("shlomo")]string name,

                    int id)

    {

    }

 
יעבור קומפילציה ואפילו יעבוד, אני לא אומר שזה שימושי כל כך, אבל טוב לדעת שזה אפשרי.
 
 
שנית - וזה כבר יותר שימושי, זהו שימוש ב - dynamic.
 
הקוד הבא:
 

    static void Add(dynamic d = 10)

    {

    }

 
יחזיר שגיאת קומפילציה :
 
'd' is of type 'dynamic'. A default parameter value of a reference type other than string can only be initialized with null
 
אנחנו יודעים כמובן ש - dynamic הוא לא reference type. (נראה כמו באג של הקומפיילר) לעומת זאת הקוד הבא:
 

    static void Add([Optional, DefaultParameterValue(10)]dynamic d)

    {

    }

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

    public static void Main()

    {

        Add("noam");

        Add();

    }

 

    static void Add(string name = "shlomo")

    {

    }

 
 
מתרנדר לקוד הבא:
 

    public static void Main()

    {

        Add("noam");

        Add("shlomo");

    }

 

    static void Add(string name = "shlomo")

    {

    }

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

תוכן התגובה

Liran Chen כתב/ה:

כן, עם הזמן #C נהפכת דומה יותר ויותר ל-CPP

בינתיים אני אמשיך לחכות בשקט ל-const'ים..

# June 28, 2009 5:56 PM

אחד בארץ כתב/ה:

טוב לדעת שזה לא פוגע בביצועים אלא רק ברמת הקומפיילר.

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

# January 27, 2011 9:09 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 3 and 5 and type the answer here:


Enter the numbers above: