Как статические события сравниваются с нестатистическими событиями в С#?

Я просто понял, что существуют статические события, и мне любопытно, как люди их используют. Интересно, как относительное сравнение относится к методам статического и экземпляра. Например, статический метод в основном является глобальной функцией. Но я всегда ассоциировал события с экземплярами объектов, и у меня возникли проблемы с их восприятием на глобальном уровне.

Вот несколько кодов для ссылки, если это поможет объяснить:

void Main()
{
    var c1 = new C1();
    c1.E1 += () => Console.WriteLine ("E1");
    C1.E2 += () => Console.WriteLine ("E2");
    c1.F1();
}

// <<delegate>>+D()
public delegate void D();

// +<<event>>E1
// +<<class>><<event>>E2
// +F()
//      <<does>>
//          <<fire>>E1
//          <<fire>>E2
public class C1
{
    public void F1()
    {
        OnE1();
        OnE2();
    }
    public event D E1;
    private void OnE1()
    {
        if(E1 != null)
        {
            E1();
        }
    }
    static public event D E2;
    static private void OnE2()
    {
        if(E2 != null)
        {
            E2();
        }
    }
}

Ответы

Ответ 1

Многое из ООП можно рассматривать в терминах передачи сообщений.

Вызов метода - это сообщение от вызывающего абонента (несущего параметры) и сообщение с возвращаемым значением.

Событие - это сообщение от источника к подписчику. Таким образом, возможно, задействованы два экземпляра, один отправляет сообщение и тот, кто его получает.

Со статическим событием отсутствует экземпляр отправки (только тип, который может быть или не быть классом). Все еще может быть экземпляр получателя, закодированный как цель делегата.

Ответ 2

Будьте осторожны с статическими событиями. Помните, что когда объект подписывается на событие, ссылка на этот объект хранится издателем события. Это означает, что вы должны быть очень осторожны в явной отмене подписки на статические события, так как они будут поддерживать подписчика навсегда, т.е. Вы можете получить управляемый эквивалент утечки памяти.

Ответ 3

Если вы не знакомы со статическими методами

Вероятно, вы уже знакомы со статическими методами. В случае, если вы этого не сделаете, легко понять, что вам не нужно создавать экземпляр объекта toi, используя статический метод, но вам нужно создать экземпляр объекта для вызова не- статический метод.

Хорошим примером являются классы System.IO.Directory и System.IO.DirectoryInfo.

Класс Directory предлагает статические методы, а класс DirectoryInfo - нет.

Здесь есть две статьи, описывающие их, чтобы вы могли увидеть разницу для себя.

http://visualcsharptutorials.com/2011/01/system-io-directory-class/

http://visualcsharptutorials.com/2011/01/system-io-directoryinfo-class/

Теперь на статические события...

Однако статические события редко встречаются в дикой природе. Есть очень мало случаев, когда я могу думать о opf, где я действительно хотел бы использовать его, но есть статья CodeProject, которая показывает одно потенциальное использование.

http://www.codeproject.com/KB/cs/staticevent.aspx

Ключевая мысль здесь взята из объяснения (жирный текст добавлен мной, чтобы указать соответствующий текст):

Мы видели это свойство как отдельный объект, и мы убедились, что там это только один экземпляр этого за раз. И все случаи транзакции знали, где их найти, когда это необходимо. Существует штраф разница. Транзакции не нужно знать о изменения происходят по обменному курсу, скорее они будут использовать последние измененное значение в то время, когда они используют его, запрашивая текущий стоимость. Этого недостаточно, если, например, мы хотим реализовать приложение, в котором пользовательский интерфейс немедленно реагирует на изменения в характеристики пользовательского интерфейса, такие как шрифт, как будто это должно произойти в в режиме реального времени. Было бы очень легко, если бы у нас было статическое свойство в классе Font под названием currentFont и статическом методе изменения это значение и статическое событие для всех экземпляров, чтобы сообщить им, когда им необходимо обновить их внешний вид.

Как разработчики .NET, мы обучаемся работе с отключенной моделью. Подумайте об ADO.NET по сравнению с классическим ADO. В приложении VB6 вы можете использовать элементы управления данными, которые позволят использовать следующие функции: если вы запускали приложение на своем ПК, данные в вашей сетке обновлялись, когда кто-то на другом ПК редактировал данные.

Это не то, к чему привыкли разработчики .NET. Мы очень привыкли к отключенной модели. Статические события позволяют использовать более "подключенный" опыт. (даже если этот опыт - это то, к чему мы больше не привыкли).

Ответ 4

для некоторой проницательности проверьте эту ссылку http://www.codeproject.com/KB/cs/staticevent.aspx

может использоваться статическое событие

  • когда не существует экземпляра
  • выполнить многоадресное событие для всех существующих экземпляров...
  • когда у вас есть статический класс, способный запускать события...

НО нужно использовать их с уклоном... см. обсуждение http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/2ac862f346b24a15/8420fbd9294ab12a%238420fbd9294ab12a?sa=X&oi=groupsr&start=1&num=2

подробнее

http://msdn.microsoft.com/en-us/library/8627sbea.aspx
http://dylanbeattie.blogspot.com/2008/05/firing-static-events-from-instance.html
http://www.nivisec.com/2008/09/static-events-dont-release.html

Ответ 5

Статические члены не являются "глобальными", они просто являются членами класса, а не экземплярами класса. Это так же справедливо для событий, как для методов, свойств, полей и т.д.

Я не могу привести пример использования статического события, потому что обычно я не считаю, что статические члены полезны в большинстве случаев. (Они склонны намекать на анти-шаблоны, например, Синглтон.)