Самый быстрый метод IPC в Windows 7

Чтобы понять различия, вы можете посмотреть на это 2 примера

Пример с делегатами (в данном случае Action - это своего рода делегат, который не возвращает значение)

public class Animal
{
    public Action Run {get; set;}

    public void RaiseEvent()
    {
        if (Run != null)
        {
            Run();
        }
    }
}

Чтобы использовать делегат, вы должны сделать что-то вроде этого:

Animal animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();

Этот код работает хорошо, но у вас могут быть слабые места.

Например, если я напишу это:

animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;

с последней строкой кода, я переопределил предыдущие действия только с одним отсутствующим + (я использовал = вместо +=)

Еще одно слабое место в том, что каждый класс, который использует ваш класс Animal, может поднять RaiseEvent, просто называя его animal.RaiseEvent().

Чтобы избежать этих слабых мест, вы можете использовать events в c #.

Ваш класс Animal изменится следующим образом:

public class ArgsSpecial : EventArgs
{
    public ArgsSpecial (string val)
    {
        Operation=val;
    }

    public string Operation {get; set;}
} 

public class Animal
{
    // Empty delegate. In this way you are sure that value is always != null 
    // because no one outside of the class can change it.
    public event EventHandler Run = delegate{} 

    public void RaiseEvent()
    {  
         Run(this, new ArgsSpecial("Run faster"));
    }
}

для вызова событий

 Animal animal= new Animal();
 animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
 animal.RaiseEvent();

Различия:

  1. Вы не используете публичное свойство, а общедоступное поле (используя события, компилятор защищает ваши поля от нежелательного доступа)
  2. События не могут быть назначены напрямую. В этом случае это не приведет к предыдущей ошибке, которую я показал с переопределением поведения.
  3. Никто из вашего класса не может поднять событие.
  4. События могут быть включенным в объявление интерфейса, тогда как поле не может

Примечания:

EventHandler объявляется следующим делегатом:

public delegate void EventHandler (object sender, EventArgs e)

it принимает отправителя (типа объекта) и аргументы события. Отправитель имеет значение null, если оно исходит из статических методов.

Этот пример, который использует EventHandler, также может быть записан с использованием EventHandler.

Здесь / g0] для документации о EventHandler

37
задан Cartesius00 19 August 2011 в 20:48
поделиться