繁体   English   中英

用=而不是+ =订阅事件

[英]Subscribing to events with = instead of +=

订阅活动有什么不对

MyPopup.CustomPopupPlacementCallback = popupFixCentered;

代替:

MyPopup.CustomPopupPlacementCallback += popupFixCentered;

例如,如果我要从另一种方法更改为其他回调,则要确保仅订阅了一个回调,而无需-=正确的回调。

好吧,听起来您没有尝试过。 如果这样做,则会出现以下编译错误:

事件“ XXX”只能出现在+ =或-=的左侧(从类型“ YourClass”中使用时除外)

错误非常明显:您只能在事件上使用+=-=运算符。

如果你试图给该event从定义事件类 ,那么它会“工作”。 但在这种情况下,它似乎能够分配给event的原因是因为它实际上没有访问该事件。 它正在访问一个自动生成的私有委托实例,您可能没有意识到它实际上在那里。

引用克里斯·伯罗斯关于该主题的文章

在定义类似字段的事件E的类或结构之外,绑定到名称E会解析为事件本身,唯一的合法操作就是在该事件上调用访问器; 在定义类似字段的事件E的类或结构中,绑定到名称E解析为私有委托字段。

要理解这一点,您需要在定义事件时将其可视化,例如:

public event EventHandler MyEvent;

...您看不到的是,它实际上已被翻译成类似的东西(我是从乔恩·斯凯特(Jon Skeet)关于事件和委托的文章中复制 。此外,请注意,翻译成的确切代码在的不同版本之间已更改C#,因此可能有所不同,但总体思路是相同的)

private EventHandler _myEvent;

public event EventHandler MyEvent
{
    add
    {
        lock (this)
        {
            _myEvent += value;
        }
    }
    remove
    {
        lock (this)
        {
            _myEvent -= value;
        }
    }        
}

因此,当您从类外部访问MyEvent时,只能通过+=-=运算符调用addremove方法。

但是,从类 ,访问MyEvent意味着不同的东西。 它实际上成为对您看不到的_myEvent委托变量的引用,但是它在那里。 因为这是委托类型,所以可以在其上使用赋值( = )运算符。


因此,要实现所需的目标,可以在定义事件的同一类中定义一个公共方法,然后使用该方法设置新的事件处理程序。

像这样:

public class MyClass
{
    public event EventHandler MyEvent;

    public void setSingleEventHandler(EventHandler eventHandler)
    {
        this.MyEvent = eventHandler;
    }
}

但是,如果要执行此操作,那么它将违反event类型的目的。 如果您只希望在任何给定时间最多调用一个事件处理程序,则以这种方式定义它(不使用event关键字)更有意义:

public class MyClass
{
    public EventHandler MyEvent { get; set; }
}

参考

乔恩·斯凯特(Jon Skeet)文章: 代表和活动

克里斯·伯罗斯(Chris Burrows)的文章:(另请参阅本系列的其余部分): C#4,第二部分:语义变化和+ = /-=

我刚刚测试过。 是的,您可以使用=运算符分配给事件。 (编辑:显然仅来自同一班级)

delegate void Foo();
event Foo bar;
Method()
{
    bar = () => { Console.WriteLine("1"); };
    bar();
    bar = () => { Console.WriteLine("2"); };
    bar();
}

产生输出:

1
2

但是,如果您尝试从课外进行分配,则会给您一个错误。

您可以使用Java样式的set方法来解决此问题:

SetBar(Foo foo)
{
    bar = foo;
}  

只有在我建议将Java约定用于属性的外部访问时才可以使用:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM