我可以在此代码中使用其他东西代替 "this" 吗?

Can I use something else instead of "this" in this code?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Event_training
{
    class Publisher
    {
        public event EventHandler x;

        public void raise()
        {
            x(this, null);
        }

    }

    class Subscriber
    {
        public void method1(object o, EventArgs e)
        {
            Console.WriteLine("metod1 called");
        }

        public void method2(object o, EventArgs e)
        {
            Console.WriteLine("metod2 called");
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Publisher p = new Publisher();
            Subscriber s = new Subscriber();

            p.x += s.method1;
            p.x += s.method2;

            p.raise();
        }
    }
}

很难理解 "this" 关键字。这里的"x(this, null);"指的是什么?我可以用别的东西代替 "this" 吗?

标准模式是

// it's not a public method 
internal void raise()
{
    // local copy for being thread safe
    var localX = x;

    // do not forget to check for null
    if (null != localX)
      localX(this, EventArgs.Empty); // standard EventArgs.Empty, not null
}

请注意,this 是标准模式 的 部分:它显示 哪个 实例(即 this) 引发事件。

this指的是class的当前时刻。

例如:

Publisher publisher = new Publisher();
publisher.raise();

其中 this 是本例中的 publisher 实例。如果我把它展示给你,也许会更清楚: publisher.x(publisher, null);

此外,在您的情况下,甚至没有使用第一个参数。所以也可以写成null, null.

您所说的 object o 通常称为 sender。这是有道理的,因为引发事件的任何对象都通过此参数传递。

如果您想了解有关 this 关键字的更多信息,请参阅 Microsoft 站点 (link)

为什么需要传递 Publisher 的实例?假设您有多个发布者和一个订阅者:

 Publisher p1 = new Publisher() { Name = "Bob" };
 Publisher p2 = new Publisher() { Name = "Joe" };
 Subscriber s = new Subscriber();

您订阅了两个发布者的 x 事件:

 p1.x += s.method1;
 p2.x += s.method1;

现在的问题 - 您如何知道哪个发布者在事件句柄中引发了事件?

public void method1(object o, EventArgs e)
{
    Console.WriteLine("metod1 called");
}

这就是默认 EventHandler 委托有两个参数的原因。第一个通常称为 sender 而不是 o。这样您就可以检查 sender 并了解哪个发布者引发了事件。假设 Publisher 也有 Name 属性:

class Publisher
{
    public event EventHandler x;
    public string Name { get; set; }        

    public void Raise()
    {
       EventHandler x = this.x;
       if (x != null)
          x(this, EventArgs.Empty);
    }
}

现在在事件处理程序中您可以获得发布者的名称,因为您已将发布者实例 (this) 传递给事件处理程序:

public void method1(object sender, EventArgs e)
{
    Publisher publisher = (Publisher)sender;
    Console.WriteLine(publisher.Name + " raised event x");
}

如果您不需要传递任何事件参数和引发事件的对象实例,那么您可以使用其他类型的事件委托。例如。 Action委托没有任何参数。

class Publisher
{
    public event Action x;      

    public void Raise()
    {
       Action x = this.x;
       if (x != null)
          x(); // No parameters
    }
}

处​​理程序将如下所示:

public void method1()
{
    Console.WriteLine("metod1 called");
}