我可以在此代码中使用其他东西代替 "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");
}
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");
}