פונקציות ב-C#

המטרות של פונקציות הן לסדר את הקוד ולתמוך בעקרון DRY – Do Not Repeat yourself. לכל תוכנית יש לפחות פונקציה ראשית אחת שמהווה את נקודת הפתיחה של התוכנית. במקרה של תוכנית console יש לנו את פונקציית Main.

class Program
{
    static void Main(string[] args) {
        welcomeMessage();
        Console.ReadLine();
    }

    static void welcomeMessage() {
        Console.WriteLine("Welcome!");
    }
}

המילה static מציינת את האפשרות לקרוא לפונקציה ישירות מכל מקום. לא חייב ליצור מופע של ה-class כדי לקרוא לפונקציה.

Void functions

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

Return type functions

פונקציה יכולה להחזיר ערך שאפשר להשתמש בו. למשל הפונקציה theName מחזירה ערך string.

static void Main(string[] args) {
    welcomeMessage();
    Console.ReadLine();
}

static void welcomeMessage() {
    Console.WriteLine("Welcome " + theName());
}

static string theName() {
    return "Jack";
}

Function parameters

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

static void Main(string[] args) {
    Console.WriteLine(add(2, 4)); 
    Console.ReadLine();
}

static int add(int num1, int num2) {
    return num1 + num2;
}

Optional parameters

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

static void Main(string[] args) {
    Console.WriteLine(add(2)); 
    Console.ReadLine();
}

static int add(int num1, int num2 = 50) {
    return num1 + num2;
}

עוד דרך לסמן פרמטר רשות היא על ידי המילה Optional. הפרמטר יקבל ערך ברירת מחדל של הסוג בו הוא מוגדר. אפשר גם להשתמש בערך default והתוצאה תהיה זהה.

static int add(int num1, [Optional] int num2) {
    return num1 + num2;
}

static int add(int num1, int num2 = default) {
    return num1 + num2;
}

Named parameters

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

static void Main(string[] args) {
    Console.WriteLine(add(num2:2, num1:4)); 
    Console.ReadLine();
}

static int add(int num1, int num2 = default) {
    return num1 + num2;
}

Out parameters

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

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

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

int.TryParse(Console.ReadLine(), out int num);

איך מגדירים פונקציה כזאת?

הגדרנו את המשתנה num בפונקציה הראשית, הוא קבל את הערך 0. בפונקציה test קבלנו את המשתנה num אבל הוא מוגדר שם כ-out. כלומר הוא יוצא את הערך שלו מהפונקציה. תוך הפונקציה חייבת להיות השמה למשתנה num.

static void Main(string[] args) {
    int num = 0;
    bool success = test(out num);
    Console.WriteLine(num);
    Console.ReadLine();
}

static bool test(out int num) {
    num = 5;
    return true;
}

Reference parameters

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

static void Main(string[] args) {
    int num = 10;
    assign(ref num);
}

static void assign(ref num){
   num = 20;
}

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