c# - 在 C#3 和 C#4 中是否有更简洁的方法来定义自定义事件?

标签 c# events delegates

在下面的控制台应用程序示例中,事件 定义如下:

public delegate void PurchaseHandler(object obj, PurchaseArgs args);
public event PurchaseHandler OnPurchaseMade;

在阅读之后我觉得这可能有点“C#2”。

是否有更简洁的方式用 C#3 和 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);
        }
    }
}

最佳答案

总是这样定义事件,不要使用自定义委托(delegate):

event EventHandler<EventArgsClassType> MyEventHandler;

或者,如果他们不接受参数:

event EventHandler MyEventHandler;

基于 System.EventHandler类,这确保了所有事件的统一签名,遵循 .NET 准则。

如果您的事件需要更多参数,则其 EventArgsClassType 必须继承自 System.EventArgs


此外,在实例化事件处理程序时,您不必使用这种显式形式:

product1.OnPurchaseMade += new Product.PurchaseHandler(NotifyUser);

因为方法组可以隐式转换为匹配的委托(delegate)。因此,以下代码同样有效:

product1.OnPurchaseMade += NotifyUser;

关于c# - 在 C#3 和 C#4 中是否有更简洁的方法来定义自定义事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2820054/

相关文章:

c# - 将枚举元素作为事件参数传递 C#

c# - 保持在 C# 和 JS 中实现的相同逻辑同步

c# - .NET 在服务器上创建计划任务失败并显示 E_ACCESSDENIED

javascript - 处理 keydown 事件中的某些键时遵循默认行为

javascript - 当我的javascript打开的窗口关闭时如何捕获事件

c# - 为什么委托(delegate)可以互换用于类方法和静态函数?

ios - 在 Objective-c 问题中访问委托(delegate)静态方法

c# - 如何将 View 构造函数参数传递给 View 模型

c# - 如何获取 Nullable<T> 实例的类型

javascript - 防止 jQuery click() 冲突