|
Some more advantages; it's more readable when there are lots of arguments, one can easily modify the parameter-set without having to touch each method, and one can even inherit a new set of parameters.
EventArgs - wonderfull example.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Also protects you when you have to add another option.
ed
~"Watch your thoughts; they become your words. Watch your words they become your actions.
Watch your actions; they become your habits. Watch your habits; they become your character.
Watch your character; it becomes your destiny."
-Frank Outlaw.
|
|
|
|
|
I'm personally not a big fan of it, but in .NET you have optional parameters.
They look like the example you showed in Ruby (but I don't know if they're the same thing since I don't know Ruby).
For example:
private void SomeMethod(bool useThisOption = true, string optionName = "")
{
}
private void UseOptionalParams()
{
this.SomeMethod(optionName: "MyOption");
}
For more information: Named and Optional Arguments[^]
It's an OO world.
public class SanderRossel : Lazy<Person>
{
public void DoWork()
{
throw new NotSupportedException();
}
}
|
|
|
|
|
I suspect that Marc, as a highly accomplished .NET developer, is well aware of this.
|
|
|
|
|
I suspect so too, but he didn't mention it and he did ask for it
I learned a little from it too, because I wanted to give an Attribute as example and then I found out attributes behave like they have optional parameters while they are actually just properties that can be set in the constructor!
So I just gave a little example using methods for all the folks reading this and thinking to themselves "what's he talking about?"
It's an OO world.
public class SanderRossel : Lazy<Person>
{
public void DoWork()
{
throw new NotSupportedException();
}
}
|
|
|
|
|
I believe that strictly speaking, you do NOT have optional parameter in .NET.
You have it in C#. But it is handled solely by the compiler, at compile time. Sort of synthetic sugar. (Or sugar-free, since we are talking about parameters who are not there in the source code.) In the .NET assembly, noone can tell whether the value specified as default in the function declaration was really defaulted or specified explicitly by the caller.
|
|
|
|
|
Good point. Although .NET has sort of become a synonym for C# and VB and they both support it
Strictly speaking you're right though.
It's an OO world.
public class SanderRossel : Lazy<Person>
{
public void DoWork()
{
throw new NotSupportedException();
}
}
|
|
|
|
|
I've tried a number of different ways, and found a class/message to be the most convenient. However, it does get a bit tedious to implement an interface where every method has it's own custom object even for simple calls, depending on language support.
One set of methods in the current app I work on has a string of 6 int? parameters in a row, and keeping them in order is a pain in the butt.
|
|
|
|
|
I also subscribe to the struct approach (of course you need to determine the break even point between how many parameters you have before it is worth wrapping them in a struct), but am going to go a little further. I have projects where the function I wish to call may be several layers deeper or I need to add a new request from a client UI and direct a call to a new function on the server - I know you have all been there too and know what I am talking about.
In some of my projects, I have a generic message class that can be XML'ified (, compressed, encrypted) and transmitted between server and client. The class has a member variable, which is a list of name/value pairs and this can be used directly for most parameters. When adding new stuff, only the sender and receiver function need to know about the parameters and all layers in between just work without being updated. For more advanced parameters, such as structs, the class has a string member variable that can be an XML string containing any kind of object that has been serialized to XML.
That whole core is kind of old and would probably benefit from being updated to JSON.
If extreme performance is an issue, I avoid the whole back and forth string conversion and use a different mechanism, but for normal applications the processing time is plenty fast enough and the savings in maintenance when you need to add a new parameter is well worth it.
Soren Madsen
"When you don't know what you're doing it's best to do it quickly" - Jase #DuckDynasty
|
|
|
|
|
In most cases I consider a large number of parameters (let say over 8) as design flaw, however it is possible that you end with such a list, in which case I would use struct/class...
I'm not questioning your powers of observation; I'm merely remarking upon the paradox of asking a masked man who he is. (V)
|
|
|
|
|
In the old days, I was working with a Fortran compilers where we had to push the release due to one (important) customer who had run into a limitation of the previous one: It could take only 99 (ninety-nine) parameters. The new version could handle 128 parameters, which was sufficient for the immediate needs of the customer, but the design allowed expansion to 256 parameters.
If there ever was a case for Fortran COMMON blocks, I would call this a candidate.
(Don't take me wrong - I am not suggesting using COMMON blocks as good programming practice. Nor is 100+ function parameters.)
|
|
|
|
|
|
COMMON is certainly good "programming practice" as long as each COMMON is named and contains a single value. Otherwise I submit that COMMON should be found non-complying in coding standards.
Gus Gustafson
|
|
|
|
|
When Dealing with Microsoft related programming products creating your procedures with the parameters (Sender as object, e as eventArgs) as an extremely recommended practice, and have your parameter class inherit from system.eventArgs.
This way your code naturally interacts with windows runtime components.
|
|
|
|
|
Except that you have created event arguments for use with none events. The sender is probably going to be completely useless.
|
|
|
|
|
You do understand that we are working with event driven programming right? The entire inner working of the object programming model has a point of origin and the event that triggered it.
You should always be making your code generic as it can be understood by everything, and your procedure should be tread safe - which means everything you need should be passed as a parameter.
|
|
|
|
|
Colborne_Greg wrote: You do understand that we are working with event driven programming right? That's a very narrow point of view, focused on one technology set. At no stage did Marc state he was asking about an event. And while there is a point of origin, there's no guarantee that he is responding to an event - you may have noticed that Marc was talking in a generic sense, hence the reason he mentioned ROR. So, in the case of doing something like processing a batch input on a file, forcing the programming model to use an event signature doesn't really make sense.Colborne_Greg wrote: You should always be making your code generic as it can be understood by everything, and your procedure should be tread safe - which means everything you need should be passed as a parameter. And that is why my response, at the top of this thread, stated that I would normally wrap things up into an object.
|
|
|
|
|
When the procedure was called is an event
when the processing a batch input on a file BOF reached and EOF reached are events.
Everything is an event, and inheriting from eventargs allows your code to be repurposed everywhere, and when all your delegates have the same signature you wont get held back when you want to dive deeper into generics.
|
|
|
|
|
Seriously, everything isn't an event. Not all environments are event based, and for those that are, creating events for things that don't need to be events is an unnecessary overhead. We might as well stop now because I'm not going to convince you and you aren't going to convince me.
|
|
|
|
|
You are thinking to hard.
Kiss - keep it simple stupid.
Everything is an event whether you are programming with events, responding to events, or looking for events in code via a conditional statement, an event is a English word that gives abstract context to meaning.
Its like arguing that a date/time, or decimal is not a string - well yes those are strings and are processed differently, which is the opposite to generics - inherit from eventargs whether or not you are responding to an actual event so that all your delegates have the same signature, then when you get into the thinking of what an actual event is your code will become cleaner.
|
|
|
|
|
I suppose the difference between you and me is that I have experience in none event driven systems, as well as in none .NET platforms so my first instinct is not to always make things an event. They aren't suitable for every platform. So perhaps you need to think a little harder and get out of the .NET bubble. It'll open your mind.
|
|
|
|
|
-_- I am a cobol programmer, I also started my statement with... when dealing with Microsoft related products which is the dot net bubble...
|
|
|
|
|
Also you can send a class object as the sender for the processing to interact with.
In your example of the processing of the batch input, the result can be given in the same procedure to the sender to be displayed.
|
|
|
|
|
I'm not sure that I've ever needed to do that other than in cases similar to database connection strings -- like a factory of some sort -- and then XML works.
@"<options option1='true' option2='foobar' option3='42' />"
Obviously, the problem with "but you have absolutely no clue what these optional parameters are unless you look up the online documentation (if it exists)" is taken to a whole new level.
You'll never get very far if all you do is follow instructions.
|
|
|
|
|
I think I have some internal, arbitrary rule that says;
If the parameters are basically unrelated except for being passed to that function, then leave them as individual arguments, well defined by their names.
If the parameters are related, then wrap them in some structure or other.
In other words, I wouldn't wrap parameters in a class or struct just to make the function signature smaller or more legible, but I would do so if it made sense for the parameters to be combined;
The danger of wrapping them is that you replace a long function call with a complex struct creation, to no real advantage - reading a method signature with meaningful argument names is self-documentation; the same method with a single argument called "necessaryInfoToDoTheJob is less descriptive!
|
|
|
|