这篇“.NET中怎么将事件视为对象”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“.NET中怎么将事件视为对象”文章吧。
将事件视为对象,有的时候就是把事件的级别进行了提升,这样就能有效地提高语言的抽象能力。有的时候会出现错误,但还是值得尝试的。
如果一个语言(平台)把事件视为对象,则表明它把“事件”作为了语言的一等公民来对待。这意味着,我们可以把一个单独的事件作为参数传递给方法,也可以将其作为一个对象的一部分,这有效地提高语言的抽象能力。试想,如果没有“委托”,在.NET中就无法把“方法”看作是对象,也就很难使用如今各种灵活的抽象方式。同样,由于.NET本身无法将事件作为单个对象处理,因此在某些时候就会束手束脚,也难以引入一些特别的编程模型。
这就是“把事件作为对象进行传递”的实际意义。
我们提出了一种“解决方案”,它允许我们编写这样的代码:
class Program { public event EventHandler Submit; static void Main(string[] args) { Program p = new Program(); var ev = EventFactory.Create(() => p.Submit); ev += (sender, eventArgs) => Console.WriteLine(sender); p.Submit("Hello World", EventArgs.Empty); Console.WriteLine("Press any key to exit..."); Console.ReadLine(); } }
看上去挺那么像回事儿的,使用方式和传统的事件似乎没有太大区别。但是文末我提到这里其实有些“糊弄”的意味,而我们的装配脑袋同学、以及“脑袋装配得不输给装配脑袋”的RednaxelaFX,这两位纯爷们也都指出了问题。
信脑袋,得永生。信RednaxelaFX,原地满状态复活。
以上代码的“忽悠”,在于操作Program.Submit的代码处于Program类之内。如果我们想要使用相同的做法操作其他类的事件就做不到了,例如:
public class MyClass { public event EventHandler MyEvent; } class Program { static void Main(string[] args) { var myClass = new MyClass(); var ev = EventFactory.Create(() => myClass.MyEvent); } }
这样的代码看似没有问题,但是编译器会提示这样的错误:
The event 'SimpleConsole.MyClass.MyEvent' can only appear on the left hand side of += or -= (except when used from within the type 'SimpleConsole.MyClass')
编译器告诉我们,除了在MyClass类的内部,MyEvent事件只能出现在+=或-=操作的左边。之前提到的两位纯爷们在前文的评论中也有过相关及衍生的讨论。因此,我们目前的做法是失败的。
前文的评论中还有朋友提到,我们事实上也可以把一个事件作为参数传递给一个方法(然后在方法里添加或删除处理程序),只要使用ref关键字就可以了,例如:
static void RegisterHandlers(ref EventHandler e) { ... }
然后:
static void Main(string[] args) { var myClass = new MyClass(); RegisterHandlers(ref myClass.MyEvent); }
不过很显然,这样的做法也会遇到相同的问题:除非是Program内部的事件,我们不能把它像一个委托对象那样传递。而且,即使可以传递,我们也只能为它添加或删除处理函数,而不能把它作为另一个对象的一部分,然后经过各种处理之后,还可以对这个事件进行操作。
因此,我们要实现的其实是这样一个类型:
public class DelegateEvent { ... public DelegateEvent AddHandler(TDelegate handler) { ... } public DelegateEvent RemoveHandler(TDelegate handler) { ... } }
以上就是关于“.NET中怎么将事件视为对象”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。