C# 4.0 Part 11 - Named Parameters
ל - Optional Parameters יש בעיה אחת קטנה.
static void Add(int id, string name = "shlomo", float age = 0)
{
}
static void Main()
{
Add(22, ,24);
}
זה לא מתקמפל וכמובן מאוד לא ברור. ולכן המציאו את ה - Name Parameters.
static void Main()
{
Add(22, age: 24);
}
גם עבור פרמטרים שהם חובה ניתן לשלוח עם השם:
static void Main()
{
Add(id: 22, age: 24);
}
זה גורם שהקוד שלנו יהיה יותר קריא. אבל צריך להיות זהירים עם השימוש ב - Named Parameters. (פוסט מומלץ לקריאה -
כאן).
החל מ - C# 4.0 אסור לשנות את השמות של פרמטרים של מתודות או של Interface מכיון שזה יכול לגרום לשגיאות קומפילציה של מי שקרא למתודה שלנו והשתמש ב - Named Parameter וברגע שנשנה את השם של הפרמטר הקוד שלו לא יתקמפל, סיבה שנייה - שהתוצאה שאנחנו מצפים לקבל יכולה להשתנות לפי הסדר של שליחת הפרמטרים, לדוגמא:
static void Main()
{
int i = 0;
Print(i++, i++, i++);
i = 0;
Print(z: i++, y: i++, x: i++);
}
static void Print(int x, int y, int z)
{
Console.WriteLine("x {0}, y {1}, z {2}", x, y, z);
}
שימו לב להבדל בתוצאות בין הקריאה הראשונה לשנייה.
ושוב תמיד צריך לזכור שכל העבודה זה של הקומפיילר שעובד קשה כדי להכניס את הערכים למשתנים כמו שבקשנו.
נקודה נוספת לזהירות בשימוש עם Named Parmetser היא חוסר היכולת שלו לעבוד עם params כלומר, ברגע שנקרא לפונקציה ונשלח אפילו את אחד מהפרמטרים באמצעות השם שלו, לא נוכל לשלוח ערכים לפרמטר מסוג params, הקוד הבא (של פונקצית ה - Main) אינו חוקי.
static void Add(int id, params int[] intArray)
{
}
static void Main()
{
Add(id: 10, intArray: 2, 2, 2);
}
זה נראה לי כמו באג ולא כמו משהו שתכננו מראש לעשות את זה, יותר מכך אני ציפיתי שבגלל שיש Named Parameters נוכל להגדיר מתודה שמקבלת יותר מ - params אחד, כלומר ציפיתי שהקוד הבא יהיה חוקי.
static void Add(params string[] stringArray, params int[] intArray)
{
}
מכיון שאני יכול לקרוא לפונקציה בצורה הבאה:
static void Main()
{
Add(stringArray: "a", "b", "c", intArray: 2, 3, 4);
}
אבל לדאבוני זה לא עובד, ולכן נזכור שברגע שאנחנו משתמשים ב - Named Parameters לא נוכל לשלוח ערכים לפרמטר מסוג params ויותר מכך ברגע שאנחנו מגדירים פרמטר שהוא אופציונלי, במידה ולא ישלחו לו ערך לא נוכל לקבל גם עבור ה - params, לדוגמא:
static void Add(string name, int id = 10, params int[] intArray)
{
}
כדי לשלוח ערך ל - intArray נהיה חייבים לשלוח ערך גם ל - id (ולא באמצעות השם שלו, אלא באמצעות המיקום שלו)
הסיבה שמשתמשים עם האופרטור : ולא עם האופרטור = היא כדי לא לבלבל עם משתנים של ה - class, שמו לב לקוד (וזה דרך אגב גם יעבוד בגרסאות קודמות של השפה)
public class Class1
{
static void Main()
{
new Person().Run();
}
}
class Person
{
private int id = 20;
public void Run()
{
Console.WriteLine(this.id);
Add(id = 10);
Console.WriteLine(this.id);
}
void Add(int id)
{
Console.WriteLine(id);
}
}
זה מוזר, אבל מסתבר שהקריאה למתודה Add עם שליחת הפרמטר בצורה הבאה: id = 10 היא חוקית גם לפני C# 4.0, (בתנאי שהוגדר גם משתנה בשם הזה כמשתנה גלובלי) ומה שזה עושה זה באמת לתת ערך ל - id של המתודה Add אבל במקביל זה גם משנה את הערך של המשתנה id הגלובלי שהערך שלו היה מוגדר ל - 20. התוצאה של הריצה תדפיס:
20
10
10
וכדי שזה לא יקרה החליטו להשתמש עם האופרטור : כדי לשלוח ערכים לפרמטרים.