Come sbagliato è per creare un gestore delegato dell'evento con lo standard (Obj sender, EventArgs args) firma?

StackOverflow https://stackoverflow.com/questions/1157072

  •  18-09-2019
  •  | 
  •  

Domanda

ho capito i vantaggi di utilizzare MS firma gestore eventi delegato di serie in quanto consente di espandere facilmente le informazioni passate attraverso l'evento con fuori rompere eventuali vecchie relazioni che si basano sulla vecchia firma del delegato.

Quello che mi chiedo è, in pratica, quanto spesso le persone seguono questa regola? Dire che ho un semplice evento come questo

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

Si tratta di un evento semplice, e io sono quasi positivo che gli unici argomenti che sto andando mai bisogno di sapere dall'evento NameChanged è l'oggetto il cui nome cambiato, il vecchio nome, e il nuovo nome. Così è la pena di creare una classe NameChangedEventArgs separata, o per eventi semplici come questo è accettabile per tornare solo gli argomenti direttamente attraverso gli argomenti delegato?

È stato utile?

Soluzione

Si può fare tutto nel modo sbagliato, se sei l'unico che ha a che fare con esso. Ma non è una cattiva idea di imparare norme e bastone a loro in modo da mantenere le buone abitudini quando si lavora sul codice con gli altri.

Così farò l'affare. Se promettete di farlo nel modo giusto, io ti do un frammento di codice che ti rendono molto meno di un dolore. Basta mettere questo in un file .snippet, e mettere il file in:

Documenti \ Visual Studio 2008 \ Frammenti di codice \ Visual C # \ My Code Snippets \
(O Visual Studio 2005, se del caso)

Ed ecco il frammento; usarlo in VS digitando ev2Generic e colpendo 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>

Altri suggerimenti

Utilizzare i delegati generici EventHandler<T> per i vostri eventi e creare un tipo derivato da EventArgs per tenere i vostri dati degli eventi. Quindi, in altre parole, sempre. E 'qualcosa che si sa sempre esattamente come funziona quando si incontra, perché non è mai fatto altrimenti.

Modifica:

CA1003: utilizzare le istanze del gestore di eventi generici
analisi del codice CA1009: declare gestori di eventi correttamente

  

In pratica quanto spesso le persone non [   utilizzare EventArgs classi derivate].

Non ho mai incontrato un momento in cui non sono state utilizzate le classi derivate EventArgs. Come dici tu stesso, aumenta la capacità di modificare il codice in seguito. Vorrei anche sostenere che la leggibilità è migliorata, dal momento che è facile vedere che questo è un gestore di eventi.

  

Ne vale la pena per creare un separato   Classe NameChangedEventArgs, o per   eventi semplici come This Is It   accettabile per restituire solo la   argomenti direttamente attraverso la   argomenti delegato?

Ti sembra di dire che si usa EventArgs per i gestori di eventi con più params e non utilizzarlo per casi come questo. Onestamente, questo non è semplicemente un'opzione durante la programmazione in C #. La coerenza è un must, soprattutto nel mondo di oggi del Foro di come questo, i progetti open source, ecc dove è facile perderla. Certo, se si sta programmando questo sotto una roccia, si può fare quello che vuoi, ma la maggior comunità di C # vi ringrazierà per seguenti norme e soprattutto utilizzando la consistenza in voi codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top