Как статические события сравниваются с нестатистическими событиями в С#?
Я просто понял, что существуют статические события, и мне любопытно, как люди их используют. Интересно, как относительное сравнение относится к методам статического и экземпляра. Например, статический метод в основном является глобальной функцией. Но я всегда ассоциировал события с экземплярами объектов, и у меня возникли проблемы с их восприятием на глобальном уровне.
Вот несколько кодов для ссылки, если это поможет объяснить:
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
Статические члены не являются "глобальными", они просто являются членами класса, а не экземплярами класса. Это так же справедливо для событий, как для методов, свойств, полей и т.д.
Я не могу привести пример использования статического события, потому что обычно я не считаю, что статические члены полезны в большинстве случаев. (Они склонны намекать на анти-шаблоны, например, Синглтон.)