Есть ли более сокращенный способ определения пользовательского события в C # 3 и C # 4? - PullRequest
3 голосов
/ 12 мая 2010

В следующем примере консольного приложения событие определяется следующим образом:

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);
        }
    }
}

Ответы [ 3 ]

9 голосов
/ 12 мая 2010

Всегда определяйте такие события, не используйте пользовательских делегатов:

event EventHandler<EventArgsClassType> MyEventHandler;

или, если они не принимают аргументов:

event EventHandler MyEventHandler;

Основываясь на классе System.EventHandler, это обеспечивает единую подпись для всех событий, следуя рекомендациям .NET.

Если ваше событие принимает дополнительные аргументы, его EventArgsClassType должно наследоваться от System.EventArgs.


Кроме того, при создании экземпляра обработчика событий вам не нужно использовать эту явную форму:

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

поскольку группы методов могут быть неявно преобразованы в соответствующие делегаты. Как следствие, следующий код работает так же хорошо:

product1.OnPurchaseMade += NotifyUser;
3 голосов
/ 12 мая 2010

Попробуйте это:

public event EventHandler<PurchaseArgs> OnPurchaseMade;

Кроме того, такие строки:

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

Можно упростить:

product1.OnPurchaseMade += NotifyUser;
1 голос
/ 12 мая 2010

Сначала вы можете использовать шаблон EventHandler для создания делегата, поэтому ваш код будет:

public event EventHandler<PurchaseArgs> OnPurchaseMade;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...