使用
订阅活动是否有任何问题MyPopup.CustomPopupPlacementCallback += popupFixCentered;
而不是:
namespace DataAccessLayer
{
public class DAL : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Administrator>().ToTable("tblAdministrator");
modelBuilder.Entity<User>().ToTable("tblUser");
}
public DbSet<Administrator> Administrators { get; set; }
public DbSet<User> Users { get; set; }
}
}
例如,如果我要从另一个方法更改为不同的回调,我想确保只订阅一个回调而不需要 - =正确的回调。
答案 0 :(得分:4)
嗯,听起来你没有尝试过。如果您这样做,您将收到以下编译错误:
事件'XXX'只能出现在+ =或 - =的左侧(除非在'YourClass'类型中使用)
错误非常明确:您只能在活动中使用+=
和-=
运算符。
如果您尝试从定义事件的类 中分配event
,那么它将“正常”。但在这种情况下它似乎能够分配给event
的原因是因为它实际上没有访问该事件。它正在访问一个您可能没有意识到的自动生成的私有委托实例。
从Chris Burrows' article引用主题:
在定义类似字段的事件E的类或结构之外,绑定到名称E解析为事件本身,唯一合法的操作是调用访问器;在定义类字段事件E的类或结构内部,绑定到名称E解析为私有委托字段。
要理解这一点,您需要在定义事件时可视化,例如:
public event EventHandler MyEvent;
...你看不到的是,它实际上被翻译成类似的东西(我正在从Jon Skeet's article on events and delegates复制它。还要注意它被翻译成的确切代码有在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文章:Delegates and Events
Chris Burrows文章:(另请参阅本系列的其余部分):Events get a little overhaul in C# 4, Part II: Semantic Changes and +=/-=
答案 1 :(得分:0)
我刚试过它。是的,您可以使用=
运算符分配给事件。 (编辑:显然只来自同一个班级)
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约定来进行属性的外部访问:)