为事件分配指针以供稍后使用
本文关键字:事件 分配 指针 | 更新日期: 2023-09-27 18:04:31
这有点难以表达,所以我将主要依靠代码。
顺便说一句,如果你能更好地表达这个问题请不要犹豫,给你的2c!
class CustomEventArgs : EventArgs
{
public delegate void CustomEventHandler( Object sender, CustomEventArgs args );
public int data;
public CustomEventArgs (int _data)
{
data = _data;
}
}
这是我们将在本例中使用的事件。
class EventGenerator
{
public event CustomEventArgs.CustomEventHandler WeOccasion;
public EventGenerator ()
{
Task.Factory.StartNew( () =>
{
var index = 1;
// just loop and generate events every now and then
while (true)
{
Thread.Sleep( 1000 );
WeOccasion( this, new CustomEventArgs (++index));
}
});
}
}
这个类只是循环触发CustomEventHandler事件。
class EventActivity
{
// EventActivity has an event of the same type as EventGenerator's
public event CustomEventArgs.CustomEventHandler WeOccasion;
// this is the part I cant seem to get right
public event CustomEventArgs.CustomEventHandler Source ( get; set; }
public bool Active {
set
{
if (value)
{
Source += DoWork;
}
else
{
Source -= DoWork;
}
}
}
private void DoWork( Object sender, CustomEventArgs frame);
}
这是我真正需要帮助的地方。我想要一个指向另一个类型为CustomEventHandler的类中的事件的指针,我可以稍后在激活活动时为其分配事件处理程序。
这是一个用类封装的用法示例;
class EventAssigner
{
EventGenerator Generator;
EventActivity DoSomeThing1;
EventActivity DoSomeThing2;
public EventAssigner ()
{
// init
Generator = new EventGenerator();
DoSomeThing1 = new EventActivity();
DoSomeThing2 = new EventActivity();
// assign sources
DoSomeThing1.Source = Generator.WeOccasion;
DoSomeThing2.Source = DoSomeThing1.WeOccasion;
// activate the first activity
DoSomeThing1.Active = true;
}
public void Activate2()
{
// activate the second activity
DoSomeThing2.Active = true;
}
public void Deactivate2()
{
// deactivate the second activity
DoSomeThing2.Active = false;
}
}
显然这段代码不起作用,我想这就是我要问的。你能让这种设计模式发挥作用吗?
对于。net事件,您要求做的事情实际上是不可能的,并且可能不像您想象的那样令人满意。一点背景知识应该有助于解释为什么:
属性具有get和set操作的基本模式。可以通过访问属性(对于get)和对属性赋值(对于set)来调用:
var x = instance.Prop1; // access
instance.Prop1 = x; // assignment
当您从类外部访问事件(即instance.Event
)时,您将获得"公共"面,这与属性一样,有两个操作:添加处理程序和删除处理程序。这些是使用+=
和-=
操作符调用的。
instance.Event += this.Handler; // add
instance.Event -= this.Handler; // remove
重要的是要注意它没有"get"操作- 没有办法在类之外获取对事件的引用;您只能修改已注册的处理程序。
当你从一个类中访问一个事件时,你会得到一个"私有"面,它本质上是一个特殊的委托集合(函数指针)到注册的事件处理程序。当你调用委托时,你实际上是在要求框架遍历注册的事件处理程序并调用它们。
if(this.Event != null)
{
this.Event.Invoke(e, args); // raise event
}
这种公共面孔和私人面孔的分离是什么让你有一个简单的event
关键字,神奇地给你一个事件。这也是阻止您传递对事件的引用的原因。
要将事件传递给注册方法,必须传递事件所附加的对象。如果你有多个实现相同事件的类,并且你想以相同的方式注册它们,你应该让它们实现一个带有事件的接口(是的,事件可以在接口上),并编写你的方法来接受接口作为参数。
如果我没看错的话,你想要
DoSomeThing1.Source = Generator.WeOccasion;
保存指向WeOccasion事件的指针,以便稍后添加DoWork调用,对吗?
我认为这在"正常"代码中是不可能的,因为事件不是一个值,而更像是一个属性。考虑下面的类似代码:
myProp = aPerson.Name; // attempt to save the name property for later
myProp = "Fred"; // intent is to set aPerson.Name = "Fred"
如果你想这样做,我建议使用反射来找到事件,并使用EventInfo添加到它。AddEventHandler方法(http://msdn.microsoft.com/en-us/library/system.reflection.eventinfo.addeventhandler.aspx)