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

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

здесь некоторый код для ссылки, если это помогает объяснению:

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 ответов


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

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

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

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


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


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

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

хорошим примером является система.ИО.Каталог и система.ИО.Классы DirectoryInfo.

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

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

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

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

теперь на static событий...

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

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

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

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

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

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


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

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

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

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

больше info

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


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

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