gpt4 book ai didi

c# - 无法删除强制转换事件处理程序

转载 作者:行者123 更新时间:2023-11-30 15:36:52 28 4
gpt4 key购买 nike

我有一个设计模式(不确定这是否是常用的 DP,如果有人知道它的名字请告诉我)我有一个类的非通用接口(interface)和通用接口(interface)。该实现存储泛型值并隐式实现泛型接口(interface)。它还显式地实现了非泛型接口(interface),每个属性返回泛型属性的值,适本地转换为它的非泛型形式。这对于属性来说非常有效,但我遇到了一些问题让它同样适用于事件。

下面是我正在做的事情的一个大大简化的版本。这个想法是,将处理程序添加到 Event 的任一接口(interface)版本应该将其添加到同一事件,这样当事件触发时,它是如何订阅的并不重要。 Main 中的测试代码显示事件处理程序没有像我预期的那样被删除。使用 INormalInterface.Event 的添加/删除 block 添加到事件/从事件中删除的正确代码是什么?

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
{
}

我想这个问题是因为我每次都在“新建”委托(delegate),所以在添加/删除时它不会解析为相同的值,有没有办法转换委托(delegate)?我确实有一个解决方案,但它需要为每个事件都有一个字段,所以希望能避免这种情况的任何解决方案:

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>());
}
}
}

最佳答案

这确实有用,但我不认为它很漂亮:

    event EventHandler<NormalEventArgs> INormalInterface.Event
{
add
{
var handler = (EventHandler<GenericEventArgs<T>>)Delegate.CreateDelegate(typeof(EventHandler<GenericEventArgs<T>>), value.Target, value.Method);
Event += handler;
}
remove
{
var handler = (EventHandler<GenericEventArgs<T>>)Delegate.CreateDelegate(typeof(EventHandler<GenericEventArgs<T>>), value.Target, value.Method);
Event -= handler;
}
}

问题

    add { Event += new EventHandler<GenericEventArgs<T>>(value); }

是它为 Delegate.Invoke 方法创建了一个委托(delegate),因此它无法在事件的多播委托(delegate)中找到匹配项。是不是新对象本身的创建阻止了您删除处理程序。

关于c# - 无法删除强制转换事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13307185/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com