Click to See Complete Forum and Search --> : Code re-use
Ctwizzy
March 21st, 2005, 02:26 PM
Probably a really dumb simple question but felt the need to ask.
So In my code I have a set of buttons that all do different things, but at the end of the day they each have this line of code:
ButtonPressedEventArgs args = new ButtonPressedEventArgs();
OnBtnPressed(args);
They all fire this event.
Now while I dont mind c/p the code into each Method, I got to wondering about something darwen had said about never rewriting the same line twice, and decided I should look into way of doing this.
This is what I determined,
Generally I should create a custom userControl which extends the command button class, modify it to say throw this exception and then add into my project.
I dont know if the above method is the preffered so ill list another I found:
Using goto.
One site I checked said to use goto with labels as thats easier code reuse.
Another said that if all 8 buttons are the same (3 of which are just cancel buttons and thus would "assumingly act the same") then just change their event to register to one central one. But then if I want to change the way one cancel button behaves in the future it would change all three.
this is when I talked to someone who codes in a different language and said that his language has shortforms, where he can define a block of code and then say X = these lines of code, then call X. Sounds like a Method() to me he didnt speak very good english so was hard to fully understand.
As I dont think defining a method for 2 lines of code was worth it.
This doesnt apply just to my buttons tho, In general whats the best ways to avoid having to rewrite a line because it does a similar(some things are the same, some arnt) yet not entirely the same function?
I know OOP is the definitive way of code reuse but should everything either extend, inherit from or be an object? Is this the proper way I should be learning to program?
Thanks! Rep for most helpful answer!
cilu
March 21st, 2005, 04:43 PM
Now while I dont mind c/p the code into each Method, I got to wondering about something darwen had said about never rewriting the same line twice, and decided I should look into way of doing this.
DRY principle: Don't Repeat Yourself.
However there is a KISS principle too: Keep It Simple, Stupid. ;)
ButtonPressedEventArgs args = new ButtonPressedEventArgs();
OnBtnPressed(args);
This is the same with
OnBtnPressed(new ButtonPressedEventArgs());
No matter how you refactor your code you must replace this line of code with at least another one. So what do you gain?
Well, if you don't like to have 8 lines like the one above you can create a method:
public void RaiseEvent() {
OnBtnPressed(new ButtonPressedEventArgs());
}
and call RaiseEvent() at the end of each button handler.
Zeb
March 21st, 2005, 04:44 PM
why not set 2 event handlers - 1 that runs the two lines of code and handles every (or at least, all 8) button, and then an event handler for each button to do their custom function? that sounds like the easiest way to me, and for now I'll assume you know how to do that cause I've seen you around a bit (but if not, just reply and I'll explain).
in some cases I would say to subclass the button and create your own custom one, but in this particular instance I think it is a little overkill when the above method is so simple. the only issue I have with the above is that I never know which order the events will fire in (and i've never played around to figure it out myself). but I'm sure someone out there will know.
I certainly wouldn't use goto, and the other method you described is pretty similar to what I've suggested, but you get to keep each buttons individuality.
darwen
March 21st, 2005, 05:00 PM
Glad to hear it CtWizzy ! You're actually thinking about good design, which is wonderful.
In actual fact I've puzzled long and hard over such issues. There are things which are done all the time in C# which I feel could potentially be automated.
The best thing I've come up with it using attributes and reflection to do things like this.
Once you start investigating this sort of thing, it's quite amazing what you can automate.
For instance, I've now got a 'IPropertyCollection' interface which effectively is a set of dynamic properties for a class. Initially the 'PropertyCollection' class maps a string to a property, and has a get/set for this.
Nothing peculiar here, I here you say.
However I also have an 'AutoPropertyCollection' which takes another class, searches all of its "public const string" members, finds which of them has a certain attribute and takes information from these attributes, like the type of the property, and adds the property to the property collection.
Why do this ? Again I hear you ask.
(1) You can have 1 event for changes on all properties on the class. The property name (i.e. the public const string) is passed through et voi-la you can handle these at will.
(2) PropertyGrids. Darn, I love these. They are so wonderful ! It's the most useful and intelligent control which I've ever come across. Using my property collection class (with a few helper classes) a property grid is a breeze.
In my particular application this is invaluable : adding a property + event handler is reduced to just adding a public const string to the property defining class plus an attribute determining type and other useful additions.
I'm intending on writing an article on this... but I'm a bit bogged down with my own work at the moment so I can't say when.
Conclusion : Have a look at reflection and attributes. For object-oriented, automated code they are truly wonderful.
Darwen.
Issa
March 21st, 2005, 05:00 PM
the only issue I have with the above is that I never know which order the events will fire in (and i've never played around to figure it out myself). but I'm sure someone out there will know.
i believe methods held in the invocation list of a multicast delegate are invoked synchronously in the order they were added.
Zeb
March 21st, 2005, 05:03 PM
i believe methods held in the invocation list of a multicast delegate are invoked synchronously in the order they were added.
That is what I had assumed, but never tested - thanks Issa!
darwen
March 21st, 2005, 05:05 PM
I believe that too. But in a large application you might not know (or be able to control) which order the delegates are called.
The best thing is to assume is that the object which fired the event (which should be passed through - always - just good practice) will have its state changed beforehand.
Assuming a particular order of event delegate calling isn't a good idea in my opinion as it's easily broken.
Darwen.
Issa
March 21st, 2005, 05:16 PM
Assuming a particular order of event delegate calling isn't a good idea in my opinion as it's easily broken.
yeah, and if order was important this would seem to violate the publisher-subscriber design of events.
unfortunately, because the calls are synchronous the design seems to be imperfect for a couple reasons. for instance, if an exception is thrown by a subscribed method and allowed to propogate outside that method, then all following methods in the invocation list would fail to be called...it makes me wonder why they are called synchronously...anyone know?
darwen
March 21st, 2005, 05:58 PM
The are called synchonously for the following reason :
Ease of use. If a seperate thread was fired up for each and every call then .NET events would rapidly become a concurrency nightmare.
A sequential call order can be understood. A non-sequential call order cannot.
Look, the event mechanism is one of my favourite parts of C#. It works extremely well so let's not analyse it so hard eh ?
Oh and there is a way of doing your own event delegate calling when it is fired. I.e. it's all overridable so if you know an exception could be called on a particular delegate being called you can handle it.
Darwen.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.