Dec 31, 2013

დელეგატები (2/5) - გამოყენება

ქვემოთ მოცემული მაგალითი იყენებს toString() მეთოდს. მაგალითი საკმაოდ გრძელი გზაა ამ მეთოდი int ტიპისთვის გამოსაყენებლად.
class Program
    {
        private delegate string GetString();

        static void Main()
        {
            int num = 40;
            GetString Fmethod = new GetString(num.ToString);
            Console.Write("String -> {0}", Fmethod());
        }
    }


ამ კოდში ჩვენ ვქმნით დელეგატს, რომლის ტიპია GetString და ვსაზღვრავთ მის „ობიექტს“, რომლის პარამეტრიცაა ToString() მეთოდი, რომელიც ოპერაციას ატარებს num ცვლადზე. სინტაქსურად დელეგატები პარამეტრად იღებენ ერთ მეთოდს, რომელსაც უკავშირდებიან და საჭიროების შემთხვევაში იძახებენ. გასათვალისწინებელია ის ფაქტი, რომ მეთოდისა და დელეგატის ხელწერა უნდა დაემთხვეს ერთმანეთს. შემდეგ ხდება დელეგატის გამოძახება, რომელიც იძახებს და ასრულებს შემცველ მეთოდს (ებს). დელეგატისთვის ბოლოს ფრჩხილების () დაწერა იმავეს ნიშნავს, რომ დაგეწერათ Fmethod.Invoke();

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

GetString Fmethod = num.ToString;

კომპილატორი ხვდება, რომ ამ შემთხვევაში ვიყენებთ დელეგატს და ის ჩვენთვის ქმნის დელეგატის ახალ „ობიექტს“ და მისამართით ატარებს იმ მეთოდს, რომელსაც ვუტოლებთ მას. ასევე ზემოთ მოცემულ სინტაქსში ყურადღებაა გასამახვილებელი იმ ფაქტზე, რომ num.ToString მეთოდი წერია () ის გარეშე, რადგან ეს წარმოადგენს ამ მეთოდის მისამართს, ხოლო თუ მას ფრჩხილებსაც მივამატებდით - num.ToString(), წარმოიშვებოდა პრობლემა, რადგან ეს უკვე ნიშნავს იმას, რომ ხდება მეთოდის გამოძახება და ეს მეთოდი აბრუნებს string ტიპის ობიექტს, რომელიც მიუღებელია დელეგატისთვის. სწორედ ამიტომ ვუტოლებთ დელეგატს მეთოდის მისამართს და არა თვით მეთოდის გამოძახების შედეგად მიღებულ ობიექტს. დელეგატისთვის მეთოდის პირდაპირ გატოლებას ეწოდება inference. დელეგატების ეს თვისება აქტიურად გამოიყენება event ებში, რომელის განხილვასაც დავიწყებ დელეგატების შემდგომ.

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

მე წარმოგიდგენთ ორ კლასს: Car და VirualDB, რომელიც წარმოადგენს მანქანების ვირტუალურ მონაცემთა ბაზას. პროგრამის მიხედვით, მთავარ ტანში ჩვენ გვაქვს მოცემული დელეგატის ტიპი, რომლის გამოყენებითაც განისაზღვრება პარამეტრის და არგუმენტი. ეს უკანასკნელი იყენებს Car კლასში მოთავსებულ სტატიკურ მეთოდ GetModel-ს, რომელიც მომხმარებელს აცდის მოდელის შეყვანას, როგორც ტექსტურ ცვლადს. ამის შემდეგ განისაზღვრება ვირტუალური მონაცემთა ბაზის (VirtualDB) ახალი ობიექტი - VDB. ამ ობიექტის გამოყენებით ვიძახებ AddCar მეთოდს, რომელიც არასტატიკურია და არგუმენტად ვატარებ დელეგატს. AddCar ის ბლოკში რომ შევიდეთ, ეს მეთოდი აკეთებს შემდეგ რამეს:
¨       შიდა სიაში ამატებს იმ მანქანას, რომლის მოდელიც არის იმ მეთოდის დაბრუნებული ტექსტური ცვლადი, რომლის მისამართსაც შეიცავს დელეგატი.
¨       გამოაქვს წარმატების ნიშანი
¨       აბრუნებს true მნიშვნელობას, შემდგომი გამოყენებისათვის
ქვემოთ წარმოგიდგენთ კოდს




namespace BlogSpotAppConsole
{
    class Program
    {
        public delegate string Mydel();
        static void Main()
        {
            //დაწყების მესიჯი
            Console.WriteLine("Enter Car Model");

            Mydel ArgumentDelegate = Car.GetModel;

            //ვქმნით ვირტუალური მონაცემთა ბაზის ობიექტს
            VirtualDB VDB = new VirtualDB();
            VDB.AddCar(ArgumentDelegate);

            //ვიცდით
            Console.ReadKey();
        }

        public class VirtualDB
        {
            List<Car> carList = new List<Car>();

            public bool AddCar(Mydel ParameterDelegate)
            {
                if (ParameterDelegate == null)
                    return false;
                else
                {
                    carList.Add(new Car { ModelName =                                                         ParameterDelegate() });
                    //carList.Add(new Car { ModelName = delegateParam.Invoke() });
                    //იმავეს აკეთებს რასაც პირველი მეთოდი ამ ბლოკში

                    //წარმატების მესიჯი ინგლისურად, ობიექტური მიზეზების გამო
                    Console.WriteLine("Car {0} added successfully",                                 this.carList[carList.Count - 1].ModelName);
                    return true;
                }
            }
        }

        public class Car
        {
            private string _modelName = null;
            public string ModelName
            {
                get
                {
                    return _modelName;
                }
                set
                {
                    if (value != null)
                        _modelName = value;
                }
            }

            public static string GetModel()
            {
                string modelN = Console.ReadLine();
                return modelN;
            }
        }
    }
}

ესეც Program.cs ფაილი, რომლის გამოყენებაც შეგეძლებათ VisualStudio ს გამოყენებით 


No comments:

Post a Comment