By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,644 Members | 2,423 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,644 IT Pros & Developers. It's quick & easy.

[Proposal] Named and Optional Parameters with Default Values

P: n/a
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)

so here we go..

To make things simpler and better readable I'd make all default parameters
named parameters so that you can decide for yourself which 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 and can be omitted when calling
the method.
Named parameters can only be declared 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 ambiguity, 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.

How will it work?
----------------------------

the following method:

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

would generate the following code:

public struct OpenParams
{
public AccessMode mode;
public int bufferSize;

// because we cannot have parameterless ctors in structs
public static OpenParams DefaultValues
{
get{
OpenParams instance = new OpenParams();
instance.mode = AccessMode.Read;
instance.bufferSize=1024;
return instance;
}
}
}

public void Open(string path, ref OpenParams parms)
{
// ...
}

and the call:

Open("text.txt", $bufferSize=512);

is compiled as:

OpenParams parms = OpenParams.DefaultValues;
parms.bufferSize=512;
Open("text.txt", ref parms);
So what do you think? Is it just another stupid idea or may it be worth the
effort and valueable for csharp programmers?

Jun 9 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
I like it.

"cody" <de********@gmx.de> wrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)

so here we go..

To make things simpler and better readable I'd make all default parameters
named parameters so that you can decide for yourself which 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 and can be omitted when calling
the method.
Named parameters can only be declared 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 ambiguity, 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.

How will it work?
----------------------------

the following method:

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

would generate the following code:

public struct OpenParams
{
public AccessMode mode;
public int bufferSize;

// because we cannot have parameterless ctors in structs
public static OpenParams DefaultValues
{
get{
OpenParams instance = new OpenParams();
instance.mode = AccessMode.Read;
instance.bufferSize=1024;
return instance;
}
}
}

public void Open(string path, ref OpenParams parms)
{
// ...
}

and the call:

Open("text.txt", $bufferSize=512);

is compiled as:

OpenParams parms = OpenParams.DefaultValues;
parms.bufferSize=512;
Open("text.txt", ref parms);
So what do you think? Is it just another stupid idea or may it be worth
the effort and valueable for csharp programmers?

Jun 9 '06 #2

P: n/a
It's obvious you put a lot of thought into your proposal, but personally I'm
against optional parameters. Given that we have overloading in .NET, I
don't believe that optional parameters should have been carried over to
VB.NET much less that they should now be added to C#. Yes, there may be
situations where a method has several overloads. But the signature of those
overloads give additional information that could be lost or at least
obscured if optional parameters were used.

Say you have a method with five parameters --- A, B, C, D, E -- where D and
E are not required or where default values are OK. In this case, the idea
of optional parameters makes sense. But what if you have a situation where
you have odd combinations of those five parameters that must be used? For
example, you might have two versions of a method, one which accepts
parameters A, D, and E, and another which accepts A, B, and C. Using
overloading, you'd obviously use two overloaded methods. There'd be no
ambiguity about which combinations of the five parameters were valid.
Whereas if you tried to use optional parameters to design a single method,
you'd have to make B, C, D, and E optional. But there'd be no way to tell
what parameters were optional in which context.

Could optional parameters be used responsibly by programmers who knew to
avoid this issue? Sure. But why bother introducing an alternative when the
requirement is so elegantly handled by overloading? So you get an
occasional method that has several overloads. So what. There may be a lot
of them, but at least you know that they represent every valid combination
of parameters rather than having to guess it. For me, the option of making
the language more complex isn't worth the "benefit" of eliminating
superoverloaded methods.

Regards,

- Mitchell S. Honnert
"cody" <de********@gmx.de> wrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)

so here we go..

To make things simpler and better readable I'd make all default parameters
named parameters so that you can decide for yourself which 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 and can be omitted when calling
the method.
Named parameters can only be declared 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 ambiguity, 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.

How will it work?
----------------------------

the following method:

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

would generate the following code:

public struct OpenParams
{
public AccessMode mode;
public int bufferSize;

// because we cannot have parameterless ctors in structs
public static OpenParams DefaultValues
{
get{
OpenParams instance = new OpenParams();
instance.mode = AccessMode.Read;
instance.bufferSize=1024;
return instance;
}
}
}

public void Open(string path, ref OpenParams parms)
{
// ...
}

and the call:

Open("text.txt", $bufferSize=512);

is compiled as:

OpenParams parms = OpenParams.DefaultValues;
parms.bufferSize=512;
Open("text.txt", ref parms);
So what do you think? Is it just another stupid idea or may it be worth
the effort and valueable for csharp programmers?

Jun 9 '06 #3

P: n/a
> It's obvious you put a lot of thought into your proposal, but personally
I'm against optional parameters. Given that we have overloading in .NET,
I don't believe that optional parameters should have been carried over to
VB.NET much less that they should now be added to C#.
And my opinion is that a good language should not reqire the programmer to
duplicate a methods declaration lots of times to provide optional
parameters. Also the xml docs always have to be duplicated.
Also, when having lots of parameters a language should not rely on the
correct order of parameters but instead givt the ability to pass arguments
by their name to make the code cleaner and easier to read.
no one can guess what a call to Graphics.DrawImage with its tail if
parameters does without having to read the documentation.
Say you have a method with five parameters --- A, B, C, D, E -- where D
and E are not required or where default values are OK. In this case, the
idea of optional parameters makes sense. But what if you have a situation
where you have odd combinations of those five parameters that must be
used? For example, you might have two versions of a method, one which
accepts parameters A, D, and E, and another which accepts A, B, and C.
Using overloading, you'd obviously use two overloaded methods.


Sure, in the case where optional arguments exclude each other, you *have* to
use two different methods, this is no cure for every disease :)

I tried hard and experimented a bit with the 30 existing overloads of
Graphics.DrawImage and noted that with optional parameters the number of
overloads can be reduced to 12:

Graphics.DrawImage (Image, Point)
Graphics.DrawImage (Image, PointF)
Graphics.DrawImage (Image, Rectangle, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, RectangleF, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Int32, Int32, Int32, Int32)
Graphics.DrawImage (Image, Int32, Int32, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, Single, Single)
Graphics.DrawImage (Image, Point[], Rectangle, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, PointF[], RectangleF, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, Rectangle, Int32, Int32, Int32, Int32,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)
Graphics.DrawImage (Image, Rectangle, Single, Single, Single, Single,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)

This is not as good as I expected but it would make client code much cleaner
and you can decide which parameter to leave out instead of relying the
appropriate overload to exist which does not cover every case (What if I
want to pass DrawImageAbort but not ImageAttributes or the GraphicsUnit?
What if I want to pass position of the image with Point then I cannot pass
any other parameter just because there is no overload for that).
Jun 10 '06 #4

P: n/a
"cody" <de********@gmx.de> wrote in message
news:uP**************@TK2MSFTNGP02.phx.gbl...
It's obvious you put a lot of thought into your proposal, but personally
I'm against optional parameters. Given that we have overloading in .NET,
I don't believe that optional parameters should have been carried over to
VB.NET much less that they should now be added to C#.
And my opinion is that a good language should not reqire the programmer to
duplicate a methods declaration lots of times to provide optional
parameters.

Ah, but the different overloads are not duplications. They are giving extra
information that might otherwise be lost or obscured if optional parameters
were used. Each overload is telling the user "Hey, this particular
combination of parameters is valid. If you want to pass in a default value,
that's your business."
Also the xml docs always have to be duplicated. I believe this to be a limitation of the documentation tool -- that you
can't give a description at the method level instead of the overload
level -- rather than a limitation of the language.
Also, when having lots of parameters a language should not rely on the
correct order of parameters but instead givt the ability to pass arguments
by their name to make the code cleaner and easier to read. Personally, I don't see this as a big deal either way. I can see a case for
named parameters, but I don't think their inseperable from the concept of
optional parameters.
no one can guess what a call to Graphics.DrawImage with its tail if
parameters does without having to read the documentation.

I don't think this is true, at least not as a principle that can be applied
to the concept of overloading. Again, with overloading there may be several
overloads you have to scroll through, but there is a definitive list of
allowable parameter combinations which can be used. In fact,I think the use
of optional parameters would *increase* the chance of having to look at the
documentation because they would more likely hide these valid combinations.
"OK, I remember that A is required and the rest are optional. But can I
call the method with just A, E, and C? I don't know! There's no way to
tell from just the signatures!"
Say you have a method with five parameters --- A, B, C, D, E -- where D
and E are not required or where default values are OK. In this case, the
idea of optional parameters makes sense. But what if you have a
situation where you have odd combinations of those five parameters that
must be used? For example, you might have two versions of a method, one
which accepts parameters A, D, and E, and another which accepts A, B, and
C. Using overloading, you'd obviously use two overloaded methods.


Sure, in the case where optional arguments exclude each other, you *have*
to use two different methods, this is no cure for every disease :)

I tried hard and experimented a bit with the 30 existing overloads of
Graphics.DrawImage and noted that with optional parameters the number of
overloads can be reduced to 12:

Graphics.DrawImage (Image, Point)
Graphics.DrawImage (Image, PointF)
Graphics.DrawImage (Image, Rectangle, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, RectangleF, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Int32, Int32, Int32, Int32)
Graphics.DrawImage (Image, Int32, Int32, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, Single, Single)
Graphics.DrawImage (Image, Point[], Rectangle, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, PointF[], RectangleF, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, Rectangle, Int32, Int32, Int32, Int32,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)
Graphics.DrawImage (Image, Rectangle, Single, Single, Single, Single,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)

This is not as good as I expected but it would make client code much
cleaner and you can decide which parameter to leave out instead of relying
the appropriate overload to exist which does not cover every case (What if
I want to pass DrawImageAbort but not ImageAttributes or the GraphicsUnit?
What if I want to pass position of the image with Point then I cannot pass
any other parameter just because there is no overload for that).

I admit that with methods that have many parameters, the number of overloads
increases greatly. But in my opinion, these superoverloaded methods are
rare enough that it does not warrant the drastic measure of introducing
optional parameters to C#. In your statement above, you are using the word
"rely" in a negative sense; to me it's a positive thing. I can rely on the
designer of a method to show me the allowable combination of parameters by
using the overloaded methods. I don't have to look in the documentation; I
can see it just by the method definition alone. If not having optional
parameters give me this assurance, but in rare cases, I don't have the exact
overload I need, then so be it. I'm OK with that.

- Mitchell S. Honnert
Jun 12 '06 #5

P: n/a
Mitchell S. Honnert wrote:
"cody" <de********@gmx.de> wrote in message
news:uP**************@TK2MSFTNGP02.phx.gbl...
It's obvious you put a lot of thought into your proposal, but personally
I'm against optional parameters. Given that we have overloading in .NET,
I don't believe that optional parameters should have been carried over to
VB.NET much less that they should now be added to C#. And my opinion is that a good language should not require the programmer to
duplicate a methods declaration lots of times to provide optional
parameters.

Ah, but the different overloads are not duplications. They are giving extra
information that might otherwise be lost or obscured if optional parameters
were used. Each overload is telling the user "Hey, this particular
combination of parameters is valid. If you want to pass in a default value,
that's your business."


As I said, if using optional parameters *all* combinations *must* be
valid. if not, you have to split the method into multiple overloads as I
showed with the DrawImage example (the Int32,Int32,Int32,Int32 overload
is certainly not compatible with the Point or Rectangle overload - the
question also is whether these overloads are useful, IMO they complicate
the method more than they help - is it better readable to pass 4 x int
instead of one rectangle - certainly not (at least not if the method
already has too much parameters)).

Thus, with optional parameters you can rely on the fact that all
combinations are valid. And nothing get obscured, intellisense should
also show you the optional parameters.

Additional you can actually see the default values and do not have to
guess it (or look in the documentation). Currently if you use
string.Compare(string, string) vs. string.Compare(string, string, bool)
you do not see which default value the bool value is when omitting it at
the call, with built in optional parameters, intellisense can show it to
you.

Also the xml docs always have to be duplicated.

I believe this to be a limitation of the documentation tool -- that you
can't give a description at the method level instead of the overload
level -- rather than a limitation of the language.
Also, when having lots of parameters a language should not rely on the
correct order of parameters but instead givt the ability to pass arguments
by their name to make the code cleaner and easier to read.

Personally, I don't see this as a big deal either way. I can see a case for
named parameters, but I don't think their inseperable from the concept of
optional parameters.
no one can guess what a call to Graphics.DrawImage with its tail if
parameters does without having to read the documentation.

I don't think this is true, at least not as a principle that can be applied
to the concept of overloading. Again, with overloading there may be several
overloads you have to scroll through, but there is a definitive list of
allowable parameter combinations which can be used. In fact,I think the use
of optional parameters would *increase* the chance of having to look at the
documentation because they would more likely hide these valid combinations.
"OK, I remember that A is required and the rest are optional. But can I
call the method with just A, E, and C? I don't know! There's no way to
tell from just the signatures!"
Say you have a method with five parameters --- A, B, C, D, E -- where D
and E are not required or where default values are OK. In this case, the
idea of optional parameters makes sense. But what if you have a
situation where you have odd combinations of those five parameters that
must be used? For example, you might have two versions of a method, one
which accepts parameters A, D, and E, and another which accepts A, B, and
C. Using overloading, you'd obviously use two overloaded methods.

Sure, in the case where optional arguments exclude each other, you *have*
to use two different methods, this is no cure for every disease :)

I tried hard and experimented a bit with the 30 existing overloads of
Graphics.DrawImage and noted that with optional parameters the number of
overloads can be reduced to 12:

Graphics.DrawImage (Image, Point)
Graphics.DrawImage (Image, PointF)
Graphics.DrawImage (Image, Rectangle, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, RectangleF, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Int32, Int32, Int32, Int32)
Graphics.DrawImage (Image, Int32, Int32, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, Single, Single)
Graphics.DrawImage (Image, Point[], Rectangle, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, PointF[], RectangleF, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, Rectangle, Int32, Int32, Int32, Int32,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)
Graphics.DrawImage (Image, Rectangle, Single, Single, Single, Single,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)

This is not as good as I expected but it would make client code much
cleaner and you can decide which parameter to leave out instead of relying
the appropriate overload to exist which does not cover every case (What if
I want to pass DrawImageAbort but not ImageAttributes or the GraphicsUnit?
What if I want to pass position of the image with Point then I cannot pass
any other parameter just because there is no overload for that).

I admit that with methods that have many parameters, the number of overloads
increases greatly. But in my opinion, these superoverloaded methods are
rare enough that it does not warrant the drastic measure of introducing
optional parameters to C#. In your statement above, you are using the word
"rely" in a negative sense; to me it's a positive thing. I can rely on the
designer of a method to show me the allowable combination of parameters by
using the overloaded methods. I don't have to look in the documentation; I
can see it just by the method definition alone. If not having optional
parameters give me this assurance, but in rare cases, I don't have the exact
overload I need, then so be it. I'm OK with that.

- Mitchell S. Honnert

Jun 12 '06 #6

P: n/a
cody wrote:
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)

<snip/>
So what do you think? Is it just another stupid idea or may it be worth the
effort and valueable for csharp programmers?


I really respect the effort that you have put into this post, but I
think (based on my experience) that this is not a simple feature at all.

Let's take a look at your slightly extended example:

class Base
{
public virtual void Open(string path,
AccessMode mode = AccessMode.Read,
int bufferSize=1024)
{
// ...
}
}
// derived class
class Derived
{
public virtual void Open(string path,
AccessMode mode = AccessMode.Write,
int bufferSize=1024)
{
// ...
}
}
Base b = new Derived();
b.Open("..");

Is it open for read or for write? And this is just a starter! I just
have to dig in my dark memories of the C++ world... Just think about
shadowing a method with "new", overloaded methods that are scattered
over an inheritance hierarchy, abstract methods and last but not least
interfaces. It is sure possible to define a meaningful behavior for all
of it (it was possible in C++), but this isn't a simple and easy feature
than anymore. Actually it is one of the pitfalls that Scott Meyers
mentions in his famous Effective C++ books.

Maintenance/Feature development (Keeping alive the features you have and
add new ones ) is the most difficult part in a software project.
Maintenance is done by reading and interpreting code so that you can
extend or refactor it. Features like this in the best case add an
unnecessary difficulty to it, because now I have to take default
variables into account.
Cheers,
Andy
Jun 12 '06 #7

P: n/a
> Thus, with optional parameters you can rely on the fact that all
combinations are valid. And nothing get obscured, intellisense should also
show you the optional parameters. This is true in the examples you've given, but in my experience with
VB6\VB.NET optional programmers are not used to reduce the overloads from
about 30 to 12, but to reduce them from about three to one. In other words,
even when creating three overloads would make sense -- because you only
really have three valid combinations of your parameters -- the programmer
would use optional parameters "because it's easier". This is such an awful
scenario that I personally wouldn't want to bring over that corruption from
the VB world. (For the record, VB.NET is my language of choice. I just
think optional parameters in VB.NET is an example of where MS pandered too
much to the old school VB6 developers.) Would C# programmers "know better"?
Probably, but it's not worth the risk.
Additional you can actually see the default values and do not have to
guess it (or look in the documentation). This is a really good point. I'll admit to having had to look up a default
value of some of the sparser overloads, especially constructors. However,
for me this wouldn't sway my opinion that optional parameters wouldn't be
worth the drawbacks.

- Mitchell S. Honnert

"cody" <de********@gmx.de> wrote in message
news:OO**************@TK2MSFTNGP03.phx.gbl... Mitchell S. Honnert wrote:
"cody" <de********@gmx.de> wrote in message
news:uP**************@TK2MSFTNGP02.phx.gbl...
It's obvious you put a lot of thought into your proposal, but
personally I'm against optional parameters. Given that we have
overloading in .NET, I don't believe that optional parameters should
have been carried over to VB.NET much less that they should now be
added to C#.
And my opinion is that a good language should not require the programmer
to duplicate a methods declaration lots of times to provide optional
parameters.

Ah, but the different overloads are not duplications. They are giving
extra information that might otherwise be lost or obscured if optional
parameters were used. Each overload is telling the user "Hey, this
particular combination of parameters is valid. If you want to pass in a
default value, that's your business."


As I said, if using optional parameters *all* combinations *must* be
valid. if not, you have to split the method into multiple overloads as I
showed with the DrawImage example (the Int32,Int32,Int32,Int32 overload is
certainly not compatible with the Point or Rectangle overload - the
question also is whether these overloads are useful, IMO they complicate
the method more than they help - is it better readable to pass 4 x int
instead of one rectangle - certainly not (at least not if the method
already has too much parameters)).

Thus, with optional parameters you can rely on the fact that all
combinations are valid. And nothing get obscured, intellisense should also
show you the optional parameters.

Additional you can actually see the default values and do not have to
guess it (or look in the documentation). Currently if you use
string.Compare(string, string) vs. string.Compare(string, string, bool)
you do not see which default value the bool value is when omitting it at
the call, with built in optional parameters, intellisense can show it to
you.

Also the xml docs always have to be duplicated.

I believe this to be a limitation of the documentation tool -- that you
can't give a description at the method level instead of the overload
level -- rather than a limitation of the language.
Also, when having lots of parameters a language should not rely on the
correct order of parameters but instead givt the ability to pass
arguments by their name to make the code cleaner and easier to read.

Personally, I don't see this as a big deal either way. I can see a case
for named parameters, but I don't think their inseperable from the
concept of optional parameters.
no one can guess what a call to Graphics.DrawImage with its tail if
parameters does without having to read the documentation.

I don't think this is true, at least not as a principle that can be
applied to the concept of overloading. Again, with overloading there may
be several overloads you have to scroll through, but there is a
definitive list of allowable parameter combinations which can be used.
In fact,I think the use of optional parameters would *increase* the
chance of having to look at the documentation because they would more
likely hide these valid combinations. "OK, I remember that A is required
and the rest are optional. But can I call the method with just A, E, and
C? I don't know! There's no way to tell from just the signatures!"
Say you have a method with five parameters --- A, B, C, D, E -- where D
and E are not required or where default values are OK. In this case,
the idea of optional parameters makes sense. But what if you have a
situation where you have odd combinations of those five parameters that
must be used? For example, you might have two versions of a method,
one which accepts parameters A, D, and E, and another which accepts A,
B, and C. Using overloading, you'd obviously use two overloaded
methods.
Sure, in the case where optional arguments exclude each other, you
*have* to use two different methods, this is no cure for every disease
:)

I tried hard and experimented a bit with the 30 existing overloads of
Graphics.DrawImage and noted that with optional parameters the number of
overloads can be reduced to 12:

Graphics.DrawImage (Image, Point)
Graphics.DrawImage (Image, PointF)
Graphics.DrawImage (Image, Rectangle, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, RectangleF, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Int32, Int32, Int32, Int32)
Graphics.DrawImage (Image, Int32, Int32, Rectangle, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, RectangleF, GraphicsUnit)
Graphics.DrawImage (Image, Single, Single, Single, Single)
Graphics.DrawImage (Image, Point[], Rectangle, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, PointF[], RectangleF, GraphicsUnit,
ImageAttributes, Graphics.DrawImageAbort, Int32)
Graphics.DrawImage (Image, Rectangle, Int32, Int32, Int32, Int32,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)
Graphics.DrawImage (Image, Rectangle, Single, Single, Single, Single,
GraphicsUnit, ImageAttributes, Graphics.DrawImageAbort, IntPtr)

This is not as good as I expected but it would make client code much
cleaner and you can decide which parameter to leave out instead of
relying the appropriate overload to exist which does not cover every
case (What if I want to pass DrawImageAbort but not ImageAttributes or
the GraphicsUnit? What if I want to pass position of the image with
Point then I cannot pass any other parameter just because there is no
overload for that).

I admit that with methods that have many parameters, the number of
overloads increases greatly. But in my opinion, these superoverloaded
methods are rare enough that it does not warrant the drastic measure of
introducing optional parameters to C#. In your statement above, you are
using the word "rely" in a negative sense; to me it's a positive thing.
I can rely on the designer of a method to show me the allowable
combination of parameters by using the overloaded methods. I don't have
to look in the documentation; I can see it just by the method definition
alone. If not having optional parameters give me this assurance, but in
rare cases, I don't have the exact overload I need, then so be it. I'm
OK with that.

- Mitchell S. Honnert

Jun 12 '06 #8

P: n/a

cody wrote:
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)


You posted this idea back in February 2005:

http://groups.google.com/group/micro...38375540a95f34

and I posted a link to a whiteboard discussion with Anders Hejlsberg in
which he points out the problems with the approach you're suggesting:

http://msdn.microsoft.com/msdntv/epi...h/manifest.xml

Briefly, the difficulty is that implementing default arguments in the
compiler, rather than the CLR, creates versioning problems: if you
release a new version of your commercial DLL with new (let's say
corrected) defaults for some of your parameters, your callers don't get
the new defaults unless they recompile their client code.

I agree with his objection: if there's going to be defaulting, I would
want it so that the defaults are picked up from the called assembly at
runtime, not compiled into the caller's assembly at compile time. That
way you can update a DLL and pick up new defaults without recompiling
all client code.

This could be done by the compiler, but it would be clumsy: it would
involve trolling the called assembly on every method call looking for
attributes attached to the called method, and getting default values
from there. Very slow and very ugly.

If I recall, this was also Anders' objection to run-time resolution of
defaults, which would resolve the problems I outlined above: it would
add unacceptable overhead to method calls. Can't be sure, though: I
haven't watched the video in over a year.

I made a suggestion to MSDN Feedback regarding the XML documentation
thing, but I can no longer find my suggestion in their reworked
feedback site:

http://connect.microsoft.com/feedbac...spx?SiteID=210

In that same whiteboard discussion (and again at PDC'05), suggestions
were made to Anders about having the compiler allow documentation
sharing between overloads or on inheritance. He seemed to like the
idea, but I've never seen it received with much enthusiasm by the C#
team, and I with it were. Repeating documentation every time I inherit
/ overload is a pain, and it's time I would prefer to use doing
something more productive, like posting to newsgroups. :-)

Jun 12 '06 #9

P: n/a

Bruce Wood wrote:
cody wrote:
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)


You posted this idea back in February 2005:

http://groups.google.com/group/micro...38375540a95f34

and I posted a link to a whiteboard discussion with Anders Hejlsberg in
which he points out the problems with the approach you're suggesting:

http://msdn.microsoft.com/msdntv/epi...h/manifest.xml


Oh, my bad, my bad. I didn't properly read your post. My only excuse is
that I have a cold today and my brain is all foggy. Let me tackle this
one again.

There are still problems here, but they're not as severe as the ones I
outlined. For example, it's sort of counterintuitive that if you have
default values for parameters, and you release a DLL in which some
methods have new parameters but they have defaults, you still have to
recompile client code in order that it be compatible (otherwise the
MethodParams struct that you pass in would not be the right size). It's
not the end of the world, but addressing it would require changes to
the CLR.

Another way to do what you're thinking of is to have the compiler
quietly use nullable types where parameters are declared optional, but
this involves boxing and unboxing, even if it's behind the scenes, and
still carries with it the problem that adding new parameters, even if
they have defaults, would require recompilation of all client code.

I don't really see any elegant way to handle this without changes to
the CLR and the way that parameters are placed on the stack, so that
called methods would have some built-in notion of "argument not
supplied" which would occur if the caller signaled that it wished to
omit an argument, or if the number of arguments falls short of the
required number.

Anyway, as I remarked in February, I'd much rather just see a way to
share XML doc between overloads / overrides. I consider that a much
bigger pain in the butt than the multiple-overload thing.

Jun 12 '06 #10

P: n/a
Bruce Wood wrote:
Bruce Wood wrote:
cody wrote:
I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :) You posted this idea back in February 2005:

http://groups.google.com/group/micro...38375540a95f34

and I posted a link to a whiteboard discussion with Anders Hejlsberg in
which he points out the problems with the approach you're suggesting:

http://msdn.microsoft.com/msdntv/epi...h/manifest.xml


Oh, my bad, my bad. I didn't properly read your post. My only excuse is
that I have a cold today and my brain is all foggy. Let me tackle this
one again.

There are still problems here, but they're not as severe as the ones I
outlined. For example, it's sort of counterintuitive that if you have
default values for parameters, and you release a DLL in which some
methods have new parameters but they have defaults, you still have to
recompile client code in order that it be compatible (otherwise the
MethodParams struct that you pass in would not be the right size).


Since when do clients have to be recompiled when a struct is changed?
You only have to recompile when you remove an optional param
(or change its type) that is explicitly used by the client.

Another way to do what you're thinking of is to have the compiler
quietly use nullable types where parameters are declared optional, but
this involves boxing and unboxing, even if it's behind the scenes, and
still carries with it the problem that adding new parameters, even if
they have defaults, would require recompilation of all client code.

I don't really see any elegant way to handle this without changes to
the CLR and the way that parameters are placed on the stack, so that
called methods would have some built-in notion of "argument not
supplied" which would occur if the caller signaled that it wished to
omit an argument, or if the number of arguments falls short of the
required number.


Huh? We do not need to change the CLR. I do not understand your concerns.

Jun 13 '06 #11

P: n/a
for anyone interested, I stumbled across a problem which would (at least
IMO) require Named and Optional Parameters. I made a posting about it in
microsoft.public.dotnet.general, entitled "Design Question für
entity-base-classes"

here is a copy:

------------
I have a baseclass named Entity. All stuff like Customer,Invoice,Article
and so on will derive from this class.
I have fields in the base class like "tablename" and "primarykeyname"
which is used to create the database operations on the class.

now the question is: how do I enable my base class to initialize these
values, but the values must not be changeable at a later time.

I do not want the variables to be set as in the baseclass' ctor:

public Derived():base("customer", "custID") // I don't want it this way

because I want to be able to add more variables at a later time without
breaking derives classes.

additionally I do not want these variables to reside directly in my
entitybaseclass but instead in a separate nested class which should be
accessible from outside the class with a property:

class BaseEntity
{
EntityParams parms = new EntityParams();

public EntityParams EntityParameter
{
get { return parms; }
}
}

But now the question is, how do I ensure that this object is NOT
modified after initialisation of the BaseEntity instance?
sure I could put Exceptions in each property.

And I do not want initialize the EntityParams class like this:

EntityParams parms = new EntityParams(param1, param2, param3...);

but instead I want to set the properties separately (so that later
additions of parameters do not break derived classes).

The funny thing is that I had a few week an idea of inventing
named/optional parameters which would solve exactly that problem :)

Is there a good solution for that? Did you ever stumbled across such a
problem?
Jun 20 '06 #12

P: n/a
cody,

On .NET2.0 you can declare properties where the get accessor is public, but
the set is internal for example. This might solve your problem. I know that
this is not quite what you asked fot thought.
--
Stoitcho Goutsev (100)
"cody" <de********@gmx.de> wrote in message
news:eQ**************@TK2MSFTNGP03.phx.gbl...
for anyone interested, I stumbled across a problem which would (at least
IMO) require Named and Optional Parameters. I made a posting about it in
microsoft.public.dotnet.general, entitled "Design Question für
entity-base-classes"

here is a copy:

------------
I have a baseclass named Entity. All stuff like Customer,Invoice,Article
and so on will derive from this class.
I have fields in the base class like "tablename" and "primarykeyname"
which is used to create the database operations on the class.

now the question is: how do I enable my base class to initialize these
values, but the values must not be changeable at a later time.

I do not want the variables to be set as in the baseclass' ctor:

public Derived():base("customer", "custID") // I don't want it this way

because I want to be able to add more variables at a later time without
breaking derives classes.

additionally I do not want these variables to reside directly in my
entitybaseclass but instead in a separate nested class which should be
accessible from outside the class with a property:

class BaseEntity
{
EntityParams parms = new EntityParams();

public EntityParams EntityParameter
{
get { return parms; }
}
}

But now the question is, how do I ensure that this object is NOT modified
after initialisation of the BaseEntity instance?
sure I could put Exceptions in each property.

And I do not want initialize the EntityParams class like this:

EntityParams parms = new EntityParams(param1, param2, param3...);

but instead I want to set the properties separately (so that later
additions of parameters do not break derived classes).

The funny thing is that I had a few week an idea of inventing
named/optional parameters which would solve exactly that problem :)

Is there a good solution for that? Did you ever stumbled across such a
problem?

Jun 20 '06 #13

P: n/a
Stoitcho Goutsev (100) wrote:
cody,

On .NET2.0 you can declare properties where the get accessor is public, but
the set is internal for example. This might solve your problem. I know that
this is not quite what you asked fot thought.


Right, this was not what I was looking for :)
*I want* the properties somehow to be assignable but just once and not
later again. Maybe I have to live with it and put Exceptions in each
property forbidding reassign.
While this is might be not good style it will work as long as nobody has
a better idea or Microsoft finally starts to support optional
parameters. I mean they put so much stupid cr*p into C# 3.0, mutating it
into a functional script language, but the simplest things like optional
or named parameters does still not work, although most programming
languages support it (with good reason).
Jun 20 '06 #14

P: n/a
I really don't agree with the use of optional parameters. It doesn't
solve anything that overloads of methods don't solve already. Personally, I
think that optional parameters actually muddies things a bit, especially if
you are going to keep overloading as an option.

For example, what does the compiler do in this situation?

public void DoSomething(int i)
{}

public void DoSomething(optional int i)
{}

How does it resolve it?

In regards to your specific problem, I would define the base class with
a virtual method which returns an instance of the class which you use to
pass your parameters.

This class would expose the properties that the base class would utilize
in some way.

You can then define your properties as read only in your base class.
For example, you would do something like this:

class Base
{
protected virtual EntityInfo GetEntityInfo()
{
return new EntityInfo();
}

Base()
{
// Get the entity info.
EntityInfo info = GetEntityInfo();

// Do some stuff with info here, assigning values that
// back read only properties, or store the instance itself.
}
}

class Derived : Base
{
protected override EntityInfo GetEntityInfo()
{
// Call the base, or create your own if you want.
EntityInfo info = base.GetEntityInfo();

// Set some other value.
info.SomeProperty = 10;
}
}

Here is the key. As long as you only add properties to EntityInfo, you
shouldn't have a problem with classes that already derive from Base. Just
make sure that EntityInfo sets the new properties to values that can be used
by the base class when the derived class does not set them.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"cody" <de********@gmx.de> wrote in message
news:e0**************@TK2MSFTNGP03.phx.gbl...
Stoitcho Goutsev (100) wrote:
cody,

On .NET2.0 you can declare properties where the get accessor is public,
but the set is internal for example. This might solve your problem. I
know that this is not quite what you asked fot thought.


Right, this was not what I was looking for :)
*I want* the properties somehow to be assignable but just once and not
later again. Maybe I have to live with it and put Exceptions in each
property forbidding reassign.
While this is might be not good style it will work as long as nobody has a
better idea or Microsoft finally starts to support optional parameters. I
mean they put so much stupid cr*p into C# 3.0, mutating it into a
functional script language, but the simplest things like optional or named
parameters does still not work, although most programming languages
support it (with good reason).

Jun 20 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.