Событие всегда пустое, поэтому не может быть обработано

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

import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]

Если вы хотите найти совпадающие совпадения, lookahead будет делать это:

[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]

Если вы хотите иметь обратную find-all без перекрытий, вы можете комбинировать положительный и отрицательный lookahead в выражении типа это:

search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]

re.finditer возвращает генератор , поэтому вы можете изменить [] выше, на (), чтобы получить генератор вместо списка, который будет более эффективен, если вы только итерации через результаты один раз.

2
задан Explorex 17 January 2019 в 05:25
поделиться

3 ответа

C.Connect() не вызывается, и это необходимо, поскольку именно здесь вы регистрируете EventHandler, который вызывает this.sender_PageSwap. Без этого ничего не произойдет.

0
ответ дан Cam Bruce 17 January 2019 в 05:25
поделиться

Как работают события и проблема с вашим кодом

События - это оболочка поверх Delegate, которая обеспечивает безопасный тип доступа, без возможности повредить делегировать состояние объекта. В вашем случае class A инициирует регистрацию события посредством вызова метода OnPageSwap, определенного в классе B, который в первую очередь должен вызвать метод Connect в классе C, который выполняет регистрацию события PageSwap и должен использовать тот же экземпляр объекта B, который используется для вызова метода Connect, так что регистрация событий может быть подключена и, таким образом, вызвана, new object B не требуется в Class C. Экземпляр может быть передан в методе или в конструкторе. Мой пример кода делает это в методе Connect(B sender)

Простыми словами

Вы не вызываете метод Connect в [ 1110], а затем регистрация события внутри Connect method должна быть тем же объектом из Class B. Также дизайн события некорректен, так как он не является потокобезопасным и объект может быть поврежден. Событие должно быть выставлено через аксессор.

Ниже приводится рабочая версия кода, включая тестовую консоль

void Main()
{
    new A().Button_Click(this, new RoutedEventArgs());
}

public class A
{
    public void Button_Click(object sender, RoutedEventArgs startEventArgs)
    {
        B senders = new B();
        senders.OnPageSwap(new StartEventArgs());
    }
}

public delegate void StartEventHandler(object sender, StartEventArgs e);

public class B
{
    private event StartEventHandler _PageSwap;

    private readonly object _lock = new Object();

    // Event Access via thread safe accessor
    public event StartEventHandler PageSwap
    {
        add
        {
            lock (_lock)
            {
                 _PageSwap += value;
            }
        }

        remove
        {
            lock (_lock)
            {
                 _PageSwap -= value;
            }
        }
    }

    public virtual void OnPageSwap(StartEventArgs e)
    {
        Console.WriteLine("Entered PageSwapSender");
        var c = new C();
        c.Connect(this);
        if (_PageSwap != null) _PageSwap(this, e);
    }
}

public class C
{

    public void Connect(B sender)
    {
        sender.PageSwap += new StartEventHandler(this.sender_PageSwap);
        Console.WriteLine("Entered Connect");
    }

    private void sender_PageSwap(object sender, StartEventArgs e)
    {
        Console.WriteLine("Entered Handler");
    }
}

public class StartEventArgs : EventArgs
{

}

Изменения: [ 1127]

  1. Изменено определение метода Connect на public void Connect(B sender), так что class C получает тот же объект класса B, который вызывает метод Connect внутри public virtual void OnPageSwap(StartEventArgs e) из Class B ]
  2. Создано StartEventArgs в качестве заполнителя, который может быть заменен реальным кодом
  3. Предоставлена ​​тестовая консоль для проверки вызова рабочего процесса / события
[1128 ] Результат:

Entered PageSwapSender
Entered Connect
Entered Handler

Редактировать 1:

Рядом с неверным доступом для событие, в котором не используется тот же объект, дизайн события имеет недостатки, его необходимо предоставлять через потоковый метод доступа, рассмотрим последнюю модификацию кода, где событие PageSwap предоставляется через потоковую оболочку

0
ответ дан Mrinal Kamboj 17 January 2019 в 05:25
поделиться

Проблема с вашим кодом в том, что вы создаете два отдельных экземпляра класса B. В A вы пытаетесь вызвать событие в одном случае B. В C вы пытаетесь обработать событие, вызванное , используя экземпляр разности B .

Кажется, что вы пытались сделать правильную вещь, создав метод Connect в C, но именно здесь вы должны передать существующий экземпляр B до C [ 1114].

Если бы вы написали свой код так, он бы работал:

class A
{   
    public void Button_Click(object sender, RoutedEventArgs e)
    {
        B senders = new B();
        C c = new C();
        c.Connect(senders);
        senders.OnPageSwap(new StartEventArgs());
    }
}

public delegate void StartEventHandler(object sender, StartEventArgs e);
public class B
{
    public event StartEventHandler PageSwap;
    public virtual void OnPageSwap(StartEventArgs e)
    {
        Console.WriteLine("Entered PageSwapSender");
        if (PageSwap != null) PageSwap(this, e);
    }
}

class C
{
    public void Connect(B sender)
    {
        sender.PageSwap += new StartEventHandler(this.sender_PageSwap);
        Console.WriteLine("Entered Connect");
    }

    private void sender_PageSwap(object sender, StartEventArgs e)
    {
        Console.WriteLine("Entered Handler");
    }
}
0
ответ дан Enigmativity 17 January 2019 в 05:25
поделиться
Другие вопросы по тегам:

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