[英]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
时,只能通过+=
和-=
运算符调用add
和remove
方法。
但是,从类中 ,访问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.