Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How wrong is it to create an event handler delegate with out the standard (Obj sender, EventArgs args) signature?

I understand the benefits of using the standard MS event handler delegate signature as it allows you to easily expand on the information passed through the event with out breaking any old relationships that are based on the old delegate signature.

What I'm wondering is in practice how often do people follow this rule? Say I have a simple event like this

public event NameChangedHandler NameChanged;
public delegate void NameChangedHandler(Object sender, string oldName, string newName);

It's a simple event, and I'm nearly positive that the only arguments I'm ever going to need to know from the NameChanged event is the object whose name changed, the old name, and the new name. So is it worth it to create a separate NameChangedEventArgs class, or for simple events like this is it acceptable to just return the the arguments directly through the delegate arguments?

like image 375
Eric Anastas Avatar asked Jul 21 '09 03:07

Eric Anastas


2 Answers

Use the EventHandler<T> generic delegates for your events and create a type derived from EventArgs to hold your event data. So in other words, always. It's something that you always know exactly how it works when you come across it because it's never done otherwise.

Edit:

Code analysis CA1003: Use generic event handler instances
Code analysis CA1009: Declare event handlers correctly

like image 89
Sam Harwell Avatar answered Oct 13 '22 00:10

Sam Harwell


You can do anything the wrong way if you're the only one who has to deal with it. But it's not a bad idea to learn standards and stick to them so that you keep good habits when you're working on code with others.

So I'll make you a deal. If you promise to do it the right way, I'll give you a code snippet that'll make it much less of a pain. Just put this in a .snippet file, and put that file in:

My Documents\Visual Studio 2008\Code Snippets\Visual C#\My Code Snippets\
(or Visual Studio 2005 if applicable)

And here's the snippet; use it in VS by typing ev2Generic and hitting Tab:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Generic event with two types/arguments.</Title>
      <Shortcut>ev2Generic</Shortcut>
      <Description>Code snippet for event handler and On method</Description>
      <Author>Kyralessa</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>type1</ID>
          <ToolTip>Type of the first property in the EventArgs subclass.</ToolTip>
          <Default>propertyType1</Default>
        </Literal>
        <Literal>
          <ID>arg1Name</ID>
          <ToolTip>Name of the first argument in the EventArgs subclass constructor.</ToolTip>
          <Default>property1Name</Default>
        </Literal>
        <Literal>
          <ID>property1Name</ID>
          <ToolTip>Name of the first property in the EventArgs subclass.</ToolTip>
          <Default>Property1Name</Default>
        </Literal>
        <Literal>
          <ID>type2</ID>
          <ToolTip>Type of the second property in the EventArgs subclass.</ToolTip>
          <Default>propertyType2</Default>
        </Literal>
        <Literal>
          <ID>arg2Name</ID>
          <ToolTip>Name of the second argument in the EventArgs subclass constructor.</ToolTip>
          <Default>property2Name</Default>
        </Literal>
        <Literal>
          <ID>property2Name</ID>
          <ToolTip>Name of the second property in the EventArgs subclass.</ToolTip>
          <Default>Property2Name</Default>
        </Literal>
        <Literal>
          <ID>eventName</ID>
          <ToolTip>Name of the event</ToolTip>
          <Default>NameOfEvent</Default>
        </Literal>
      </Declarations>
      <Code Language="CSharp">
        <![CDATA[public class $eventName$EventArgs : System.EventArgs
      {
        public $eventName$EventArgs($type1$ $arg1Name$, $type2$ $arg2Name$)
        {
          this.$property1Name$ = $arg1Name$;
          this.$property2Name$ = $arg2Name$;
        }

        public $type1$ $property1Name$ { get; private set; }
        public $type2$ $property2Name$ { get; private set; }
      }

      public event EventHandler<$eventName$EventArgs> $eventName$;
            protected virtual void On$eventName$($eventName$EventArgs e)
            {
                var handler = $eventName$;
                if (handler != null)
                    handler(this, e);
            }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>
like image 34
Ryan Lundy Avatar answered Oct 12 '22 23:10

Ryan Lundy