2010-07-11 9 views
5

У меня есть такой код:Как автоматически вызывать событие при вызове функции?

public class Foo 
{ 
    public SomeHandler OnBar; 

    public virtual void Bar() 
    { 
    } 
} 

Foo является базовым классом и для них другие классы могут наследовать от него.
Я бы хотел, чтобы событие OnBar всегда вызывалось, когда вызывается Bar(), даже если он явно не указан внутри бара.
Как это можно сделать?

ответ

9

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

public class Foo 
{ 
    public SomeHandler OnBar; 

    public void Bar() 
    { 
     if (OnBar != null) 
     { 
      OnBar(this, EventArgs.Empty); 
     } 
     BarImpl(); 
    } 

    protected virtual void BarImpl() 
    { 
    } 
} 
+0

В основном реализация шаблона шаблона шаблона + 1 – DanP

+0

Так что это лучший способ? В C++ я бы использовал bind() для создания новой функции из функции вызова события и исходной функции. –

2

Короткий ответ: вы не можете. Не то, что Microsoft дает вам из коробки.

Это, пожалуйста, взгляните на «аспектно-ориентированное программирование» в .NET. Google, что вы можете получить что-то полезное.

Добавлено: Стандартным способом было бы поднять событие в методе Bar(), а затем потребовать, чтобы все производные классы вызывали базовую реализацию. Но вы не можете обеспечить его соблюдение.

1

Прежде всего код, который вы предоставили, не будет компилироваться.
Виртуальные функции должны иметь тело.

Для обеспечения того, чтобы событие было уволено, вы можете сделать что-то подобное.

public class Foo 
{ 
    public SomeHandler OnBar; 

    public void Bar() 
    { 
    OnBar(); (check for nulls) 
    ProtectedBar(); 
    } 

    protected virtual ProtectedBar() 
    { 
    } 
} 
+0

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

+1

Код, который вы предоставили, также не будет скомпилирован - ваша виртуальная функция не имеет типа возврата, а ваш комментарий не является комментарием. –

+0

Я предполагаю, что какой-то значок пропускал вниз для значка. :) –

0

Как сказал Vilx-, лучший способ сделать этот материал - использовать Aspect Oriented Programming.

Это поможет вам с «запутанным кодом» (т. Е. Вызовом события в методе, который не должен иметь этой ответственности) и «разбросанным кодом» (т. Е. Вызывать одно и то же событие во множестве методов, дублируя ваш код).

Вы должны взглянуть на postsharp, он имеет бесплатное издание сообщества.

Смежные вопросы