In the following console application example, the event is defined like this:
public delegate void PurchaseHandler(object obj, PurchaseArgs args);
public event PurchaseHandler OnPurchaseMade;
It seems to me after reading around that this might be a bit "C#2".
Is there a more abbreviated way to express this with C#3 and C#4?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestEvents288202
{
class Program
{
static void Main(string[] args)
{
Product product1 = Product.LoadProduct(222);
EmailManager.NotifyAdministrator(product1);
product1.OnPurchaseMade += new Product.PurchaseHandler(NotifyUser);
product1.Purchase();
Product product2 = Product.LoadProduct(333);
EmailManager.NotifyAdministrator(product2);
product2.OnPurchaseMade += new Product.PurchaseHandler(NotifyUser);
product2.Purchase();
Console.ReadLine();
}
static void NotifyUser(object sender, PurchaseArgs e)
{
((Product)sender).Log();
Console.WriteLine(e.Message);
}
}
public static class EmailManager
{
public static void NotifyAdministrator(Product product)
{
product.OnPurchaseMade += new Product.PurchaseHandler(SendEmail);
}
public static void SendEmail(object sender, PurchaseArgs e)
{
Product product = sender as Product;
Console.WriteLine("Just sent e-mail to administrator notifying of purchase of article {0}", product.ProductNumber);
}
}
public class PurchaseArgs : EventArgs
{
public string Message { get; set; }
public PurchaseArgs(string message)
{
Message = message;
}
}
public class Product
{
public int ProductNumber { get; set; }
开发者_运维问答 public string Name { get; set; }
public string Description { get; set; }
public delegate void PurchaseHandler(object obj, PurchaseArgs args);
public event PurchaseHandler OnPurchaseMade;
public static Product LoadProduct(int productNumber)
{
List<Product> products = new List<Product>();
products.Add(new Product { ProductNumber = 111, Name = "Intel CPU", Description = "Newest model, very fast." });
products.Add(new Product { ProductNumber = 222, Name = "Philips Monitor", Description = "22-inch, very nice." });
products.Add(new Product { ProductNumber = 333, Name = "Sony Camera", Description = "10 Megapixels, sharp pictures." });
return products.Where(p => p.ProductNumber == productNumber).SingleOrDefault();
}
public void Purchase()
{
PurchaseArgs purchaseArgs = new PurchaseArgs(String.Format("The product \"{0}\" was just purchased.", this.Name));
OnPurchaseMade(this, purchaseArgs);
}
public void Log()
{
Console.WriteLine("Log: #{0} purchased.", this.ProductNumber);
}
}
}
Always define events like this, don’t use custom delegates:
event EventHandler<EventArgsClassType> MyEventHandler;
or, if they don’t take arguments:
event EventHandler MyEventHandler;
By being based on the System.EventHandler
class, this ensures a uniform signature for all events, following the .NET guidelines.
If your event takes further arguments, its EventArgsClassType
must inherit from System.EventArgs
.
Furthermore, when instantiating an event handler, you don’t have to use this explicit form:
product1.OnPurchaseMade += new Product.PurchaseHandler(NotifyUser);
since method groups can be implicitly converted to matching delegates. As a consequence, the following code works just as well:
product1.OnPurchaseMade += NotifyUser;
Try this:
public event EventHandler<PurchaseArgs> OnPurchaseMade;
Also, lines like this:
product1.OnPurchaseMade += new Product.PurchaseHandler(NotifyUser);
Can be simplified:
product1.OnPurchaseMade += NotifyUser;
At first, you could use the EventHandler template to create the delegate, so your code would be:
public event EventHandler<PurchaseArgs> OnPurchaseMade;
精彩评论