درخواست توضیح یک مثال در مورد Event ها
با سلام و درود
دوستان امکان داره این مثال مخصوصا چند قسمت رو توضیحی بده که خوب درک کنیم؟ ممنون میشم
کد:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCarEventArgs
{
public class CarEventArgs : EventArgs
{
public readonly string msg;
public CarEventArgs(string message)
{
msg = message;
}
}
}
کد:
using System;
using System.Collections.Generic;
using System.Text;
namespace GenericCarEventArgs
{
public class Car
{
#region Basic Car state data / constructors
// Internal state data.
public int CurrentSpeed { get; set; }
public int MaxSpeed { get; set; }
public string PetName { get; set; }
// Is the car alive or dead?
private bool carIsDead;
public Car()
{
MaxSpeed = 100;
}
public Car(string name, int maxSp, int currSp)
{
CurrentSpeed = currSp;
MaxSpeed = maxSp;
PetName = name;
}
#endregion
// This delegate works in conjunction with the
// Car's events.
//public delegate void CarEngineHandler(object sender, CarEventArgs e);
// This car can send these events.
public event EventHandler<CarEventArgs> Exploded;
public event EventHandler<CarEventArgs> AboutToBlow;
public void Accelerate(int delta)
{
// If the car is dead, fire Exploded event.
if (carIsDead)
{
Exploded?.Invoke(this, new CarEventArgs("Sorry, this car is dead..."));
}
else
{
CurrentSpeed += delta;
// Almost dead?
if (10 == MaxSpeed - CurrentSpeed)
{
AboutToBlow?.Invoke(this, new CarEventArgs("Careful buddy! Gonna blow!"));
}
// Still OK!
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
}
}
کد:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCarEventArgs
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Events *****\n");
Car c1 = new Car("SlugBug", 100, 10);
// Register event handlers.
c1.AboutToBlow += CarAboutToBlow;
c1.Exploded += CarExploded;
EventHandler<CarEventArgs> d = new EventHandler<CarEventArgs>(CarExploded);
c1.Exploded += d;
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
c1.Exploded -= CarExploded;
Console.WriteLine("\n***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
Console.ReadLine();
}
#region Targets for events
public static void CarAboutToBlow(object sender, CarEventArgs e)
{
// Just to be safe, perform a
// runtime check before casting.
if (sender is Car c)
{
Console.WriteLine("Critical Message from {0}: {1}", c.PetName, e.msg);
}
}
public static void CarExploded(object sender, CarEventArgs e)
{ Console.WriteLine(e.msg); }
#endregion
}
}
ابهام اینجاست که ما در این خط داریم
کد:
public event EventHandler<CarEventArgs> Exploded;
public event EventHandler<CarEventArgs> AboutToBlow
;
یعنی Exploded و AboutToBlow از نوع CarEventArgs هستند که یک پارامتر در سازنده میگیرد. اما در خط دیگر وقتی این متغیر را صدا زدیم ،
کد:
Exploded?.Invoke(this, new CarEventArgs("Sorry, this car is dead..."));
دو پارامتر فرستادیم، همان متدی که تو برنامه اصلی بهش داده شده. سوال اینجاست ما وقتی نوع داده رو انتخاب میکنیم که اینجا CarEventArgs هست، مگر Type-Safe نمی شود و ملزم به رعایت امضا اون هستیم ؟(پارامتر و نوع داده برگشتی؟) پس چطور یک تابع با مشخصات دیگر بهش داده میشه
سوال دوم اینکه خط زیر ابهام داره ، خط های قبل رو بهتر درک کردم و قانون هاش رو فهمیدم اما منطق این رو نمیفهمم...
کد:
EventHandler<CarEventArgs> d = new EventHandler<CarEventArgs>(CarExploded);
c1.Exploded += d
;