我在泛型类上有一个适配器模式,它本质上是在类型之间进行适配:
class A<T> { event EventHandler e; }
class Aadapter<T1, T2> : A<T1> { A<T2> a; Aadapter(A<T2> _a) { a = _a; } }问题是A包含一个事件。我实际上希望分配给Adapter的所有事件处理程序都落入一个。
如果我可以将a的事件处理程序分配给适配器的事件处理程序,那就太棒了,但这是不可能的?
这里的想法是A几乎真的就是A,但我们需要一种方法来适应它们。由于事件的工作方式,除了手动添加两个事件处理程序,当它们被调用时,它们被“中继”到另一个事件,我无法有效地做到这一点。虽然这并不漂亮,但如果我能有像这样的东西,那会更好
class A<T> { event EventHandler e; }
class Aadapter<T1, T2> : A<T1> { event *e; A<T2> a; Aadapter(A<T2> _a) { a = _a; e = a.e; } }在某种意义上,我们有一个指向事件的指针,我们可以将2的事件赋值给它。
我怀疑有任何简单的方法,但也许有人有一些想法让它工作。
(顺便说一句,我意识到这在虚拟事件中是可能的,但如果可能的话,我想避免这种情况)
发布于 2011-01-13 13:09:43
我想这就是你想要的:
class A<T>
{
public virtual event EventHandler e;
}
class Aadapter<T1, T2> : A<T1>
{
A<T2> a;
Aadapter(A<T2> _a) { a = _a; }
public override event EventHandler e
{
add { a.e += value; }
remove { a.e -= value; }
}
}或将其链接起来
class A<T>
{
public event EventHandler e;
protected void ChainEvent(object sender, EventArgs eventArgs)
{
e(sender, eventArgs);
}
}
class Aadapter<T1, T2> : A<T1>
{
A<T2> a;
Aadapter(A<T2> _a)
{
a = _a;
a.e += ChainEvent;
}
}发布于 2011-01-13 11:51:10
为什么订阅和转发事件并不美观?我觉得它很优雅。
这样做与适配器其余部分的实现方式是一致的。
即使你可以使用指针,它也是不一致的,因为你不会想在每种情况下都这样做。
例如,如果您要将一个实现了INotifyPropertyChanged的类改写为一个接口,而该接口没有实现,但却公开了两个属性,比如"TitleChanged“和"MaxLengthChanged”,那么就不会使用指针。您的适配器将公开这两个事件,消费者将进行订阅。您的适配器将订阅PropertyChanged事件,并仅在收到"Title“已修改的通知时引发"TitleChanged”,并仅在收到"MaxLength“已被修改的通知时引发"MaxLengthChanged”。所有其他通知将被忽略。
我喜欢这种方法,因为我发现它简单、一致并且符合模式。
发布于 2011-01-13 13:35:29
示例显示了解决问题的“标准”方法。第一种使用虚拟事件/方法,而第二种使用“双端”转发方案。这两种方法各有优缺点,但如果有一种更简单的方法,而不是随着事件数量的增加而增长,那就更好了。我们想要做的是将这两个事件直接组合成一个事件,而不是间接的,这就是所有这些代码所做的事情。(如果指针在C#中是可能的,那么它们就是这样一种方法)
//#define __virtual
#define __direct
using System;
using System.Collections.Generic;
using System.Text;
namespace VirtualEvents
{
#if __virtual
#region
public class A<T>
{
public virtual event EventHandler e;
public virtual void Fire() { e(this, null); }
}
public class Aadapter<T1, T2> : A<T1>
{
A<T2> a;
public override event EventHandler e
{
add { a.e += new EventHandler(value); }
remove { a.e -= new EventHandler(value); }
}
public override void Fire()
{
a.Fire();
}
public Aadapter(A<T2> _a)
{
a = _a;
}
}
#endregion
#elif __direct
#region
public delegate EventHandler EventHandlerPtr();
public class eventPtr
{
public EventHandler _event;
}
public class A<T>
{
//internal EventHandler _event;
public eventPtr _event = new eventPtr();
public event EventHandler e
{
add { _event._event += value; }
remove { _event._event -= value; }
}
public void Fire() { _event._event(this, null); }
}
public class Aadapter<T1, T2> : A<T1>
{
A<T2> a;
public Aadapter(A<T2> _a)
{
a = _a;
this._event = a._event;
}
}
#endregion
#else
#region
public class A<T>
{
public event EventHandler e;
public void Fire() { e(this, null); }
}
public class Aadapter<T1, T2> : A<T1>
{
A<T2> a;
public Aadapter(A<T2> _a)
{
a = _a;
a.e += new EventHandler(a_e);
e += new EventHandler(Aadapter_e);
}
void Aadapter_e(object sender, EventArgs e)
{
a.e -= new EventHandler(a_e);
a.Fire();
a.e += new EventHandler(a_e);
}
void a_e(object sender, EventArgs e)
{
this.e -= new EventHandler(Aadapter_e);
Fire();
this.e += new EventHandler(Aadapter_e);
}
}
#endregion
#endif
class Program
{
static void Main(string[] args)
{
var a = new A<double>();
var q = new Aadapter<int, double>(a);
a.e += new EventHandler(a_e);
q.e += new EventHandler(q_e);
a.Fire();
q.Fire();
((A<int>)q).Fire();
Console.ReadKey();
}
static void a_e(object sender, EventArgs e)
{
Console.WriteLine("From a");
}
static void q_e(object sender, EventArgs e)
{
Console.WriteLine("From q");
}
}
}(编辑:代码现在包括了一个新的方法,它将事件包装在一个类中,这个类现在允许轻松有效地分配事件,表示“指针”的情况。希望有人能在这些方面做更多的改进。)
https://stackoverflow.com/questions/4676437
复制相似问题