www.doronamir.com

E-mail: doron@doronamir.com

 

© דורון אמיר יעוץ הדרכה ופיתוח תוכנה

 

מה זה Delegates ? 

Delegate: משמש כמצביע לפונקציה (מתודה), ה delegate יכול להצביע

לפונקציה של אוביקט והן לפונקציה סטטית.

 

כאשר רוצים לקרוא למתודה ספציפית (מתודה ששמה ידוע לנו מראש בעת כתיבת הקוד )

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

  myClass.Methodבמקרה של מתודה סטטית מסויימת.

 

מדוע צריך delegates כאשר אפשרי לקרוא לפונקציה ?

 

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

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

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

 

כדי להבין טוב יותר יש לחקור את הקוד הנ"ל

החלק הראשון אינו משתמש ב delegate ומציב אותנו בבעיה.

בקוד הנ"ל ניתן לראות מחלקה button המכילה מתודה OnClick שתפקידה

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

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

OnClick תקרה למתודה אחרת שאינה רשומה במחלקה לדוגמה Y_Method ? (ולא להוסיף אותה למחלקה Button כמובן ).

התשובה נמצאת בקוד2 אך תחילה יש להבין את קוד 1.

 

קוד1 :

 

 

using System;

namespace BeforeDelegates002

{

 

    public class Button

    {

        public void OnClick()

        {

        X_Metohd();

        }

 

        public  void X_Metohd()

        {

            System.Console.WriteLine("Hello From X_Metohd");

       

        }

   

    }

 

    public class MainClass

    {

        public static void Main()

        {

       

            Button button1 = new Button();

            button1.OnClick();

            Console.ReadLine();

        }

 

    }

}

 

תוצאה קוד 1    Hello From X_Metohd 

שימוש ב delegate

כאשר רוצים לקרוא לפונקציה מתוך אובייקט למרות שאינה קיימת במחלקת האובייקט ניתן להשתמש ב delegate

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

אבל בדוגמה זו המתודה OnClick תבצע קריאה למתודה שאינה ידועה מראש כמעין קריאה כללית למתודה , האובייקט

ימתין עד לקבלת שם המתודה לאחר שנוצר (המתודה אינה חלק ממחלקת ה Button)

 

הסבר קוד2 : שימוש ב Delegate

 

במחלקה Button הוגדר טיפוס עבור יצירת Delegate אשר יהיה מסוגל להצביע למתודות

החיצוניות מהחלקה Button ושאינן מחזירות ערך ) ( Void הגדרת הטיפוס נעשית ע"י המילה השמורה delegate

כולל סוג הערך המוחזר של הפונקציה שעליה נצביע וגם שם הטיפוס :

public delegate returnType DelegateTypeName();

 

השלב השני הוא הגדרת ה delegate שבעזרתו נבצע את ההצבעה לפונקציה :

public DelegateTypeName delegateName;

 

במחלקת Button המתודה OnClick מבצעת קריאה לפונקציה אשר מוצבעת

ע"י ה delegate , כלומר ה delegate ממתין לשם הפונקציה שעליה יש להצביע.

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

 

using System;

namespace Delegates

{

    public class Button

    {

        public delegate void dlgForClickButton();

        public dlgForClickButton dlgClick;

        public void OnClick()

        {

            dlgClick();

        }

 

    }

במחלקה הראשית ניתן להבחין בשתי מתודות סטטיות בשם X_Method ו- Y_Method

מתודות אלו אינן שייכות למחלקה Button אך ניתן יהיה לקרוא למתודות אלו

דרך המתודה OnClick ע"י מסירת שם הפונקציה למצביע (delegate)

 

    public class MainClass

    {

 

        public static void X_Metohd()

        {

            System.Console.WriteLine("Hello From X_Metohd");

       

        }

        public static void Y_Metohd()

        {

            System.Console.WriteLine("Hello From Y_Metohd");

       

        }

       

במתודה הראשית ניצור שני מופעים מהמחלקה button האובייקט הראשון מאתחל את הdelegate  בהצבעה למתודה x_method

האובייקט השני מאתחל את הdelegate  בהצבעה למתודה y_method  

לאחר שלב אתחול המצביעים (delegates) ניתן לקרוא לפונקציות השונות דרך מתודת ה OnClick של כל אובייקט.

 

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

 

       

public static void Main()

        {

       

            Button button1 = new Button();

            button1.dlgClick =new Button.dlgForClickButton(X_Metohd);

           

            Button button2 = new Button();

            button2.dlgClick=new Button.dlgForClickButton(Y_Metohd);

           

button1.OnClick();

button2.OnClick();

 

            Console.ReadLine();

        }

 

    }

 

 

}

תוצאה קוד 2

Hello From X_Metohd

Hello From Y_Metohd

 

נ.ב

מומלץ לתת למתודות שם יותר נוח לדוגמה: [מקובל במימוש פונקציה השייכת לאירוע ]

public static void btn3_Click()

        {

            System.Console.WriteLine("Hello From btn2_Click");

       

        }