მოვლენები მთლიანად დაფუძნებულები არიან დელეგატებზე და რახან
მოვრჩი დელეგატების განხილვას, ლოგიკური იქნება თუ ჩემი პოსტების გაგრძელება შეეხება
ისეთ ელემენტებს, როგორიცაა მოვლენები. მოვლენები გვთავაზობს publish/subscribe
მექანიზმს. ყველაფრის გადათარგმნა
არ იქნება მოხერხებული და ამიტომ, ჩემი აზრით, სჯობს რამდენიმე ტერმინოლოგია ასე დავტოვო.
მაგალითისათვის, რომ ავიღოთ Windows Forms ში Button კონტროლს აქვს Click
მოვლენა. მოვლენის ეს ტიპი
არის დელეგატი, ხოლო მომგვარებელი (handler) მეთოდის გამოძახება ხდება მაშინ, როდესაც
აქტიურდება Click მოვლენა.
მომგვარებელი ანუ მოპასუხე მეთოდის განსაზღვრა ხდება მომხმარებლის მიერ უმეტეს შემთხვევაში.
ჩემი აზრით მხოლოდ თეორიას ჯობს მაგალითებიც შევურიო მასში და
ასეც მოვიქცევი. შევქმნი ახალ კლასს - JobDealer.cs, რომელიც სთავაზობს „მომხმარებელს“
მოვლენებზე დაფუძნებულ „გამოწერას“. JobDealer.cs განსაზღვრავს ახალ მოვლენას NewJobInfo,
რომლის ტიპია EventHandler<JobInfoEventArgs>
event საკვანძო სიტყვის
გამოყენებით. NewJob() მეთოდის შიგნით ხდება NewJobInfo
მოვლენის გააქტიურება.
public class JobInfoEventArgs
: EventArgs
{
public
JobInfoEventArgs(string job)
{
this.Job
= job;
}
public string
Job { get; private set;
}
}
public class JobDealer
{
public event EventHandler<JobInfoEventArgs>
NewJobInfo;
public void
NewJob(string job)
{
Console.WriteLine("JobDealer,
new job {0}", job);
if(NewJobInfo
!= null)
{
NewJobInfo(this,
new JobInfoEventArgs(job));
}
}
}
JobDealer.cs
კლასი მომხმარებელს სთავაზობს
ახალ მოვლენას NewJobInfo რომლის ტიპია <JobInfoEventArgs>.
კონვენციის თანახმად მოვლენები
იყენებენ მეთოდებს, რომლებსაც გააჩნიათ ორი პარამეტრი. Sender ობიექტი, რომელიც ააქტიურებს მოვლენას
და მეორე პარამეტრი აგზავნის მოვლენის შესახებ დამატებით ინფორმაციას. მეორე პარამეტრი
სხვადასხვაა სხვადასხვა ტიპის მოვლენებისათვის. .NET 1.0 ში უკვე რამდენიმე ასეული დელეგატი იყო
განსაზღვრული სხვადასხვა ტიპის მოვლენებისათვის. EventHandler<TEventArgs>
განსაზღვრავს handlerს რომელიც აბრუნებს void
ს და იღებს ორ არგუმენტს.
EventHandler<TEventArgs> ის პირველი პარამეტრი უნდა იყოს object ტიპის, ხოლო მეორე პარამეტრის ტიპი არის
T. EventHandler<TEventArgs> ასევე განსაზღვრავს T ტიპზე შეზღუდვას, რაც იმას ნიშნავს,
რომ მიუხედავად იმისა, რომ T ტიპში ნებისმიერი ტიპი შეიძლება იგულისხმებოდეს, მაინც
არსებობს გამონაკლისები და ყველა ტიპი არ შეიძლება ჩაჯდეს <> ფრჩხილებში. ეს
შეზღუდვა კი მდებარეობს შემდეგში: T ს მაგივრად გამოყენებული კლასი აუცილებელია,
რომ იყოს EventArgs ის მემკვიდრე. სწორედ ამიტომ არის გამოყენებული ჩემს მიერ შემოთავაზებულ
მაგალითში განსაზღვრული კლასისთვის წინაპარი EventArgs კლასი.
public delegate void EventHandler<TEventArgs>
(object sender, TEventArgs e)
where
TEventArgs : EventArgs
კლასი JobDealer.cs ააქტიურებს მოვლენას NewJob მეთოდში. NewJobInfo ს ()
ით გამოყენებით, იძახებთ ყველა იმ handler ს რომელსაც
„გამოწერილი“ აქვს მოვლენა. Multicast
დელეგატების მსგავსად handler ების
გამოძახების თანმიმდევრობა არ არის დაცული, ამიტომ ესეც უნდა გაითვალისწინოთ თქვენს
მიერ დაწერილ კოდში, რადგან ერთხელ შეიძლება იმუშაოს ყველაფერმა, ხოლო მეორეჯერ კი
რაიმე შეცდომა ამოაგდოს და თავის ტკივილი გაგიჩინოთ.
ასევე ყურადღებაა იმ ფაქტზე გასამახვილებელი,
რომ აუცილებლად უნდა შემოწმდეს NewJobInfo
დელეგატის არსებობა, რადგან თუ ის არავის არ აქვს გამოწერილი მაშინ null ის ტოლია.
public void NewJob(string job)
{
Console.WriteLine("JobDealer,
new job {0}", job);
if(NewJobInfo
!= null)
{
NewJobInfo(this,
new JobInfoEventArgs(job));
}
}
No comments:
Post a Comment