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")
{
}
כלומר - כל ההגדרות של פרמטרי רשות הם אך ורק עבור הקומפיילר שידע מה לתת במידה ולא נתנו ערך לפרמטר.