Событие может появляться только в левой части + = или - + [duplicate]

Мой способ может быть неправильным, но полезным

Преобразовать как float в строки, так и выполнить сравнение строк

bool IsFlaotEqual(float a, float b, int decimal)
{
    TCHAR form[50] = _T("");
    _stprintf(form, _T("%%.%df"), decimal);


    TCHAR a1[30] = _T(""), a2[30] = _T("");
    _stprintf(a1, form, a);
    _stprintf(a2, form, b);

    if( _tcscmp(a1, a2) == 0 )
        return true;

    return false;

}

оператор-переаполяция также

132
задан jwarzech 16 April 2009 в 14:58
поделиться

5 ответов

Что вам нужно сделать, это:

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

public class MyClass
{
   public event EventHandler Loading;
   public event EventHandler Finished;

   protected virtual void OnLoading(EventArgs e)
   {
       EventHandler handler = Loading;
       if( handler != null )
       {
           handler(this, e);
       }
   }

   protected virtual void OnFinished(EventArgs e)
   {
       EventHandler handler = Finished;
       if( handler != null )
       {
           handler(this, e);
       }
   }
}

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

Затем в классах, которые наследуются от этого базового класса, вы можете просто вызовите методы OnFinished или OnLoading, чтобы поднять события:

public AnotherClass : MyClass
{
    public void DoSomeStuff()
    {
        ...
        OnLoading(EventArgs.Empty);
        ...
        OnFinished(EventArgs.Empty);
    }
}
144
ответ дан Frederik Gheysels 21 August 2018 в 05:46
поделиться
  • 1
    Эти методы должны быть защищены виртуальными, если нет причин для этого. – Max Schmeling 16 April 2009 в 15:07
  • 2
    Почему это должно быть виртуальным? Я бы объявил его виртуальным, если бы хотел, чтобы наследники меняли способ создания события, но большую часть времени я не вижу причин для этого ... – Frederik Gheysels 16 April 2009 в 15:12
  • 3
    Официальные рекомендации: msdn.microsoft.com/en-us/library/w369ty8x (VS.80) .aspx – meandmycode 16 April 2009 в 15:17
  • 4
    Что касается того, чтобы сделать метод виртуальным, чтобы наследники могли переопределить поведение вызова события: сколько раз вы были в ситуации, когда это было необходимо? Рядом с этим; в методе overriden вы не можете поднять событие, так как вы получите ту же ошибку, что и указанная TS. – Frederik Gheysels 16 April 2009 в 15:31
  • 5
    @Verax Я следую за ним, потому что рассуждение звучит, в зависимости от того, насколько я могу использовать его повторно и расширяемо. Я предлагал официальные рекомендации, чтобы поддержать это. На момент написания вы также выглядели очень новыми для .NET Verax так что это немного озадачивает, что вы выкопали это, чтобы не согласиться с моим 7-летним опытом – meandmycode 1 March 2012 в 23:47

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

public event EventHandler MyPropertyChanged;

на самом деле делает это:

private EventHandler myPropertyChangedDelegate;

public event EventHandler MyPropertyChanged
{
    add { myPropertyChangedDelegate += value; }
    remove { myPropertyChangedDelegate -= value; }
}

и делает это ...

MyPropertyChanged(this, EventArgs.Empty);

на самом деле это .. .

myPropertyChangedDelegate(this, EventArgs.Empty);

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

Соглашение должно предоставить что-то подобное в объявляющем классе. .

protected virtual void OnMyPropertyChanged(EventArgs e)
{
    EventHandler invoker = MyPropertyChanged;

    if(invoker != null) invoker(this, e);
}

Вы можете вызвать OnMyPropertyChanged(EventArgs.Empty) из любого места этого класса или ниже иерархии наследования для вызова события.

114
ответ дан Adam Robinson 21 August 2018 в 05:46
поделиться
  • 1
    У меня были некоторые проблемы с реализацией этого ... stackoverflow.com/q/10593632/328397 – AccidentallyObtuse 15 May 2012 в 04:07
  • 2
    Я предпочитаю этот ответ, поскольку он объясняет, почему вы должны использовать этот подход, а не только подход. Хорошая работа. – cowboydan 24 July 2018 в 18:24

Я предполагаю, что я не могу получить доступ к этим событиям так же, как другие унаследованные элементы?

Точно. Для каждого события в базовом классе принято предоставлять защищенную функцию OnXyz или RaiseXyz, чтобы включить повышение из унаследованных классов. Например:

public event EventHandler Loading;

protected virtual void OnLoading() {
    EventHandler handler = Loading;
    if (handler != null)
        handler(this, EventArgs.Empty);
}

Вызывается в унаследованном классе:

OnLoading();
7
ответ дан Konrad Rudolph 21 August 2018 в 05:46
поделиться

Вы можете попробовать так, это работает для меня:

public delegate void MyEventHaldler(object sender, EventArgs e);

public class B
{
    public virtual event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}

public class D : B
{
    public override event MyEventHaldler MyEvent;
    protected override void OnChanged(EventArgs e)
    {
        if (MyEvent != null)
            MyEvent(this, e);
    }
}
0
ответ дан Olioul Islam Rahi 21 August 2018 в 05:46
поделиться
  • 1
    Обратите внимание, что в этой статье запрещается объявлять виртуальные события и переопределять их, поскольку он утверждает, что компилятор не справляется с этим правильно: msdn.microsoft.com/en-us/library/hy3sefw3.aspx – public wireless 13 February 2015 в 21:56
0
ответ дан Zeraphil 1 November 2018 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: