C #: Что такое виртуальные события и как их можно использовать? - PullRequest
20 голосов
/ 15 июля 2009

Как работает виртуальное событие? Как бы вы переопределили это? Как это будет работать? И в каких случаях вы бы это сделали?

Будет ли это, например, хорошей заменой защищенным методам OnEvent? Чтобы наследующие классы могли просто переопределить событие и вызвать его напрямую? Или это будет неправильно или просто не сработает?

MSDN говорит об этом:

Событие можно пометить как виртуальное событие с помощью ключевого слова virtual. Это позволяет производным классам переопределять поведение события, используя ключевое слово override. Событие, перекрывающее виртуальное событие, также может быть запечатано, что указывает, что для производных классов оно больше не является виртуальным.

Но это не сделало меня намного мудрее. Хотя запечатанный материал очевиден.

Примечание: Я видел Как работают виртуальные события в C #? , но на самом деле речь шла не о том, как работают виртуальные события. Скорее это было то, как этот человек получил результат, который он получил от их использования. Пытался выяснить, какие виртуальные события были из его примера и ответов, но на самом деле не мог понять из этого.

Ответы [ 2 ]

27 голосов
/ 15 июля 2009

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

Довольны ли вы концепцией виртуального свойства с геттером и сеттером, который можно переопределить? Если это так, вы можете думать о виртуальном событии точно так же: вместо метода получения и установки есть операция «добавить» и операция «удалить». Они могут быть виртуальными, поэтому обрабатываются полиморфно. Вы реализуете их так же, как и любой другой виртуальный / переопределенный член.

Пример:

using System;

class Base
{
    public virtual event EventHandler Foo
    {
        add
        {
            Console.WriteLine("Base Foo.add called");
        }
        remove
        {
            Console.WriteLine("Base Foo.remove called");
        }
    }
}

class Derived : Base
{
    public override event EventHandler Foo
    {
        add
        {
            Console.WriteLine("Derived Foo.add called");
        }
        remove
        {
            Console.WriteLine("Derived Foo.remove called");
        }
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();

        x.Foo += (sender, args) => {};
    }
}

Обратите внимание, что само событие не несет ответственности за то, что происходит при его возникновении - только сторона добавления / удаления. (В любом случае, в C #; у самого CLR есть понятие повышения, но мы пока проигнорируем это.)

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

Лично я нахожу очень редким, что я хочу виртуальное событие.

0 голосов
/ 08 октября 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...