Как статические события сравниваются с нестатическими событиями в C #? - PullRequest
15 голосов
/ 12 августа 2011

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

Вот код, на который можно сослаться, если это поможет объяснению:1005 *

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

Ответы [ 5 ]

45 голосов
/ 13 августа 2011

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

14 голосов
/ 13 августа 2011

Большая часть ООП может рассматриваться с точки зрения передачи сообщений.

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

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

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

3 голосов
/ 13 августа 2011

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

Возможно, вы уже знакомы со статическими методами.Если это не так, разница, которая легко понять, заключается в том, что вам не нужно создавать экземпляр объекта, чтобы использовать статический метод, но вам НЕОБХОДИМО создать экземпляр объекта для вызова не-объекта.статический метод.

Хорошим примером являются классы 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/

Теперь перейдем к статическому события ...

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

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

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

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

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

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

2 голосов
/ 13 августа 2011

для некоторого понимания проверьте эту ссылку 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

0 голосов
/ 12 августа 2011

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

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

...