В чем разница между делегатами и событиями?

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

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

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

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

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

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

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

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

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

в последней visual-c# строке кода я переопределил visual-c# предыдущее поведение только events с одним отсутствующим +.cs-file использовал = вместо +=)

Еще func-delegate одним слабым местом является delegates то, что каждый класс, использующий csharp ваш класс Animal, может напрямую glossary вызывать делегата. Например, animal.Run() или c# animal.Run.Invoke() допустимы за пределами класса func-delegate Animal.

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

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

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

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

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

Различия:

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

Примечания:

EventHandler csharp объявлен как следующий делегат:

public delegate void EventHandler (object sender, EventArgs e)

он c# принимает аргументы отправителя visual-c# (типа Object) и события. Отправитель c#-language имеет значение NULL, если c#-language он исходит из статических visual-c# методов.

Этот пример, в котором c-sharp используется EventHandler, также может c#.net быть написан с использованием c#-language вместо него EventHandler.

Обратитесь к c#-language here за документацией по EventHandler

c#

events

delegates

glossary

2022-11-19T22:42:18+00:00