DCSIMG
C# 4.0 Part 11 - Named Parameters - שלמה גולדברג (הרב דוטנט)

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

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

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);

        }

 
שימו לב להבדל בתוצאות בין הקריאה הראשונה לשנייה.
 
Naemd Parameters
 
 
ושוב תמיד צריך לזכור שכל העבודה זה של הקומפיילר שעובד קשה כדי להכניס את הערכים למשתנים כמו שבקשנו.
 
 
נקודה נוספת לזהירות בשימוש עם 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
 
וכדי שזה לא יקרה החליטו להשתמש עם האופרטור : כדי לשלוח ערכים לפרמטרים.

תוכן התגובה

Shlomo כתב/ה:

מסכים אתך כשמדובר בשני טיפוסים שונים

# November 1, 2009 6:35 PM

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

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

אפרופו params, האם אני יכול לתת לו מערך במקום לכתוב את כל הערכים ידנית? אם לא, צריך להוסיף את האפשרות הזו.

במקרה שיש לי כבר מערך מוכן עם כל האיברים. זה מוסיף גמישות, וחוץ מזה זה נראה מגעיל לכתוב כך:

int[] elements={1,2,3,4,5,6}

int res=Sum(elements[0],elements[1],elements[2]....)

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

שמיקרוסופט יחשבו על זה.

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

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 4 and 7 and type the answer here:


Enter the numbers above: