C# 如何跨对象链处理事件?
如果有,请提供以下信息:C# 如何跨对象链处理事件?,c#,.net,events,event-handling,C#,.net,Events,Event Handling,如果有,请提供以下信息: public static void main() { MyClass1 obj = new MyClass1(); obj.Method1(); } public class MyClass1() { public void Method1() { MyClass2 obj = new MyClass2(); obj.Method1(); } } public class MyClass2() {
public static void main() {
MyClass1 obj = new MyClass1();
obj.Method1();
}
public class MyClass1() {
public void Method1() {
MyClass2 obj = new MyClass2();
obj.Method1();
}
}
public class MyClass2() {
public void Method1() {
MyClass3 obj = new MyClass3();
obj.Method1();
}
}
public class MyClass3() {
public void Method1() {
// Raise event here that is handled in MyClass1?
}
}
MyClass3.Method1()
能否引发在MyClass1
中处理的事件
如果我想实现这一点,将如何编写事件处理代码 事件处理ABC假定您有订阅者和发布者。因此,您可能希望MyClass3具有公共事件,而MyClass1订阅此事件 但是,在您的特定代码中,这种复杂性没有任何意义-最简单的方法就是使用回调函数:
public static void main() {
MyClass1 obj = new MyClass1();
obj.Method1();
}
public class MyClass1{
public void Method1() {
MyClass2 obj = new MyClass2();
obj.Method1(MyEventHandler);
}
public void MyEventHandler() {
//...
}
}
public class MyClass2{
public void Method1(Action callback) {
MyClass3 obj = new MyClass3();
obj.Method1(callback);
}
}
public class MyClass3{
public void Method1(Action callback) {
// Raise event here that is handled in MyClass1?
callback();
}
}
是的,它可以,但是由于每个级别都不知道您链的更深层次,所以您必须在每个类上创建事件。有些人喜欢这样:
public static void main() {
MyClass1 obj = new MyClass1();
obj.MyEvent += (s, e) => { Console.WriteLine("Fired!"); };
obj.Method1();
}
public class MyClass1 {
public void Method1() {
MyClass2 obj = new MyClass2();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass2 {
public void Method1() {
MyClass3 obj = new MyClass3();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass3 {
public void Method1() {
// Raise event here that is handled in MyClass1?
OnMyEvent();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
using System;
using System.Windows.Forms;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
MyClass1 obj = new MyClass1();
obj.Method1();
}
}
public class MyClass1
{
public void Method1()
{
MyClass2 obj = new MyClass2();
obj.SomethingHappened += somethingHappened;
obj.Method1();
}
private static void somethingHappened(object sender, EventArgs e)
{
Console.WriteLine("Something happened!");
}
}
public class MyClass2
{
public void Method1()
{
MyClass3 obj = new MyClass3();
obj.SomethingHappened += onSomethingHappened;
obj.Method1();
}
public event EventHandler SomethingHappened;
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, e);
}
}
}
public class MyClass3
{
public void Method1()
{
onSomethingHappened();
}
private void onSomethingHappened()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, new EventArgs());
}
}
public event EventHandler SomethingHappened;
}
}
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(sender, e);
}
}
您可以将事件添加到中间类,以便将事情连接起来。大概是这样的:
public static void main() {
MyClass1 obj = new MyClass1();
obj.MyEvent += (s, e) => { Console.WriteLine("Fired!"); };
obj.Method1();
}
public class MyClass1 {
public void Method1() {
MyClass2 obj = new MyClass2();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass2 {
public void Method1() {
MyClass3 obj = new MyClass3();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass3 {
public void Method1() {
// Raise event here that is handled in MyClass1?
OnMyEvent();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
using System;
using System.Windows.Forms;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
MyClass1 obj = new MyClass1();
obj.Method1();
}
}
public class MyClass1
{
public void Method1()
{
MyClass2 obj = new MyClass2();
obj.SomethingHappened += somethingHappened;
obj.Method1();
}
private static void somethingHappened(object sender, EventArgs e)
{
Console.WriteLine("Something happened!");
}
}
public class MyClass2
{
public void Method1()
{
MyClass3 obj = new MyClass3();
obj.SomethingHappened += onSomethingHappened;
obj.Method1();
}
public event EventHandler SomethingHappened;
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, e);
}
}
}
public class MyClass3
{
public void Method1()
{
onSomethingHappened();
}
private void onSomethingHappened()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, new EventArgs());
}
}
public event EventHandler SomethingHappened;
}
}
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(sender, e);
}
}
<> P>你可能想考虑的是你在中介类中如何处理“发送者”参数。您可以将其设置为MyClass2(如上面的代码所示),也可以保留原始发件人,如下所示:
public static void main() {
MyClass1 obj = new MyClass1();
obj.MyEvent += (s, e) => { Console.WriteLine("Fired!"); };
obj.Method1();
}
public class MyClass1 {
public void Method1() {
MyClass2 obj = new MyClass2();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass2 {
public void Method1() {
MyClass3 obj = new MyClass3();
obj.MyEvent += (s, e) => { OnMyEvent(); };
obj.Method1();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
public class MyClass3 {
public void Method1() {
// Raise event here that is handled in MyClass1?
OnMyEvent();
}
public event EventHandler MyEvent;
private void OnMyEvent() {
var myEvent = MyEvent;
if (myEvent != null)
myEvent(this, EventArgs.Empty);
}
}
using System;
using System.Windows.Forms;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
MyClass1 obj = new MyClass1();
obj.Method1();
}
}
public class MyClass1
{
public void Method1()
{
MyClass2 obj = new MyClass2();
obj.SomethingHappened += somethingHappened;
obj.Method1();
}
private static void somethingHappened(object sender, EventArgs e)
{
Console.WriteLine("Something happened!");
}
}
public class MyClass2
{
public void Method1()
{
MyClass3 obj = new MyClass3();
obj.SomethingHappened += onSomethingHappened;
obj.Method1();
}
public event EventHandler SomethingHappened;
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, e);
}
}
}
public class MyClass3
{
public void Method1()
{
onSomethingHappened();
}
private void onSomethingHappened()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, new EventArgs());
}
}
public event EventHandler SomethingHappened;
}
}
private void onSomethingHappened(object sender, EventArgs e)
{
var handler = SomethingHappened;
if (handler != null)
{
handler(sender, e);
}
}
要链接事件处理程序,请使用MyClass2中的添加/删除语法。在MyClass1中,设置一些事件,在MyClass3中,引发它
public class MyClass1
{
MyClass2 obj = new MyClass2();
public MyClass1()
{
obj.SomeEvent += obj_SomeEvent;
}
public void Method1()
{
obj.Method1();
}
private static void obj_SomeEvent(object sender, EventArgs e)
{
Console.WriteLine("Some event fired");
}
}
public class MyClass2()
{
MyClass3 cls3 = new MyClass3();
public void Method1()
{
cls3.FireSomeEvent();
}
public event MyEventHandler SomeEvent
{
add { this.cls3.SomeEvent += value; }
remove { this.cls3.SomeEvent -= value; }
}
}
public class MyClass3()
{
public event EventHandler SomeEvent;
private void OnSomeEvent()
{
if (SomeEvent!= null)
{
SomeEvent(this, new EventArgs());
}
}
public void FireSomeEvent
{
OnSomeEvent();
}
}
如果要避免回调解决方案和每个类中的事件链,基本上有两种解决方案 第一种方法是将MyClassX类型的局部变量转换为字段,如Chris Gessler所建议的,但完全遵循这种方法并删除局部变量
public static void main() {
MyClass1 obj = new MyClass1();
obj.c2.c3.SomeEvent += obj_SomeEvent;
obj.Method1();
}
private static void obj_SomeEvent(object sender, EventArgs e)
{
Console.WriteLine("Some event fired");
}
public class MyClass1() {
public MyClass2 c2 = new MyClass2();
public void Method1() {
c2.Method1();
}
}
public class MyClass2() {
public MyClass3 c3 = new MyClass3();
public void Method1() {
c3.Method1();
}
}
public class MyClass3() {
public event EventHandler SomeEvent;
private void OnSomeEvent()
{
if (SomeEvent!= null)
{
SomeEvent(this, new EventArgs());
}
}
public void Method1() {
OnSomeEvent();
}
}
您的另一个选择(但这实际上取决于您试图做什么,如果它是可行的,我无论如何都不喜欢)是简单地将MyClass3中的事件定义为静态:
public static void main() {
MyClass3.SomeEvent += obj_SomeEvent;
MyClass1 obj = new MyClass1();
obj.Method1();
}
private static void obj_SomeEvent(object sender, EventArgs e)
{
Console.WriteLine("Some event fired");
}
public class MyClass1() {
public void Method1() {
MyClass2 obj = new MyClass2();
obj.Method1();
}
}
public class MyClass2() {
public void Method1() {
MyClass3 obj = new MyClass3();
obj.Method1();
}
}
public class MyClass3() {
public static event EventHandler SomeEvent;
private void OnSomeEvent(MyClass3 anObj)
{
if (SomeEvent!= null)
{
SomeEvent(anObj, new EventArgs());
}
}
public void Method1() {
OnSomeEvent(this);
}
}
因此您必须将事件链接回MyClass1,因此实际上MyClass1无法处理MyClass3引发的事件?您的问题是MyClass1不知道将引发事件的MyClass3实例,所以它不能订阅该事件。@PaulLassiter-Francesco抢先一步。添加/删除语法更容易。@ChrisGessler:你同意
回调
类型解决方案会更好吗?操作
类型是新的吗?我只使用C#2.0。可以改用委托吗?@PaulLassiter操作只是一个没有参数和无效返回类型的委托。您可以自己定义等效的内容。public delegate void Action();在这里,您以某种方式“欺骗”将局部变量转换为字段(MyClass2中的MyClass3)。此外,它不起作用,因为当您订阅MyClass2的某个事件时,cls3为空。这意味着您应该在MyClass2的Method1之外实例化MyClass3,但我不认为OP会喜欢这样。