gpt4 book ai didi

c# - 如何在 C# 中引用事件

转载 作者:太空狗 更新时间:2023-10-29 20:06:05 25 4
gpt4 key购买 nike

我有以下类(class),其中有一个名为 LengthChanged 的公共(public)事件:

class Dimension
{
public int Length
{
get
{
return this.length;
}
set
{
if (this.length != value)
{
this.length = value;
this.OnLengthChanged ();
}
}

protected virtual void OnLengthChanged()
{
var handler = this.LengthChanged;
if (handler != null)
{
handler (this, System.EventArgs.Empty);
}
}

public event System.EventHandler LengthChanged;

private int length;
}

我希望能够在名为 Observer 的方法中为此事件注册/注销处理程序,它对 Dimension 一无所知类(class)。我提出了两种方案,但都不是真正令人满意的方案:

  1. 定义接口(interface)ILengthChangedLengthChanged事件,然后确保 Dimension工具 ILengthChanged .然后我必须提供一个 Observer 的实现我定义的每个接口(interface)的方法。这绝不是足够通用的。我真的希望能够简单地传递对 System.EventHandler 的引用。事件。

  2. 使用 System.Action<System.EventHandler>Observer 中注册和注销事件处理程序的回调方法,就这样:

    class Foo
{
public void Observer(System.Action<System.EventHandler> register,
System.Action<System.EventHandler> unregister)
{
register (this.MyEventHandler);

// keep track of the unregister callback, so that we can unregister
// our event handler later on, if needed...
}

private void MyEventHandler(object sender, System.EventArgs e)
{
...
}
}

然后会像这样调用:

Foo foo = ...;
Dimension dim = ...;

foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);

并且,当执行时,最终确实会连接 LengthChanged带有内部事件处理程序的事件 MyEventHandler .但这不是很优雅。我希望能够改为这样写:

Foo foo = ...;
Dimension dim = ...;

foo.Observer (dim.LengthChanged);

但我不知道这是如何实现的。也许我在这里遗漏了一些非常明显的东西?我猜有些 dynamic魔法可以以某种方式解决问题,但这不会强制执行编译时类型检查:我不希望 Observer 的用户传递对不满足 System.EventHandler 的事件的引用事件签名。

最佳答案

不幸的是,实际上并没有办法做到这一点。事件通常不是 .NET 中的一等公民 - 尽管 F# 试图在那里提升它们。

要么传入订阅/取消订阅委托(delegate),要么使用指示事件名称的字符串。 (后者通常更短,但在编译时显然不太安全。)

这些是 Reactive Extensions 的方法需要 - 如果有更简洁的方法,我相信他们会使用它 :(

关于c# - 如何在 C# 中引用事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4755988/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com