Proposal: Default Parameters/Named Parameters

C

cody

Why doesn't C# allow default parameters for methods?
An argument against I hear often is that the default parameters would have
to be hardbaken into the assembly, but why? The Jit can take care of this,
if the code is jitted the
"push xyz" instructions of the actual default values can be inserted.

To make things simpler and better readable I'd make all default parameters
named parameters so that you can decide for yourself why one to pass and
which not, rather than relying on massively overlaoded methods which
hopefully provide the best overload for you, for example the Image.DrawImage
method has 20 overloads.

I propose a syntax like the following:

public void Open(string path, AccessMode mode = AccessMode.Read, int
bufferSize=1024)
{
// ...
}

As you can see, path is a regular parameter which cannot be omitted, whereas
Mode and BufferSize provide default values an can be omitted when calling
the method.
Named parameters can only be declare behind all regular parameters and if
you have params parameters (variable parameterlist) is must be declared at
the end of the parameterlist. Although you can omit the named parameters if
you pass them they should appear in the same order as they were declared for
better readability.

You could call the example method like the following:

Open("text.txt", @mode=AccessMode.Write, @bufferSize=512);
Open("text.txt", @bufferSize=512);
Open("text.txt", @mode=AccessMode.Write);
Open("text.txt");

Note that an @ sign has to appear before all named parameter so that you
have no naming conflicts with other variables in the callers context.

Additionally there can not be more that one method with the same name and
the same regular parameters to avoid ambigiuty, so:

Foo(int i, string a="");
Foo(int i, double f=1.0f);

Would not be allowed because the call Foo(100) could not be resolved.

What do you think about that? Would it even be possible to do that in the
CLR or would there have be so huge changes that it can't be done in the
future?
 
B

Bruce Wood

Anders Hejlsberg touched on this during his (very interesting)
whiteboard talk:

http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20040624csharpah/manifest.xml

Basically, there are several ways to implement default arguments.

The first is to have the compiler build the defaults into the method
call on the caller's side. Essentially the called method would receive
all of its parameter arguments every time and not have to worry about
missing arguments, because the caller would take care of filling in the
blank. Hejlsberg's objection to this is that it would involve compiling
the defaults into the caller, which would break all of your callers if
you ever changed the defaults.

However, you're suggesting doing it during the JIT phase, which would
remove that objection, but require changes to the IL. An interesting
idea.

The other possibility is to have the called method handle defaulting,
but this would come with a mondo speed penalty, as I think Hejlsberg
points out.

Personally, the only place I've found that really could use optional
parameters is when writing constructors. Most other methods don't
experience the kind of massive overloading that constructors do, and
the only part of writing constructor overloads that I hate is having to
copy (and maintain) the documentation on every overload.

Someone also mentions this to Hejlsberg as a compromise: allowing
sharing of XML documentation between overloaded methods / constructors.
That would make me happy enough, without changing the IL, the JITter,
and the definition of what a C# method signature looks like.
 
B

Bob Powell [MVP]

Default parameters are not needed when overloading can do the job for you.

The parameter lists scan from left to right anyway so all you have to do is
overload the function once for each extra parameter in the list.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
B

Bruce Wood

There is one situation in which _named_ parameters, as outlined by
cody, would be helpful, and that is when you have what really ought to
be two different overloads that take the same parameter types,
something like

public Page (int width, int height)

public Page (int width)

now, if you want another constructor overload for Page that creates a
Page with a default width and a given height, you're stuck.

However, I'm fairly certain that it's not worth reworking the C#
language and the IL in order to handle this one, rare case.
 
C

cody

Please tell me if you should have a new idea!

Bob Powell said:
It strikes me that this can be done with attributes. I'll have to think
about it.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
C

cody

Personally, the only place I've found that really could use optional
parameters is when writing constructors. Most other methods don't
experience the kind of massive overloading that constructors do, and
the only part of writing constructor overloads that I hate is having to
copy (and maintain) the documentation on every overload.

There are a lot of methods that take a lot for than 5 arguments and have
multiple overloads like the framework class Image which method DrawImage has
20 overloads!

I think this heavy overlading makes the code less readable and unnessaccary
bloated.
So if you have just 5 overloads you have to write at least 5*5 lines of code
and this is without documentation. You often do not see which overloaded
method calls which and you sometimes end up with an endless recursion. You
have also take care that the parameters ar in the same order in each method
to provide good readability.
Additionally if you do not do it clean and put additional code in the
overadloaded methods beside the call of the "main worker method" end up with
very messy code like that:

Foo(double d, string s, int i, bool b)
{
// dostuff
}

Foo(double d, string s, int i)
{
Foo(d, s, 0, false);
// do some stuff here
}

Foo()
{
Foo(0, "", 0, false);
// do some stuff here
}

Foo(double d)
{
Foo(0, "", 0, false);
// do some stuff here
}

Foo(int i)
{
Foo(0, "", i, false);
// do some stuff here
}

Foo(double d, string s)
{
Foo(d, s, i, false);
// do some stuff here
}

At the end, you have a huge piece a crap in you texteditor where you just
would have needed JUST ONE SIMPLE METHOD.
 
B

Bruce Wood

Do I need to point out that if each overload has some extra "do some
stuff here" code that isn't in the "master method" then you couldn't
code it any better using default arguments? :)

Really, for my money the only annoying thing about having to use
overloads is copying the documentation over and over again. Fix that
problem and I would be quite happy with the status quo.
 

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