Dose C#2.0 support optional parameters

A

ad

Does C#2.0 support optional parameters like VB.NET:
Function MyFunction(Optional ByVal isCenter As Boolean = False)
 
A

ad

I have seen it:
The params keyword lets you specify a method parameter that takes an
argument where the number of arguments is variable.

But it is different from optional parameters of VB.Net
 
W

wbekker

Otherwise i'm afraid you are stuck with this kind of construction:

public void MyFunction(bool isCenter)
{
//place code here
}



public void MyFunction()
{
MyFunction(false);
}

Ward
 
J

John B

ad said:
Why,
Is there some drawback about optional parameters?
Optional parameter is supported by Delphi(Object Pascal) and VB.NET
Why C# ?
I cant recall seeing a case where I would consider optional parameters
to be *better than overloading.

To take your case below, we could refactor as:

public bool MyFunction()
{
return Myfunction(false)
}

public bool MyFunction(bool center)
{
//do the dance
}

JB
*better being defined as readibility, ease of use, etc..
 
M

Mark Broadbent

Limit them to a minimum yes, but they still have their place. Consider this.

public void Show(params string[] message)
{
if (message.Length == 0)
{
Console.WriteLine("No message!");
return;
}

Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}


public void Show2()
{
Console.WriteLine("No message!");
}
public void Show2(string message)
{
Console.WriteLine("Messages...");
Console.WriteLine(message);
}
public void Show2(string[] message)
{
Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}

Now in this scenario, where we want to pass 0 to many messages in a
parameter for overloading we have had to create 3 different type signatures
wheras using optional params we only need the one. Also note that the
overloading scenario would look even more clumsy if we did checking for zero
length arrays in there as well -since the behaviour of it at present is not
identical to the optional one. Also note for the Show2, if you want to pass
multiple strings, type checking forces you to pass an array, wheras the
optional Show method allows for a list (or an array).

e.g.
inst.Show2(new string[]{"one","two"});

inst.Show("one","two"); //this I believe is the greatest benefit
to the optional parameters.
inst.Show(new string[]{"one","two"});


Br,

Mark.
 
J

John B

Mark said:
Limit them to a minimum yes, but they still have their place. Consider this.
They may well have their place but I have yet to come across a scenario
where I would need them.

Not being a real example to me I can only try and interpret what you are
trying to achieve (I understand the code but would need a real life
situation where it would be applicable to me) but I would possibly write
this as:

public void show()
{
show("No Message");
}

public void show(params string[] messages)
{
foreach(string message in messages)
{
show(message);
}
}

public void show(string message)
{
console.writeline(message);
}


If we really wanted the line:
..WriteLine("Messages...");

then I would probably put a private writeheader method which would be
called by the relevant methods.

JB :)

public void Show(params string[] message)
{
if (message.Length == 0)
{
Console.WriteLine("No message!");
return;
}

Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}


public void Show2()
{
Console.WriteLine("No message!");
}
public void Show2(string message)
{
Console.WriteLine("Messages...");
Console.WriteLine(message);
}
public void Show2(string[] message)
{
Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}

Now in this scenario, where we want to pass 0 to many messages in a
parameter for overloading we have had to create 3 different type signatures
wheras using optional params we only need the one. Also note that the
overloading scenario would look even more clumsy if we did checking for zero
length arrays in there as well -since the behaviour of it at present is not
identical to the optional one. Also note for the Show2, if you want to pass
multiple strings, type checking forces you to pass an array, wheras the
optional Show method allows for a list (or an array).

e.g.
inst.Show2(new string[]{"one","two"});

inst.Show("one","two"); //this I believe is the greatest benefit
to the optional parameters.
inst.Show(new string[]{"one","two"});


Br,

Mark.


I cant recall seeing a case where I would consider optional parameters to
be *better than overloading.

To take your case below, we could refactor as:

public bool MyFunction()
{
return Myfunction(false)
}

public bool MyFunction(bool center)
{
//do the dance
}

JB
*better being defined as readibility, ease of use, etc..
 
M

Mark Broadbent

I agree to an extent with what you say although I have still used them
occasionally.
Couple of points though ...
1. What if that extra "Messages..." line was something useful (and many
lines of code)?
1.a Firstly your version fails to account for passing an empty array into
that overload. i.e. The "No Message" message would not be printed from your
code.

1.b You mention this extra private method for the header, but have you
thought what it would do to the code? This would have to be called by each
overload apart from the first, which would mean that when the Show(array
sig) method calls the Show(string sig) method you'd get (if a 3 element
array was passed)...

Messages...
Messages...
.....
Messages...
.....
Messages...
....

2. I still fail to see any benefits to your code in this example over the
optional params. Or to put it another way, what benefit are we getting? If
you write your code so that it displays exactly the same functionality you
will see that it cannot be done as efficiently without using the optional
parameter.

3. Real world example or not, the behaviour that is demonstrated (namely the
fact that we can pass 0 to many arguments and handle it fine in a few lines
of code) can be applied to many many different scenarios.

....I'll give you one. I have a method which takes zero to many attributes
(objects) and adds them into an element object. I want to be able to have
the following to be possible.(apologies for any typos! but you get the
idea)..

Element e = new Element();
e.Add();
e.Add(new Attribute());
e.Add(new Attribute(), new Attribute());
e.Add(new Attribute[]{});
e.Add(new Attribute[]{new Attribute(), new Attribute});


4. What we have here is the same sort of argument that people say against
jumping execution e.g. GOTO. Those people say NEVER use it. Sometimes
though, certain things are more appropriate to certain scenarios and goto
and optional parameters definitely have a time and place.

I'll reiterate on thing though and that is to ONLY use them when appropriate
and that refactoring using overloads is most likely going to be appropriate
in 98% of the time.

Br,

Mark.


John B said:
Mark said:
Limit them to a minimum yes, but they still have their place. Consider
this.
They may well have their place but I have yet to come across a scenario
where I would need them.

Not being a real example to me I can only try and interpret what you are
trying to achieve (I understand the code but would need a real life
situation where it would be applicable to me) but I would possibly write
this as:

public void show()
{
show("No Message");
}

public void show(params string[] messages)
{
foreach(string message in messages)
{
show(message);
}
}

public void show(string message)
{
console.writeline(message);
}


If we really wanted the line:
..WriteLine("Messages...");

then I would probably put a private writeheader method which would be
called by the relevant methods.

JB :)

public void Show(params string[] message)
{
if (message.Length == 0)
{
Console.WriteLine("No message!");
return;
}

Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}


public void Show2()
{
Console.WriteLine("No message!");
}
public void Show2(string message)
{
Console.WriteLine("Messages...");
Console.WriteLine(message);
}
public void Show2(string[] message)
{
Console.WriteLine("Messages...");
foreach (string s in message)
{
Console.WriteLine(s);
}
}

Now in this scenario, where we want to pass 0 to many messages in a
parameter for overloading we have had to create 3 different type
signatures wheras using optional params we only need the one. Also note
that the overloading scenario would look even more clumsy if we did
checking for zero length arrays in there as well -since the behaviour of
it at present is not identical to the optional one. Also note for the
Show2, if you want to pass multiple strings, type checking forces you to
pass an array, wheras the optional Show method allows for a list (or an
array).

e.g.
inst.Show2(new string[]{"one","two"});

inst.Show("one","two"); //this I believe is the greatest
benefit to the optional parameters.
inst.Show(new string[]{"one","two"});


Br,

Mark.


ad wrote:

Why,
Is there some drawback about optional parameters?
Optional parameter is supported by Delphi(Object Pascal) and VB.NET
Why C# ?


I certainly hope not ;)

I cant recall seeing a case where I would consider optional parameters to
be *better than overloading.

To take your case below, we could refactor as:

public bool MyFunction()
{
return Myfunction(false)
}

public bool MyFunction(bool center)
{
//do the dance
}

JB
*better being defined as readibility, ease of use, etc..




"John B" <[email protected]>
???????:[email protected]...


ad wrote:


Does C#2.0 support optional parameters like VB.NET:
Function MyFunction(Optional ByVal isCenter As Boolean = False)



I certainly hope not ;)

JB
 
J

John B

Mark said:
I agree to an extent with what you say although I have still used them
occasionally.
I did not say that they were the root of all evil. What I did say and
stand by is that I have not come across a case where I thought not
having them was a major drawback. :)
Couple of points though ...
1. What if that extra "Messages..." line was something useful (and many
lines of code)?
Still handled by the private header method.
1.a Firstly your version fails to account for passing an empty array into
that overload. i.e. The "No Message" message would not be printed from your
code.
true, easily enough fixed by:


//public methods
public void WriteOutput(string message)
{
//since string is also nullable ;)
if(message == null || message == "") //an extrapolation to assume
that "" equals no message as well
{
WriteNoMessageHeader();
}
else
{
WriteMessageHeader();
Write(Message);
}
}

public void WriteOutput()
{
WriteNoMessageHeader();
}

public void WriteOutput(params string[] messages)
{
if(messages == null || messages.Length == 0)
{
WriteNoMessageHeader();
}
else
{
WriteMessageHeader();
foreach(string s in messages)
{
WriteMessage(s);
}
}
}

//private methods
private void Write(string message)
{
Console.WriteLine(message);
}

private void WriteNoMessageHeader()
{
Write("No Messages");
}

private void WriteMessageHeader()
{
Write("Messages...");
}
1.b You mention this extra private method for the header, but have you
thought what it would do to the code? This would have to be called by each
overload apart from the first, which would mean that when the Show(array
sig) method calls the Show(string sig) method you'd get (if a 3 element
array was passed)...

Messages...
Messages...
....
Messages...
....
Messages...
...

2. I still fail to see any benefits to your code in this example over the
optional params. Or to put it another way, what benefit are we getting? If
you write your code so that it displays exactly the same functionality you
will see that it cannot be done as efficiently without using the optional
parameter.

3. Real world example or not, the behaviour that is demonstrated (namely the
fact that we can pass 0 to many arguments and handle it fine in a few lines
of code) can be applied to many many different scenarios.

...I'll give you one. I have a method which takes zero to many attributes
(objects) and adds them into an element object. I want to be able to have
the following to be possible.(apologies for any typos! but you get the
idea)..
Not being an example that has any context to me I can only speculate but
I would think that it would be able to be handled just as neatly (if not
more so;)) by overloading in the same style as my messages example.
Element e = new Element();
e.Add();
e.Add(new Attribute());
e.Add(new Attribute(), new Attribute());
e.Add(new Attribute[]{});
e.Add(new Attribute[]{new Attribute(), new Attribute});
I dont think that this would be possible with optional in the vb6/vb.net
way.
It would instead be

.....
e.Add(,,new attribute[]{});
4. What we have here is the same sort of argument that people say against
jumping execution e.g. GOTO. Those people say NEVER use it. Sometimes
though, certain things are more appropriate to certain scenarios and goto
and optional parameters definitely have a time and place.
Ah, yes, the fanatics out there :)
I do concede that there are times when they might be appropriate but
have not come across an instance _myself_ so far.
I'll reiterate on thing though and that is to ONLY use them when appropriate
and that refactoring using overloads is most likely going to be appropriate
in 98% of the time.
Agreed, however, tools like optional params provide an easy way out of
hard thinking in a lot of cases and are therefore abused by lazy
programmers.
If everyone used them only when it was the _best_ solution then it would
be good. Since (IMO) they are mostly used in non appropriate situations
and to cater for vb6's lack of support for overloading I for one am
happy the are not catered for in c#.

Cheers

JB :)

<snip>
 
O

Oddball

Would this help - I'm not very good at this but gimme a chance:

public void WriteOutput(object input)
{
System.Console.WriteLine("Messages...");

if (input is string[])
{
// Do string array stuff
//including checking for no message
}
else if (input is string)
{
// Do string stuff
// Including once again, checking for no message
}
else
{
// Do what you do to stupid users who pass silly params
}
}

That should let you use either your string array OR your string.. or a Haddock object if
you want without any overloading, optional parameters or jiggery pokery.

It just uses reflection instead :S But no one is perfect.

The thing with optional parameters vs. overloading is that neither side can win because
both sides have a valid argument. Lazy VB monkeys say optional is easier, anal C#
monkeys say overloading is more structured.

I'm a C# monkey - and was therefor appaled at the suggestion that a method signature
could be so contaminated.... but that's life :)


------------------------------------

Another unchecked rambeling brought to you by:

Oddball
joshua@bf#N0SP4M#wd.co.uk
 
J

John B

Oddball said:
Would this help - I'm not very good at this but gimme a chance:

public void WriteOutput(object input)
{
System.Console.WriteLine("Messages...");

if (input is string[])
{
// Do string array stuff
//including checking for no message
}
else if (input is string)
{
// Do string stuff
// Including once again, checking for no message
}
else
{
// Do what you do to stupid users who pass silly params
throw new argumentoutofrangeexception("Oi peanut! Dont pass stupid
parameters :)"); //hehe
}
}

That should let you use either your string array OR your string.. or a Haddock object if
you want without any overloading, optional parameters or jiggery pokery.
Yeah, not what we want in this case as we do want to limit the types
that can be passed but does the job.
It just uses reflection instead :S But no one is perfect.

The thing with optional parameters vs. overloading is that neither side can win because
both sides have a valid argument. Lazy VB monkeys say optional is easier, anal C#
monkeys say overloading is more structured.
Agreed.

I'm a C# monkey - and was therefor appaled at the suggestion that a method signature
could be so contaminated.... but that's life :)
Me too (evolving (devolving probably according to some) vb6 monkey) :)

Of course they do have their place and would be valuable in some cases.
Doesnt mean I miss them or want them or would be happy if c# supported them.
I cannot _win_ this discussion, nor do I really want to, but if anyone
who queries this question reads this discussion, they might well think a
bit about why they think they need them and can maybe come to a "better"
solution. ("better" by my definition, one that does not need optional
params :p)


JB
 
M

Mark Broadbent

....and finally
John, even your overloaded solution uses the optional params statement
thereby contradicting your entire argument and making your code rewrite
pointless (also let me remind you of my original [nice compact and fully
functional] code)

public void Show(params string[] message){
if (message.Length == 0){
Console.WriteLine("No message!");
return;
}
Console.WriteLine("Messages...");
foreach (string s in message) {
Console.WriteLine(s);
}
}

How on earth you can think that your refactored solution is an improvement
over this leaves me scratching my head. Even if you are relatively new to C#
you would surely see how horrible your refactored code is? Note the line in
your first post "*better being defined as readibility, ease of use, etc..",
well I disagree with every point in this sentence with regards to the
context of the examples I have given.

*Oddball* yeah fine but...
1. You are sacrificing the ability to have the compiler check the types
passed to the procedure. Why provide the ability to pass all types
(including Haddock objects :) when we only want strings and empty in this
example. Typechecking is there for a reason. It was interesting to note that
John didn't decide this was a retrograde step.
2. Testing the types within the method is *not* (as I'm sure you are aware)
an improvement over my code (in any respect e.g. speed size etc).
3. Your code fails to allow passing a list of strings e.g.
"like","thus"

*Back to John*
I remember your line that moved me to action "I cant recall seeing a case
where I would consider optional parameters to be *better than overloading."
which suprisingly you still maintain.
When some posters make these throwaway comments, it puts novices on the
wrong track i.e. a blind belief that something is thus because they read it
somewhere.
That is how bad coding starts.
For instance I dislike the switch statement for a few reasons, but I'd never
say 'I've never seen a time when switch was preferable to using If's and
better structured code' because that would suggest to others that switch
shouldn't ever be used (and is also not entirely accurate). -And be honest
John that is essentially what you've been communicating with regards to
optional parameters.

This is probably going to be my last post in this thread (I hope), but if
you still are not convinced then try posting to this ng something like
'Optional params are a waste of time.I cant recall seeing a case where I
would consider optional parameters to be *better than overloading'.
Hopefully a few mvps will succeed in convincing you where I seem to have
failed.

Br,

Mark.


John B said:
Oddball said:
Would this help - I'm not very good at this but gimme a chance:

public void WriteOutput(object input)
{
System.Console.WriteLine("Messages...");

if (input is string[])
{
// Do string array stuff
//including checking for no message
}
else if (input is string)
{
// Do string stuff
// Including once again, checking for no message
}
else
{
// Do what you do to stupid users who pass silly params
throw new argumentoutofrangeexception("Oi peanut! Dont pass stupid
parameters :)"); //hehe
}
}

That should let you use either your string array OR your string.. or a
Haddock object if you want without any overloading, optional parameters
or jiggery pokery.
Yeah, not what we want in this case as we do want to limit the types that
can be passed but does the job.
It just uses reflection instead :S But no one is perfect.

The thing with optional parameters vs. overloading is that neither side
can win because both sides have a valid argument. Lazy VB monkeys say
optional is easier, anal C# monkeys say overloading is more structured.
Agreed.

I'm a C# monkey - and was therefor appaled at the suggestion that a
method signature could be so contaminated.... but that's life :)
Me too (evolving (devolving probably according to some) vb6 monkey) :)

Of course they do have their place and would be valuable in some cases.
Doesnt mean I miss them or want them or would be happy if c# supported
them.
I cannot _win_ this discussion, nor do I really want to, but if anyone who
queries this question reads this discussion, they might well think a bit
about why they think they need them and can maybe come to a "better"
solution. ("better" by my definition, one that does not need optional
params :p)


JB
------------------------------------

Another unchecked rambeling brought to you by:

Oddball
joshua@bf#N0SP4M#wd.co.uk
 
J

John B

Mark Broadbent wrote:
...HMM
I dont want to get into a flame war over this however I would like to
say that I dont like your condescending tone and IMO either your
comprehension of the discussion is lacking, my ability to express myself
clearly is lacking or we are arguing two different things. Therefore
this _will_ be my last post on the matter.
...and finally
John, even your overloaded solution uses the optional params statement
The point was to illustrate an easy/neat way to get around not having
optional parameters available.
But yes, I should have written it as
....Show(string[] message)...
thereby contradicting your entire argument and making your code rewrite
pointless (also let me remind you of my original [nice compact and fully
functional] code)

public void Show(params string[] message){
if (message.Length == 0){
Console.WriteLine("No message!");
return;
}
Console.WriteLine("Messages...");
foreach (string s in message) {
Console.WriteLine(s);
}
}
How on earth you can think that your refactored solution is an improvement
over this leaves me scratching my head.
OMG :(
The code I wrote was meant to illustrate an easy way to have the ability
for a method which takes zero, 1, 2, zero to many string parameters.
Even if you are relatively new to C#
you would surely see how horrible your refactored code is?
Not what I would call nice, but I would not say horrible, matter of
opinion I suppose.
Note the line in
your first post "*better being defined as readibility, ease of use, etc..",
well I disagree with every point in this sentence with regards to the
context of the examples I have given.

*Oddball* yeah fine but...
1. You are sacrificing the ability to have the compiler check the types
passed to the procedure. Why provide the ability to pass all types
(including Haddock objects :) when we only want strings and empty in this
example. Typechecking is there for a reason.
It was interesting to note that
John didn't decide this was a retrograde step.
Maybe you missed or misread the line
"not what we want in this case as we do want to limit the types that can
be passed"
2. Testing the types within the method is *not* (as I'm sure you are aware)
an improvement over my code (in any respect e.g. speed size etc).
3. Your code fails to allow passing a list of strings e.g.
"like","thus"

*Back to John*
I remember your line that moved me to action "I cant recall seeing a case
where I would consider optional parameters to be *better than overloading."
which suprisingly you still maintain.
Gee, so you are saying I _could_ recall seeing a case where I would
consider optional parameters better than overloading?
You must know me better than myself, neat.
BTW, I do not consider academic examples as "cases" as I was
specifically referring to real life experience.
When some posters make these throwaway comments, it puts novices on the
wrong track i.e. a blind belief that something is thus because they read it
somewhere.
Did you miss the "I cant recall bit.... *better than overloading"?
This is totally different from saying "overloading is always better than
optional parameters." as you are implying that I am saying.
That is how bad coding starts.
For instance I dislike the switch statement for a few reasons, but I'd never
say 'I've never seen a time when switch was preferable to using If's and
better structured code' because that would suggest to others that switch
shouldn't ever be used (and is also not entirely accurate). -And be honest
John that is essentially what you've been communicating with regards to
optional parameters.
Maybe by your reading. Others, I cant answer for but this is _not_ what
I have been trying to communicate. (did you read the bit where I said
"Of course they do have their place and would be valuable in some cases."?)
This is probably going to be my last post in this thread (I hope), but if
you still are not convinced then try posting to this ng something like
'Optional params are a waste of time.
Why would I post something like this when I have never taken this stance?
I cant recall seeing a case where I
would consider optional parameters to be *better than overloading'.
Hopefully a few mvps will succeed in convincing you where I seem to have
failed.
Just to reiterate.
I have not come across a case where I have felt that optional parameters
would be better than overloading.
This does not mean that I consider optional parameters as the root of
all evil or an invaluable construct.
At the same time I do not miss them or consider c# to be any way lacking
without them.

Take care :)
JB

<here there be snippage>
 
T

Tony Maresca

Oddball said:
The thing with optional parameters vs. overloading
is that neither side can win because both sides have
a valid argument.

Sorry to say this, but there is one aspect of this
discussion that I find a bit silly.

Optional parameters are really nothing but a shorthand
means of overloading, facilitated by the compiler.

In Delphi/Object Pascal, when you write:

Function Foo(arg: Integer = 0)
begin
// Implementation
end;

The compiler generates the object code equivalent
of the following:

Function Foo_000
begin
Result := Foo(0);
end;

Function Foo_001(arg: Integer)
begin
// Implementation
end;

In other words, when you declare optional parameters,
the compiler decodes them and from that, generates
the equivalent function overloads for you.

Actual function names of generated overloads are
mangled/decorated similar to how function names
are mangled in C++, which encodes parameter and
return type info into the mangled/decorated name.

So, one aspect of this debate essentially distills down
to little more than if it is better to write the overloads
yourself, or to let the compiler do it for you.

If I may say so, I find it annoying to have to write them
myself.

One obvious advantage of having the compiler generate
the overloads, is that you end up with less rope to hang
yourself with. Another is that you have to write far less
code. For example, three optional arguments means you
must write four overloads.

void Foo(int x, int, y, int z);
void Foo(int x, int y);
void Foo(int x);
void Foo();

Personally, I would much prefer to just do this:

void Foo(int x = 0, int y = 0, int z = 0);

The more important aspect of this, is that unlike some
of the alternatives proposed in this thread that involve
'params' and arrays, overloads/optional arguments have
no runtime overhead. The calls to the correct overloads
are resolved and bound at compile time, and there is no
need for any kind of runtime checking of argument types;
array sizes; etc.
 
M

Mark Broadbent

You are correct, the MSIL generated code is almost identical when compared
side by side against a properly implemented overloaded example against an
optional example.

Your use of using defaults might be preferable if....
1. if they were supported by C#
2. In the scenario we knew the maximum no of parameters that would be used
(and that it wasn't too large).
One reason why the C++ model (with respect to defaults) was not implemented
in C# is due to the method prototype that would be generated and what that
would mean with regards to changing a default (e.g. recompilation).

Also a point that I've made several times which seems to keep getting
unnoticed by every reply is that only optional parameters allow for the use
of a variable length list in the method call -which in some scenarios just
fits the "model" beautifully (in otherwords it just seems right).

Thanks for your input,

Br,

Mark.
"you can lead a horse to water, but..."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top