Pol*_*ity 6 .net c# event-handling
令我恼火的一件事是,在默认事件中,Sender属于object类型,因此在我们使用它之前几乎总是需要手动转换.幸运的是,由于VB现在也支持委托中的差异,我们可以以强类型发送者的方式更新事件的签名,请参阅:事件参数; "发件人为对象",或"发件人为T"?
遗憾的是,这对于发送者属于object类型的现有声明事件不起作用.
现在一个解决方案就是生成一个假的EventHandler,它在内部为你处理演员表.我做了一个简单的例子,见:
struct EventHandler<TSender, TEventArgs>
where TEventArgs: EventArgs
{
private readonly Action<TSender, TEventArgs> _delegate;
public EventHandler(Action<TSender, TEventArgs> @delegate)
{
if (@delegate == null)
throw new ArgumentNullException("@delegate");
_delegate = @delegate;
}
public static implicit operator EventHandler<TEventArgs>(EventHandler<TSender, TEventArgs> eventHandler)
{
return new EventHandler<TEventArgs>(eventHandler.Execute);
}
private void Execute(object sender, EventArgs e)
{
TSender typedSender = (TSender)sender;
TEventArgs typedEventArgs = (TEventArgs)e;
_delegate(typedSender, typedEventArgs);
}
}
Run Code Online (Sandbox Code Playgroud)
可以按照您的预期使用它:
class Program
{
event EventHandler<EventArgs> Test;
static void Main(string[] args)
{
new Program().Main();
}
void Main()
{
Test += new EventHandler<Program, EventArgs>(TestEventHandler);
Test(this, EventArgs.Empty);
}
void TestEventHandler(Program sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我真的想要使用它,那么还有很多工作要做.(结构应该像原始委托一样).然而我确实感觉已经有一个很好的实现,或者没有实现,因为我忽略了一些主要的缺点.
谁能回答我上面提到的问题?还有其他提示吗?
我想不出任何比以下代码更少的解决方案
var original = (OriginalType)sender;
Run Code Online (Sandbox Code Playgroud)
另外,如果类是您的,那么没有什么可以阻止您创建自己的委托而不是 EventHandler 委托
delegate void EventHandler<in TSender, in TArgs>(TSender sender, TArgs args);
Run Code Online (Sandbox Code Playgroud)
这是 args 和 sender 的逆变
人们通常还拥有引发事件的对象的引用,因此他们很少需要从发送者那里获取该内容。在你的情况下有可能吗?
编辑:既然您提到您正在处理不是由您编写的事件,因此修改委托是不可能的,并且您可能没有对该对象的引用,因此在这种情况下您必须求助于发送者。现在,在您的解决方案中,您无法取消订阅该事件。如果您修改它以支持这一点,那么您将必须保留对您的这个结构的引用,这比简单的转换需要更多的工作。我认为铸造仍然是最干净的解决方案。
| 归档时间: |
|
| 查看次数: |
1895 次 |
| 最近记录: |