While digging in my company codebase i found something that astounds me: pairs of functions that differ only in optional parameters, here's one example:
public static List<AvailableDay> Find(string mailboxCalendarId, string[] typeTrameCles, DateTime dateMin, bool hasPhNonUrgent, bool hasPhUrgence, bool hasPhUrgenceDuJour)
public static List<AvailableDay> Find(string mailboxCalendarId, string[] typeTrameCles, DateTime dateMin, bool hasPhNonUrgent, bool hasPhUrgence, bool hasPhUrgenceDuJour, int maxDaysResultCout = 1)
what I find very strange, is that the compiler is happy with them. What is the explanation for this? Am I missing something?
Optional parameters are defined at the end of the parameter list, after any required parameters. If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters.
We can make a parameter optional by assigning default values for that parameter, like: public static void Sum(int a,int b , int[] n=null)
Optional Parameters are parameters that can be specified, but are not required. This allows for functions that are more customizable, without requiring parameters that many users will not need.
In c#, we can also achieve the optional parameters by using method overloading functionality. Generally, the method overloading functionality will allow us to create multiple methods with the same name but with different parameters.
This is perfectly valid code. In your situation, however, the optional parameter is never used, because the compiler will always prefer the first overload when the method is invoked with six parameters.
From C# In Depth:
When faced with a choice between a method which requires the compiler to fill in optional parameter values and one which doesn't, if the methods are otherwise "tied" (i.e. normal argument conversion hasn't decided a winner), overload resolution will pick the one where the caller has specified all the arguments explicitly.
There may be situations when the compiler would pick the first overload over the second one because the more specific method is hidden. Here is a somewhat artificial example:
interface Foo {
void Bar(int a, int b = 1);
}
class FooImpl : Foo {
public void Bar(int a, int b) {
Console.WriteLine("bar/2");
}
public void Bar(int a) {
Console.WriteLine("bar/1");
}
}
If you do this
Foo f1 = new FooImpl();
f1.Bar(1); // Here, Bar(int a, int b = 1) is the only choice
bar/2
gets printed, but if you do this
FooImpl f2 = new FooImpl();
f2.Bar(1); // Here Bar(int a) of the implementation wins
bar/1
gets printed (demo).
The optional parameter, is just a syntax sugar in C#.
If you have the following method that uses optional parameter:
public void DeleteFiles(string extension = "*.*")
The real signature of this method is
public void DeleteFiles(string extension)
The compiler does the trick here, when you use this method like that:
obj.DeleteFiles();
When compiler was doing her job, he got call to DeleteFiles without parameters, and he try to find it, but he couldn't so he will try to find and overload that uses a optional parameter that can match, this time he found, the DeleteFile(string), and now he does the trick.
In fact the compiled code will be this:
var extension = "*.*";
obj.DeleteFiles(extension);
So if you try to do this code:
public class A
{
public void DeleteFiles(string extension = "*.*")
{
}
public void DeleteFiles(string extension2)
{
}
}
The compiler will give the following error message:
Error CS0111: Type 'A' already defines a member called 'DeleteFiles' with the same parameter types
Now we have this class
public class A
{
public void DeleteFiles(string folderPath)
{
}
public void DeleteFiles(string folderPath, string extension = "*.*")
{
}
}
The real code in this case is
public class A
{
public void DeleteFiles(string folderPath)
{
}
public void DeleteFiles(string folderPath, string extension)
{
}
}
Then you have this code:
aInstance.DeleteFiles("path")
The compiler will look if there is a DeleteFiles method that receive one parameter. He will find it.
So in this case, the optional parameter feature, will never be used, because there is a perfect method signature that makes compiler never try to find a other signature that used optional parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With