Why should events in C# take (sender, EventArgs)?

前端 未结 10 1209
轻奢々
轻奢々 2020-12-08 18:46

It\'s known that you should declare events that take as parameters (object sender, EventArgs args). Why?

相关标签:
10条回答
  • 2020-12-08 19:27

    Sometimes you would like to force all of your event consumers to use a particular event parameter, for example, a security event which passes a boolean parameter, true for good, false for bad. In this case you want your consumer to be painfully aware of the new parameter, i.e. you want your consumers to be coupled with that parameter. Take note, your consumers are still decoupled from your event firing class, but not from your event.

    I suspect that this scenario applies to a large number of cases and in those cases the value of EventArgs is greatly reduced.

    0 讨论(0)
  • 2020-12-08 19:27

    The EventArgs class alone is useless since it must be derived to instantiate with any content. This would indicate a subclass should be used, and many already exist in .NET. Sadly, I can't find any good generic ones.

    Let's say you want to delegate logging to a generic event... WITHOUT WRITING YOUR OWN EventArgs SUBCLASS. It may seem a pointless exercise, but I like using existing features. You can pass your string through the Object argument, but that goes against it's intended use. Try to find a good reference of EventArgs subclasses on Google, and you'll come up dry. (At least I did.)

    ReSharper helps a bit, since when you type "EventArgs" you'll see a list of all classes (within your using/imports scope) that CONTAIN the string "EventArgs". Perusing the list you'll see many classes with no string members. When you get to ControlEventArgs, you see that the Text property might be used, but with all of the overhead of a windows control. ConvertEventArgs might be useful, since you pass the type along with the data, but this still requires tight coupling that's neither well-documented nor inherently type-safe. DataReceivedEventArgs has no implementation. EntryWrittenEventArgs requires an EventLogEntry with a byte array or StreamingContext for data. ErrorEventArgs is closer, with an Exception message, if you don't mind calling all of your log events Exception ErrorEvents internally. FileSystemEventArgs is probably the closest yet, with two strings and a required WatcherChangeTypes enum argument that CAN be set to 0, if you know what you're doing. LabelEditEventArgs uses an int and a string, if you don't mind requiring the Windows.Forms namespace. RenamedEventArgs is similar to FileSystemEventArgs with an extra string. Finally, ResolveEventArgs in System.Runtime.InteropServices passes a single string. There are other libraries, but I stuck to some of the most common ones. So, depending on the implementation I can use ErrorEventArgs, FileSystemEventArgs or ResolveEventArgs for logging.

    0 讨论(0)
  • 2020-12-08 19:28

    Using a single parameter, EventArgs, for the data passed by an event allows you to add data to your event in future versions of your software without breaking existing consumers. You simply add new members to an existing EventArgs-derived class, or create a derived class with the new members.

    Otherwise consistency and the principle of least surprise justify using EventArgs for passing data.

    As for sender, in some (but not all) cases it's useful to know what type sent the event. Using a type other than object for the sender argument is too restrictive: it would mean that other senders couldn't reuse the same event signature.

    0 讨论(0)
  • 2020-12-08 19:28

    Chris Anderson says in the Framework Design Guidelines book:

    [T]his is just about a pattern. By having event arguments packaged in a class you get better versioning semantics. By having a common pattern (sender, e) it is easily learned as the signature for all events.

    There are situations mostly involving interop that would require deviation from this pattern.

    0 讨论(0)
  • 2020-12-08 19:28

    It seemed that this was Microsoft's way to evolve the event model over time. It also seems that they are also allowing another way to do it with the "new" Action delegate and it's variations.

    0 讨论(0)
  • 2020-12-08 19:29

    This allows the consuming developer the ability to write a single event handler for multiple events, regardless of sender or event.

    Edit: Why would you need a different pattern? You can inherit EventArgs to provide any amount of data, and changing the pattern is only going to serve to confuse and frustrate any developer that is forced to consume this new pattern.

    0 讨论(0)
提交回复
热议问题