Carl said:
Marcus said:
You don't have to duplicate the methods. Place all the code in the
method call with the most parameters, and have the other methods call
that one, like this.
public int MyFunc(string s,int optional)
{
// Code goes here ...
}
public int MyFunc(string s)
{
MyFunc(s,10); //Assuming default value for optional is 10
}
.... and while this isn't as elegant as optional parameters, in terms of the
amount of source text you have to write, at runtime it's pretty much a wash,
and perhaps actually better. With optional parameters, the compiler has to
instantiate the optional parameters at every call site, while the forwarding
function instantiates the optional parameters only once. [..]
I made a proposal in this newsgroup a few days ago "[Proposal] Named and
Optional Parameters with Default Values", which would solve the problem
very elagant and with no change of the clr.
Although C# does not support this at this time with short syntax (but I
hope it will do so at a later time), it is possible to use the
underlaying implementation as a good solution is some cases where it
might fit.
The basic idea is to use a second class or struct as a parameter object
which already has the default values and you assign only the
parameter-properties you actually need and pass the object into your method:
-------- my posting --------
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);