C# - 事件的关键字优势? [英] C# - Event keyword advantages?

查看:172
本文介绍了C# - 事件的关键字优势?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来最近明白,一个C#事件确实是。这是不是真的任何事情,真的。综上所述我的发现:的的事件的关键字是简单的只适用于代表一个修改

所以,事件的所有魔力是一位代理的业务。而已。我已经经历了很多微软的文档读取,但不成句,在这种方式总结了如此简洁。要继续我的发现,的委托,类和结构的都在同一个级别。他们是如何定义对象。我的意思不是对象作为类型,但'东西'封装的概念。怎么样说这个词的时候对象是用来的的面向对象编程

总之,对象有一定的调节剂。例如,密封的,只读的,虚拟的,静态的,等等... 的这份名单可以发现的此处。在委托的情况下,它有额外的一个叫做的事件的。事件使得它如此,当一个委托声明为类的一部分,它只是暴露在添加删除方法按给该事件的访问修饰符。这些方法在具有类似性质定义为获取设置属性即可。委托(赋值,只读访问,方法调用等)的其他操作仅在该事件委托被宣布为类中允许的。我觉得有趣的另一件事,是所有代表都有方法调用,BeginInvoke的,和EndInvoke,但你不能定位到Visual Studio中查看它们,也能找到它们描述的文件...

好吧。因此,了解一切后,什么是比使用修改委托如何可以访问其他事件关键字的优势在哪里?这似乎是,在许多情况下,我会更好,只是声明没有委托事件关键字。最近,我遇到了一个情况是,我想创建包含2个事件的抽象基类。从这个基类派生的任何类应该能够像它们自己的,类似于暴露于派生类(类的任何其他对象使用的事件又名,非私有的,除非派生类是在另一个装配,并且对象被宣布内部)。

基本上,我想要的派生类使用这些事件作为自己。做到这一点的唯一方法是公开为保护事件的后盾变量,所以派生类可能引发的事件。纵观code,这似乎pretty愚蠢的,因为我基本上是定义两次委托;一次作为受保护字段,另一个作为公共事件。我以为,


  

难道我会更好做一类称为事件,有一个出
  在构造一个动作的参数?返回的操作相当于提高,许多人提出,作为代表一个扩展方法,它检查是否委托为空,然后调用委托。在活动中唯一的公共方法将被添加和追加的代表和来自底层的代表去除它们删除(+ =, - =)。类可以有这些事件的属性,例如,


 公共事件SomethingHappened {搞定;私人集; }


  

,使得只有该类别可以重新分配该事件。或公共只读域将是一样有效。即从构造返回的输出参数是由类存储和上课的时候​​要提高事件调用。我知道这是一个解决办法做作,但它会完成这项工作,并允许这些事件不仅作为参数传递,但允许派生类调用Raise方法如果基类把它定义为受保护。


TLDR:

什么是比使用修改委托如何可以访问其他事件关键字的优势在哪里?


解决方案

  

什么是使用比修改委托可以如何访问其他事件关键字的优势在哪里?


这的的使用事件关键字的主要优势。您可以使用事件经过短短的原始委托prevent委托被调用,或从它在定义的类的范围之内清除,因为事件的情况下,它是该类负责调用事件。外部实体不应直接调用它(它们可以而且应该间接调用的事件),也不应照顾是否有任何其他的事件处理程序或参与接触他们(通过,例如,分配完全新的委托到外地)。

想允许子类触发事件由具有定义该事件创建受保护的方法,做什么,但触发事件的类最常见解决的特定情况。这些方法将按照惯例,具有相同的名称作为事件但开prefixing它。

是的,你可以创建自己的类型,它在逻辑上重新presents的事件,是一个委托的包装,并限制可以对事件进行到那些函数应该能够执行他们(可能使用比C#稍有不同的规则事件关键字使用,这是一些经常在其他语言中使用的不具有事件关键字(或者甚至可能代表)。C#的设计者简单地意识到这是一个很常见的模式,并认为这是值得的能量将关键字添加的语言,以帮助减少样板$ C $需要C创建一个逻辑上的事件。

使用的另一个好处事件关键字,而不是仅仅有一些类型的委托作为一个属性,是你让你的意图更加清晰。如果我看到的只是一个委托财产的含义一般是它重新presents一种方法。是的,在C#中的所有代表是多播代表,所以这不是真的,但它是不寻常的人利用事件以外的功能。人认为的,一个动作重新presents一个动作,而不是操作的列表。活动还与对于C#文档特殊处理。他们都单独列出来,他们在Visual Studio中,等这一切都有助于使会员更加清晰使用类一目了然人的意图和语义。不同的图标

最后,事件关键字确保有多个线程,这不是由委托执行之间的同步类。如果多个线程去处理,同时添加到事件时,事件关键字保证都被添加。如果你只是公开揭露委托有可能为一个覆盖其他因竞争状态,并有一个处理程序结束了掉在地上。如果你滚你自己的事件类,你可以提供这一功能,但它更多的样板code和东西是pretty织补容易乱了(或者两者从而留下比赛条件,或过多的同步导致丢失性能)。

I've come to recently understand that a C# 'event' really is. It isn't really anything, honestly. To sum up my findings: The event keyword is simply a modifier that only applies to delegates.

So, all the 'magic' of an event are the operations of a delegate. That's it. I've read through a lot of the Microsoft documentation, but there no sentence that summarizes in that manner so succinctly. To continue with my findings, delegate, class, and struct are all on the same 'level'. They are ways to define a 'object'. I don't mean 'object' as in the type, but an encapsulated concept of 'something'. Like how the word 'object' is used when saying object oriented programming.

Anyway, 'objects' have certain modifiers. For example, sealed, readonly, virtual, static, etc... This list can be found here. In the case of a delegate, it has the extra one called event. Event makes it so that when a delegate is declared as part of a class, it only exposes the add and remove methods as per the access modifier given to the event. These methods are defined in a similar nature to get and set of a property. Other operations of the delegate (assignment, read-access, method invocation, etc) are only allowed within the class in which the event delegate was declared. The other thing I find interesting, is that all delegates have the methods Invoke, BeginInvoke, and EndInvoke, yet you cannot navigate to view them within Visual Studio, nor could I find the documentation describing them...

Okay. So after knowing all that, what is the advantage of using the event keyword other than for modifying how the delegate can be accessed? It seems like, in many cases, I'd be better off simply declaring a delegate without the event keyword. A situation I ran into recently is that I wanted to create an abstract base class that contained 2 events. Any class that derived from this base class should be able to use the events like they are their own, similar to any other object of the class that is exposed to the derived class (aka, non-private, unless the derived class is in another assembly, and the object was declared internal).

Basically, I wanted the derived classes to use these events as their own. The only way to do this was to expose the backing variable of the events as protected, so the derived classes could raise the events. Looking at the code, this seemed pretty stupid since I was basically defining the delegate twice; once as a protected field, and the other as the public event. I thought,

Wouldn't I be better off making a class called Event that has an out parameter of an Action in the constructor? The action that is returned is equivalent to Raise that many have made as an extension method for delegates, where it checks to see if the delegate is null, and then invokes the delegate. The only public methods on Event would be Add and Remove for appending delegates and removing them from the underlying delegate (+=, -=). Classes could have these events as properties, such as,

public Event SomethingHappened { get; private set; }

so that only that class can re-assign the event. Or a public readonly field would be just as effective. The out parameter that is returned from the constructor is stored by the class and called when the class wants to raise the event. I know it is a hokey workaround, but it'll get the job done, and allows the events to not only be passed as arguments, but allow derived classes to call the Raise method if the base class defines it as protected.

TLDR:

What is the advantage of using the event keyword other than for modifying how the delegate can be accessed?

解决方案

What is the advantage of using the event keyword other than for modifying how the delegate can be accessed?

That is the primary advantage of using the event keyword. You use an event over just a raw delegate to prevent the delegate from being invoked or cleared from outside the scope of the class it is defined in, because in the case of events it is the responsibility of that class to invoke the event. External entities shouldn't be invoking it directly (they can and should be invoking the event indirectly), nor should they "care" about whether there are any other event handlers or be involved in touching them (by, for example, assigning an entirely new delegate to the field).

The specific case of wanting to allow sub-classes to fire the event is most commonly solved by having the class that defines the event creating a protected method that does nothing but fire the event. Such methods will, by convention, have the same name as the event but with "On" prefixing it.

Yes, you could create your own type that logically represents an event, is a wrapper for a delegate, and limits the functions that can be performed on that event to those that "should" be able to perform them (possibly using slightly different rules than the C# event keyword uses. This is something that is frequently used in other languages that don't have an event keyword (or possibly even delegates). The C# designers simply realized that this was a very common pattern, and felt that it was worth the energy to add the keyword to the language to help minimize the boilerplate code required to create a logical "event".

Another benefit of using the event keyword, as opposed to just having some type of delegate as a property, is that you make your intentions much clearer. If I see just a delegate property the implication is generally that it represents one method. Yes, all delegates in C# are multicast delegates, so that's not true, but it's unusual for people to leverage that functionality outside of events. People think that an Action represents one action, not a list of actions. Events also have special treatment with respect to the C# documentation. They are all listed separately, they have different icons in visual studio, etc. This all helps make the intentions and semantics of the member much clearer to someone using the class at a glance.

Finally, the event keyword ensures that there is synchronization between multiple threads, which isn't performed by the Delegate class. If multiple threads go to add handlers to an event at the same time, the event keyword ensures both are added. If you just publicly expose a delegate it's possible for one to overwrite the other due to a race condition and have one handler end up dropped on the floor. If you roll your own Event class you could provide this functionality, but it is both more boilerplate code and something that's pretty darn easy to mess up (either resulting in leaving race conditions in, or excessive synchronization resulting in lost performance).

这篇关于C# - 事件的关键字优势?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆