在类中引发事件,在另一个中调用它并将其附加到第3个

时间:2015-12-22 03:06:57

标签: c# events handlers

您好我搜索了一段时间,但无法找到问题的解决方案。而且我100%确定解决方案只是一行简单的代码,我无法弄清楚;( ...所以我这里有一个带有委托AlarmHandler和事件AlarmEvent8的类在方法IncreaseHoursBy1中引发事件

class Clock
{
    public delegate void AlarmHandler(string info);

    public event AlarmHandler AlarmEvent8;


    private int minutes;
    private int hours;

    public int Minutes
    {
        get { return minutes; }
    }
    public int Hours
    {
        get { return hours; }
    }

    public Clock(int minutes, int hours)
    {
        this.minutes = minutes;
        this.hours = hours;
    }

    public void IncreaseHoursBy1()
    {
        this.hours += 1;
        if(this.hours == 8)
        {
            if(AlarmEvent8 != null)
            {
                this.AlarmEvent8("Time to wake up!");
            }
        }
    }

现在我想在另一个类中为事件创建一个处理程序:

 class Person
{
    private string name;

    public Person(string name)
    {
        this.name = name;
    }

    public string EventHandler(string info)
    {
        return this.name + " " + info;

    }


}

最后我想在Form1的构造函数中将Handler附加到Event中,但我不知道我的Form1构造函数是什么

    Clock myClock;
    Person Me;
    public Form1()
    {
        InitializeComponent();
        myClock = new Clock(50, 2);
        Me = new Person("RandomPerson");

        myClock.AlarmEvent8 += new Clock.AlarmHandler(Me.EventHandler(info));
    }

我目前所拥有的是给我一个错误" info"还不存在。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

您通常会像这样连接处理程序:

myClock.AlarmEvent8 += new Clock.AlarmHandler(Me.EventHandler);

请注意,info变量是在调用处理程序时传递的内容,而不是在您添加处理程序时。

但是,在这种情况下,您会收到此语法错误:

  

CS0407' string Person.EventHandler(string)'有错误的返回类型

你在这里有点奇怪。您的delegate定义为:

public delegate void AlarmHandler(string info);

然而,您尝试附加的处理程序具有此签名:

public string EventHandler(string info)

请注意,前者的返回类型为void,后者的返回类型为string。他们不兼容。

因此,您必须更改delegate的签名或处理程序方法才能使它们匹配。

执行此操作的正常方法是同时返回void。在这种情况下,Person中的处理程序方法必须编写如下:

public void EventHandler(string info)
{
    Console.WriteLine(this.name + " " + info);
}

您无法再返回某个值,因此您必须以某种方式处理该事件。我已经选择将值写入控制台。

但是,如果您更改委托以返回string,那么您将能够在事件引发代码中处理返回值,如下所示:

public void IncreaseHoursBy1()
{
    this.hours += 1;
    if (this.hours == 8)
    {
        if (AlarmEvent8 != null)
        {
            Console.WriteLine(this.AlarmEvent8("Time to wake up!"));
        }
    }
}

现在,如果我使用以下代码运行这些变体中的任何一个:

var myClock = new Clock(50, 2);
var Me = new Person("RandomPerson");

myClock.AlarmEvent8 += new Clock.AlarmHandler(Me.EventHandler);

myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();

我得到以下输出:

RandomPerson Time to wake up!

但是,这段代码的不同之处在于:

var myClock = new Clock(50, 2);
var Me1 = new Person("Person 1");
var Me2 = new Person("Person 2");

myClock.AlarmEvent8 += new Clock.AlarmHandler(Me1.EventHandler);
myClock.AlarmEvent8 += new Clock.AlarmHandler(Me2.EventHandler);

myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();

如果我使用void - 返回delegate代码运行此代码,我会收到此输出:

Person 1 Time to wake up!
Person 2 Time to wake up!

如果我使用string-returning委托代码运行它,我只能得到这个:

Person 2 Time to wake up!

如果将多个处理程序附加到返回值的事件,则只传回最后一个委托的返回值 - 即使两个处理程序都已运行。

你真的应该坚持使用void - 回复代表。

Vikhram提出的另一个选择是使用原始代码并执行此操作:

myClock.AlarmEvent8 += new Clock.AlarmHandler(info => Me.EventHandler(info));

但是,这会抛弃Me.EventHandler(info)调用的返回值。在这里使用返回值做这样的事情会很有用:

myClock.AlarmEvent8 += new Clock.AlarmHandler(info => Console.WriteLine(Me.EventHandler(info)));

所以,如果我现在转到这个代码:

var myClock = new Clock(50, 2);
var Me1 = new Person("Person 1");
var Me2 = new Person("Person 2");

myClock.AlarmEvent8 += new Clock.AlarmHandler(info => Console.WriteLine(Me1.EventHandler(info)));
myClock.AlarmEvent8 += new Clock.AlarmHandler(info => Console.WriteLine(Me2.EventHandler(info)));

myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();
myClock.IncreaseHoursBy1();

运行它,我得到这个输出:

Person 1 Time to wake up!
Person 2 Time to wake up!

我认为,你可能想做什么。

这三种不同的方法表明您可以在三个不同的位置处理public string EventHandler(string info)中计算的结果。您最好决定哪种方式最适合您。

答案 1 :(得分:-2)

你不需要那里的信息。该行应如下所示

myClock.AlarmEvent8 += new Clock.AlarmHandler(info => Me.EventHandler(info));

此外,您可以更改EventHandler本身以不返回任何内容(通常是如何完成的)

public void EventHandler(string info)
myClock.AlarmEvent8 += new Clock.AlarmHandler(Me.EventHandler);