Jan 4, 2014

დელეგატები (5/5) - Multicast Delegates


აქამდე ვიყენებდი დელეგატებს, რომლებიც იძახებდნენ მხოლოდ ერთ მეთოდს. ერთზე მეტი მეთოდის გამოსაძახებელად ერთი დელეგატის გამოყენებით საჭიროა ცხადად შეუცვალოთ დელეგატს შემცველი მეთოდის მისამართი. მაგრამ არსებობს უფრო მარტივი გზაც, რომელიც განსხვავდება პირველი პრიმიტიული გზისაგან და საშუალებას გვაძლევს ერთი დელეგატის გამოყენებით გამოვიძახოთ ერთზე მეტი მეთოდი. მსგავსი დელეგატი ცნობილია Multicast დელეგატის სახელით. თავისუფლად შეიძლება მას ეწოდოს მრავალი მეთოდის შემცველი დელეგატი. ამისთვის საჭიროა რომ ყველა მეთოდი, რომელსაც იძახებს დელეგატი, არ უნდა აბრუნებდეს არანაირ მნიშვნელობას, ანუ უნდა იყოს void ტიპის. წინააღმდეგ შემთხვევაში დელეგატი დააბრუნებს იმ მეთოდის დაბრუნებულ მნიშვნელობას რომელიც გამოიძახა ბოლოს.
მეთოდის გამოსაძახებლად, რომელიც აბრუნებს void ტიპს, გამოვიყენებ Action<T> ტიპის დელეგატს.

static void Main(string[] args)
        {
            Action<double> Ops = MathOps.MultiplyByFour;
            Ops += MathOps.Square;

ძველ მაგალითებში შეიძლება შეგხვდეთ ისეთი სიტუაცია, რომელშიც საჭიროა სხვადასხვა დელეგატის გამოყენება სხვადასხვა მეთოდის გამოძახებისთვის. აქ კი შესაძლებელია უბრალოდ ოპერაციების მიმატება და მრავალი მეთოდის შემცველ დელეგატად „გადაქცევა“ ერთი შეხედვით ჩვეულებრივი დელეგატის. დელეგატებთან მუშაობისას, ისინი ცნობენ ისეთ ოპერატორებს როგორებიც არიან + და +=. ასევე დასაშვებია ქვემოთ მოცემული კოდის გამოყენებაც

Action<double> op1 = MathOps.MultiplyByFour;
Action<double> op2 = MathOps.Square;
Action<double> op3 = op1 + op2;

მრავალი მეთოდის შემცველი დელეგატები შესაძლებელს ხდიან გამოიყენოთ - და -= ოპერატორები. ქვემოთ მოცემულია კიდევ ერთი მარტივი გამოყენება მრავალი მეთოდის შემცველი დელეგატებისა და MathOps.cs კლასის განსაზღვრის გზა.

class MathOps
        {
            public static void MultiplyByFour(double num)
            {
                double result = num * 4;
                Console.WriteLine("Multiply by 4 {0} = {1}", num, result);
            }

            public static void Square(double num)
            {
                double result = num * num;
                Console.WriteLine("Square of {0} = {1}", num, result);
            }
        }

შესამჩნევია, რომ MathOps.cs კლასში მოთავსებული მეთოდები სტატიკურია და ისინი მნიშვნელობის დაბრუნების მაგივრად ავტომატურად წერენ პასუხს, რადგან მრავალი მეთოდის შემცველ დელეგატებთან მუშაობისას სასურველია void დაბრუნების ტიპის მეთოდების გამოყენება.

შესაძლებელია ასევე შემდეგი ინტერპრეტაციის გამოყენებაც:

static void CallAndDisplay(Action<double> action, double num)
        {
            Console.WriteLine("Called with val = {0}", num);
            action(num);
        }

ხოლო Main ის კოდი გადაკეთდება შესაბამისად

static void Main(string[] args)
        {
            Action<double> ops = MathOps.MultiplyByFour;
            ops += MathOps.Square;

            CallAndDisplay(ops, 2.0);
            CallAndDisplay(ops, 5.21);
            CallAndDisplay(ops, 12.322);
            Console.ReadKey();
        }

კოდის გაშვების შემდეგ გექნებათ შემდეგი შედეგი, თუ რა თქმა უნდა არ შეცვალეთ num ცვლადის მნიშვნელობები.




ასევე გასათვალისწინებელია ის ფაქტიც, რომ როდესაც იყენებთ მრავალი მეთოდის შემცველ დელეგატებს ფორმალურად არ არის განსაზღვრული მეთოდების გამოძახების მიმდევრობა. სასურველია თავიდან აირიდოთ ისეთი მეთოდების გამოძახება მსგავსი დელეგატით, რომელთა გამოძახების მიმდევრობის არევა რაიმე რისკის გამომწვევია, რადგან თუ ერთი დელეგატის გამოძახებისას რაიმე პრობლემა შეიქმნა და კომპილერმა Exception დაიჭირა, მაშინ ამ მეთოდის შემდგომი მეთოდების გამოძახება აღარ გაგრძელდება.  

No comments:

Post a Comment