我有一个设计模式(不确定这是否是常用的 DP,如果有人有名字,请告诉我)我有一个类的非泛型和泛型接口。实现存储泛型值并隐式实现泛型接口。它还显式地实现了非泛型接口,每个属性将泛型属性的值适当地转换为其非泛型形式。这对于属性非常有效,但是我遇到了一些问题,使其在事件中也能很好地工作。
下面是我正在做的一个大大简化的版本。这个想法是,将处理程序添加到 Event 的任一接口版本都应该将其添加到同一个事件中,这样当事件触发时,它是如何订阅的都无关紧要。Main 中的测试代码表明事件处理程序没有像我预期的那样被删除。使用 INormalInterface.Event 的添加/删除块添加/删除事件的正确代码是什么?
class Program
{
static void Main(string[] args)
{
INormalInterface x = new ImplementingClass<int>();
Console.WriteLine("Created x and invoking...");
x.InvokeEvent();
Console.WriteLine("Adding event and invoking...");
x.Event += x_Event;
x.InvokeEvent();
Console.WriteLine("Removing event and invoking...");
x.Event -= x_Event;
x.InvokeEvent();
Console.WriteLine("Done.");
Console.ReadKey(true);
}
static void x_Event(object sender, NormalEventArgs e)
{
Console.WriteLine("Event Handled!");
}
}
interface INormalInterface
{
event EventHandler<NormalEventArgs> Event;
void InvokeEvent();
}
interface IGenericInterface<T> : INormalInterface
{
new event EventHandler<GenericEventArgs<T>> Event;
}
class ImplementingClass<T> : IGenericInterface<T>
{
public event EventHandler<GenericEventArgs<T>> Event;
event EventHandler<NormalEventArgs> INormalInterface.Event
{
add { Event += new EventHandler<GenericEventArgs<T>>(value); }
remove { Event -= new EventHandler<GenericEventArgs<T>>(value); }
}
public void InvokeEvent()
{
if (Event != null)
{
Event(this, new GenericEventArgs<T>());
}
}
}
class NormalEventArgs : EventArgs
{
}
class GenericEventArgs<T> : NormalEventArgs
{
}
我认为问题是因为我每次都在“新建”代表,所以在添加/删除时它不会解析为相同的值,有没有办法投射代表?我确实有一个解决方案,但它需要为每个事件都有一个字段,因此希望有任何避免这种情况的解决方案:
class ImplementingClass<T> : IGenericInterface<T>
{
private readonly Dictionary<EventHandler<NormalEventArgs>, EventHandler<GenericEventArgs<T>>> m_eventDictionary = new Dictionary<EventHandler<NormalEventArgs>, EventHandler<GenericEventArgs<T>>>();
public event EventHandler<GenericEventArgs<T>> Event;
event EventHandler<NormalEventArgs> INormalInterface.Event
{
add { Event += m_eventDictionary[value] = new EventHandler<GenericEventArgs<T>>(value); }
remove { Event -= m_eventDictionary[value]; }
}
public void InvokeEvent()
{
if (Event != null)
{
Event(this, new GenericEventArgs<T>());
}
}
}