[C#] Event raiser methods

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
In c# wordt het aangeraden om protected event raiser methods te maken voor elk event zodat subclasses toegang hebben tot het event.

Of tenminste dat ben ik vaak tegen gekomen op msdn en ook in dit artikel:
http://www.codeproject.com/KB/cs/event_fundamentals.aspx

Even een voorbeeldje:
C#:
1
2
3
4
5
6
7
8
9
10
public delegate void StateChanged(StateChangedArgs args);

protected virtual void OnStateChanged(StateChangedArgs args) 
{
    if (StateChanged != null)
    {
        // Op dit punt zijn er event args die voor niks zijn aangemaakt
        StateChanged(args);
    }
}


Als in de bovenstaande code StateChanged geen handlers heeft dan zijn de StateChangedArgs voor niks aangemaakt.

Hier moet volgens mij een betere manier voor zijn, het is mogelijk om alle data die in de StateChangedArgs gaan mee te sturen aan de OnStageChanged method waar dan vervolgens in de raiser method zelf de args worden aangemaakt.

C#:
1
2
3
4
5
6
7
8
protected virtual void OnStateChanged(string iets, int nummer) 
{
    if (StateChanged != null)
    {
        StateChangedArgs args = new StateChangedArgs(iets, nummer);
        StateChanged(args);
    }
}


Andere oplossing zou zijn alleen OnStateChanged aan te roepen als StateChanged handlers heeft (!= null)

C#:
1
2
3
4
5
if (StateChanged != null)
{
    StateChangedArgs args = new StateChangedArgs(iets, nummer);
    OnStateChanged(args);
}


Wat denken jullie?

Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 17-09 08:50
Dat object bestaat intern toch altijd al, op het moment dat intern het Event geraised word?
Dat het nou door C# gecast word naar en leesbaar object maakt voor de resources toch (weinig) uit?

Even niets...


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hoe bedoel je het object bestaat altijd al?

Je maakt toch een nieuwe instantie van het object voordat je de raiser method aanroept?

C#:
1
2
    StateChangedArgs args = new StateChangedArgs(iets, nummer); // event args object aanmaken
    OnStateChanged(args); // raiser method aanroepen

[ Voor 9% gewijzigd door Verwijderd op 04-05-2009 22:57 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik vind 't nogal een micro-optimalisatie; een EventArgs object bevat meestal niet veel meer dan wat public properties; het is niet alsof het zo "duur" is zo'n object te maken. Daarbij wordt je method call er niet duidelijker op (zeker als 't aantal parameters 3, 4 of meer wordt) en refactor je jezelf scheel als er een waarde bij moet komen terwijl je op 'gangbare' manier gewoon die property erbij klust (en gebruikt wanneer nodig) et voila. Het is niet voor niets een 'best practice' ;)

Ik durf overigens zelfs te betwijfelen of 't een optimalisatie is...

[ Voor 9% gewijzigd door RobIII op 04-05-2009 23:42 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom moet die StateChangedArgs per se een class zijn dan?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Met RobIII
.oisyn schreef op maandag 04 mei 2009 @ 23:24:
Waarom moet die StateChangedArgs per se een class zijn dan?
Guidelines ...
Is het niet zo, dat een class passen minder 'duur' is, dan het passen van een struct ? (Bij het passen van een class (reference type) wordt de reference gepast; bij een struct wordt er een kopie van de struct gemaakt) ?

Als je trouwens gebruikt maakt van de generic EventHandler<T>, dan verwacht die delegate dat T overerft van de EventArgs class.

code:
1
EventArgs<T> where T : EventArgs

[ Voor 123% gewijzigd door whoami op 05-05-2009 09:16 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

whoami schreef op dinsdag 05 mei 2009 @ 09:08:
Met RobIII


[...]

Guidelines ...
Is het niet zo, dat een class passen minder 'duur' is, dan het passen van een struct ? (Bij het passen van een class (reference type) wordt de reference gepast; bij een struct wordt er een kopie van de struct gemaakt) ?
Ligt aan de grootte van de struct. Een struct met 1 reference als member is natuurlijk net zo duur als gewoon 1 reference. Maar een class moet gealloceerd worden op de heap en wordt dus ook getracked door de GC. Vaak zijn de kosten van een allocatie vele malen duurder dan een struct een paar keer rondkopieëren.
Als je trouwens gebruikt maakt van de generic EventHandler<T>, dan verwacht die delegate dat T overerft van de EventArgs class.
Ah ok, en je kunt een struct zeker niet laten erven van een class? :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
.oisyn schreef op dinsdag 05 mei 2009 @ 13:26:
[...]

Ligt aan de grootte van de struct. Een struct met 1 reference als member is natuurlijk net zo duur als gewoon 1 reference. Maar een class moet gealloceerd worden op de heap en wordt dus ook getracked door de GC. Vaak zijn de kosten van een allocatie vele malen duurder dan een struct een paar keer rondkopieëren.
Ook als er op een managed heap gealloceerd wordt, waarbij het nodige geheugen gewoon contiguous kan gealloceerd worden ?
Ah ok, en je kunt een struct zeker niet laten erven van een class? :)
Nee idd. ;)
Je kan zelfs geen struct van een andere struct laten erven; blijkbaar is een struct sealed.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Geef ipv de StateChangedArgs een Func<StateChangedArgs> als argument
zodat je de caller een lambda kan laten passeren die de event args maakt, zo kan je deze deferred aanroepen op de moment dat je de StateChangedArgs instantie nodig hebt ....
Pagina: 1