is there a way to implement below scenario of function as a single call, so that for caller it looks like singe call (If not i can declare them as 2 overloaded calls, but checking if language has some feature)
Add(int, dateTime)
Add(datetime, int)
so that caller can call Add(2, DateTime.Now) Or Add(DateTime.Now, 2).
My scenario is that arguments to pass will come in an array, and i want caller can just call Add(args[0], args[1])
I can't use parameter name here as any parameter can be of any type. basically i want to have equivalent of
DateTime + int
int + dateTime
I would recommend just picking the order of arguments that makes sense to you, and sticking with that. Having multiple overloads of the exact same argument list in different orders is non-conventional and potentially confusing to consumers of your API.
One thing that can be done when calling methods is using Named Arguments. If your consumers use named arguments, they can put them in whatever order they want.
For example:
public static DateTime Add(int daysToAdd, DateTime date)
{
return date.AddDays(daysToAdd);
}
private static void Main()
{
// Call the method passing the int first, then the DateTime
var newDate1 = Add(daysToAdd: 5, date: DateTime.Now);
// Call the method passing the DateTime first, then the int
var newDate2 = Add(date: DateTime.Now, daysToAdd: 5);
}
No, there is no specific language feature for that.
In such cases you could use params object[] to give 0 or more parameters to the method, but I highly doubt that will ever give a decent working piece of code with is not error-prone. It means you have to cast every parameter to the desired type when you want to use them as such.
If you the types are hard-coded on the calling side, it is better to keep 1 single method.
define one of them, for exemple:
Add(int offSet, DateTime dataTime)
then use it like this
Add(offSet:2,dataTime:DateTime.Now)
Add(dataTime:DateTime.Now,offSet:2)
you can as well create a new method:
Add(DateTime dateTime, int offSet){
Add(offSet,dateTime );
}
Related
I came across the accepted answer of this question about dealing with DateTime.Now in unit tests which contains the following code example:
private readonly Func<DateTime> _nowProvider;
public SomeClass(Func<DateTime> nowProvider)
{
_nowProvider = nowProvider;
}
public bool Foo()
{
return (_nowProvider().DayOfWeek == DayOfWeek.Sunday);
}
Instantiated as such:
var s = new SomeClass(() => DateTime.Now);
I've not much used Func<T> in C# so I thought I'd take a look at the Microsoft documentation for it which has the following remarks:
You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate. This means that the encapsulated method must have no parameters and must return a value.
Why would it be more beneficial in the example to pass a Func<DateTime>, instantiated as Class(() => DateTime.Now) to the constructor
Rather than to just simply pass in a DateTime parameter instantiated as Class(DateTime.Now) to the constructor?
According to the Microsoft documentation mentioned above LINQ lambda constructors also take Func<T> arguments and my experience with these proves they are extremely flexible but I can't understand why?
Rather than to just simply pass in a DateTime parameter instantiated as Class(DateTime.Now) to the constructor?
Because the value should be the current DateTime and not the one when the class has been instanciated.
When the code runs, the Func returns the Date of exactly when the code is executed.
If the DateTime would be stored in a field, it would be the time of creation, not now.
I have an example.
Let's say you create an instance of Class at 23:59:55 on Saturday.
10 Seconds later, the following snipped:
(passedDateTime.DayOfWeek == DayOfWeek.Sunday);
would return false.
With the provider, the datetime is actually on sunday - the time it is executed at.
Technical:
DateTime is a struct.
When passing DateTime to a method or constructor as a parameter, it is passed as a value, not a reference.
Thus the DateTime will not be up to date, but just a snapshot of the value.
You can confirm this yourself:
var dateTime = DateTime.Now;
System.Threading.Sleep(1000);
bool equals = dateTime == DateTime.Now; // false
This pattern allows the Date and Time to be provided either by DateTime.Now, during normal operation, or to be closely controlled during unit testing.
For example, a Unit Test that wants to test time based functionality could verify that the returned result is correct when a function is called twice with more than 5 minutes between each call (a common caching technique), without having to wait 5 minutes between calls.
It is also an example of the "Inversion of Control" pattern. Where a method of retrieving data is "injected" in to the class, usually via constructor. The class is then free to use whatever method was injected without being aware of its implementation.
I attach a small example on how this could look like in a unit test.
If you would not have the ability to provide a different "Now" the unit test will behave different depending on the time it runs.
[TestMethod]
public void TestFoo()
{
var obj = new SomeClass(() => DateTime.Now);
//Only true on sundays
Assert.IsTrue(obj.Foo());
//This is sunday
obj = new SomeClass(() => new DateTime(2017, 7, 30));
//This will be always true
Assert.IsTrue(obj.Foo());
//This is not sunday
obj = new SomeClass(() => new DateTime(2017, 7, 29));
//This will be always false
Assert.IsFalse(obj.Foo());
}
I have a repository class that I want to add two methods to:
public IEnumerable<OpenCall> OpenCalls()
{
return something;
}
public IEnumerable<OpenCall> OpenCalls(DateTime start, DateTime endd)
{
return something_slightly_different;
}
Inside each method I am going to call another method (AverageResolutions()) that returns a list of average resolutions. Obviously this method will also need to take 0 parameters or 2 parameters. The way I'm doing things at the moment I'm either going to end with two almost identical copies of OpenCalls(), or two almost identical copies of AverageResolutions(), altered slightly to allow for the DateTime parameters.
I think I'm doing this wrong - how can I just end up with one version of a method that will either take 0 or 2 parameters and then decide what to call further down the line if they are either null or not null?
You could change the method signature to use optional arguments:
public IEnumerable<OpenCall> OpenCalls(DateTime? start=null, DateTime? end=null)
{
if (start.HasValue && end.HasValue)
{
return something_slightly_different;
}
return something;
}
Note that you will need to make the DateTime-parameters nullable, because otherwise you wouldn't be able to set default values (which have to be compile-time constants).
For more information about nullable types, and the syntactic sugar (writing DateTime? instead of Nullable<DateTime> see the MSDN article on Nullable Types
For more information about optional parameters see the Optional Arguments section of the MSDN article about Named and Optional Arguments.
public IEnumerable<OpenCall> OpenCalls()
{
return OpenCalls(null, null);
}
public IEnumerable<OpenCall> OpenCalls(DateTime? start, DateTime? endd)
{
//if (!start.HasValue) ... etc.
return something_slightly_different;
}
If this solution is "clever" really depends on your other code. Having dozens of null checks isnĀ“t nice. If you only have to check once or twice, it may be a good solution.
Also, you could use optional parameters.
I am simplifying my code (I like to write the least amount of lines per function performed) and I often come across the lengthy process of data validation. So decided to write a Validate function, in pseudocode:
public static bool Validate(string input, out object output){
// try to parse data
try {
(TypeOf(object)) output = new (TypeOf(object));
output = (TypeOf(object)).Parse(input);
return true;
} catch {
return false;
}
}
So if I use in my code to validate several text boxes, it looks nice and very readable:
double var1;
Int32 var2;
byte var3;
if (!Validate(txtDouble.text, var1)) return "Error validating a Double";
if (!Validate(txtInt32.text, var2)) return "Error validating a Int32";
if (!Validate(txtByte.text, var3)) return "Error validating a byte";
// else all data is valid, continue
Process(var1, var2, var3)
I could create a static class Validate and overload for each type, but since I am planning on using on types that include the Parse method, it seems to me that there should be a way of implementing the above function... I just don't know what I am looking for. An interface keeps coming to my mind, but failing at implementing.
Thanks!
The framework providers already wrote your function for you, it's called TryParse. There is no generic nature to it, but it's called the exact same way you're calling Validate. Might as well use what's already there.
double var1;
if (!double.TryParse(input, out var1)) return "Invalid input";
The method is available for your double, int, float, char, DateTime, etc.
You're better off creating a static class with overloads (that call TryParse instead of Parse for the various types involved. The list is fairly short and your only other options will be convoluted.
Or you could just call the appropriate version of TryParse directly in your code. If you aren't inserting any additional validation (hence the need for your own validation class), then it won't be any more verbose than your pseudocode.
You could use something like this (it uses reflection):
private static void Test()
{
var r1 = TryParse("23", typeof(int));
var r2 = TryParse("true", typeof(bool));
}
private static bool TryParse(string valueToParse, Type type)
{
//there are more then one TryParse method and we need the one with 2 parameters
var method = type.GetMethods().Where(m => m.Name == "TryParse" && m.GetParameters().Count() == 2).Single();
var instance = Activator.CreateInstance(type); //create instance of the type
var result = method.Invoke(null, new object[] { valueToParse, instance });
return (bool)result;
}
but it's really fancy code (maybe there is a chance to write it a bit better;) ) and I would never use it.
As Anthony Pegram suggested you should create few overloads methods with TryParse - it's much cleaner and better solution.
This question already has answers here:
Should you declare methods using overloads or optional parameters in C# 4.0?
(13 answers)
Closed 9 years ago.
which one is better? at a glance optional parameter seems better (less code, less XML documentation, etc), but why do most MSDN library classes use overloading instead of optional parameters?
Is there any special thing you have to take note when you choose to use optional parameter (or overloading)?
One good use case for 'Optional parameters' in conjunction with 'Named Parameters' in C# 4.0 is that it presents us with an elegant alternative to method overloading where you overload method based on the number of parameters.
For example say you want a method foo to be be called/used like so, foo(), foo(1), foo(1,2), foo(1,2, "hello"). With method overloading you would implement the solution like this,
///Base foo method
public void DoFoo(int a, long b, string c)
{
//Do something
}
/// Foo with 2 params only
public void DoFoo(int a, long b)
{
/// ....
DoFoo(a, b, "Hello");
}
public void DoFoo(int a)
{
///....
DoFoo(a, 23, "Hello");
}
.....
With optional parameters in C# 4.0 you would implement the use case like the following,
public void DoFoo(int a = 10, long b = 23, string c = "Hello")
Then you could use the method like so - Note the use of named parameter -
DoFoo(c:"Hello There, John Doe")
This call takes parameter a value as 10 and parameter b as 23.
Another variant of this call - notice you don't need to set the parameter values in the order as they appear in the method signature, the named parameter makes the value explicit.
DoFoo(c:"hello again", a:100)
Another benefit of using named parameter is that it greatly enhances readability and thus code maintenance of optional parameter methods.
Note how one method pretty much makes redundant having to define 3 or more methods in method overloading. This I have found is a good use case for using optional parameter in conjunction with named parameters.
Optional Parameters provide issues when you expose them publicly as API. A rename of a parameter can lead to issues. Changing the default value leads to issues (See e.g. here for some info: Caveats of C# 4.0 optional parameters)
Also, optional params can only be used for compile-time constants. Compare this:
public static void Foo(IEnumerable<string> items = new List<string>()) {}
// Default parameter value for 'items' must be a compile-time constant
to this
public static void Foo() { Foo(new List<string>());}
public static void Foo(IEnumerable<string> items) {}
//all good
Update
Here's some additional reading material when a constructor with default parameters does not play nicely with Reflection.
I believe they serve different purposes. Optional parameters are for when you can use a default value for a parameter, and the underlying code will be the same:
public CreditScore CheckCredit(
bool useHistoricalData = false,
bool useStrongHeuristics = true) {
// ...
}
Method overloads are for when you have mutually-exclusive (subsets of) parameters. That normally means that you need to preprocess some parameters, or that you have different code altogether for the different "versions" of your method (note that even in this case, some parameters can be shared, that's why I mentioned "subsets" above):
public void SendSurvey(IList<Customer> customers, int surveyKey) {
// will loop and call the other one
}
public void SendSurvey(Customer customer, int surveyKey) {
...
}
(I wrote about this some time ago here)
This one almost goes without saying, but:
Not all languages support optional parameters. If you want your libraries to be friendly to those languages, you have to use overloads.
Granted, this isn't even an issue for most shops. But you can bet it's why Microsoft doesn't use optional parameters in the Base Class Library.
Neither is definitively "better" than the other. They both have their place in writing good code. Optional parameters should be used if the parameters can have a default value. Method overloading should be used when the difference in signature goes beyond not defining parameters that could have default values (such as that the behavior differs depending on which parameters are passed, and which are left to the default).
// this is a good candidate for optional parameters
public void DoSomething(int requiredThing, int nextThing = 12, int lastThing = 0)
// this is not, because it should be one or the other, but not both
public void DoSomething(Stream streamData = null, string stringData = null)
// these are good candidates for overloading
public void DoSomething(Stream data)
public void DoSomething(string data)
// these are no longer good candidates for overloading
public void DoSomething(int firstThing)
{
DoSomething(firstThing, 12);
}
public void DoSomething(int firstThing, int nextThing)
{
DoSomething(firstThing, nextThing, 0);
}
public void DoSomething(int firstThing, int nextThing, int lastThing)
{
...
}
Optional parameters has to be last. So you can not add an extra parameter to that method unless its also optional. Ex:
void MyMethod(int value, int otherValue = 0);
If you want to add a new parameter to this method without overloading it has to be optional. Like this
void MyMethod(int value, int otherValue = 0, int newParam = 0);
If it can't be optional, then you have to use overloading and remove the optional value for 'otherValue'. Like this:
void MyMethod(int value, int otherValue = 0);
void MyMethod(int value, int otherValue, int newParam);
I assume that you want to keep the ordering of the parameters the same.
So using optional parameters reduces the number of methods you need to have in your class, but is limited in that they need to be last.
Update
When calling methods with optional parameters, you can used named parameters like this:
void MyMethod(int value, int otherValue = 0, int newValue = 0);
MyMethod(10, newValue: 10); // Here I omitted the otherValue parameter that defaults to 0
So optional parameters gives the caller more possibilities.
One last thing. If you use method overloading with one implementation, like this:
void MyMethod(int value, int otherValue)
{
// Do the work
}
void MyMethod(int value)
{
MyMethod(value, 0); // Do the defaulting by method overloading
}
Then when calling 'MyMethod' like this:
MyMethod(100);
Will result in 2 method calls. But if you use optional parameters there is only one implementation of 'MyMethod' and hence, only one method call.
What about a 3rd option: pass an instance of a class with properties corresponding to various "optional parameters".
This provides the same benefit as named and optional parameters, but I feel that this is often much clearer. It gives you an opportunity to logically group parameters if necessary (i.e. with composition) and encapsulate some basic validation as well.
Also, if you expect clients that consume your methods to do any kind of metaprogramming (such as building linq expressions involving your methods), I think that keeping the method signature simple has its advantages.
A good place to use optional parameter is WCF since it does not support method overloading.
This is not really an answer to the original question, but rather a comment on #NileshGule's answer, but:
a) I don't have enough reputation points to comment
b) Multiple lines of code is quite hard to read in comments
Nilesh Gule wrote:
One benefit of using optional parameters is that you need not have to do a conditional check in your methods like if a string was null or empty if one of the input parameter was a string. As there would be a default value assigned to the optional parameter, the defensive coding will be reduced to a great extent.
This is actually incorrect, you still have to check for nulls:
void DoSomething(string value = "") // Unfortunately string.Empty is not a compile-time constant and cannot be used as default value
{
if(value == null)
throw new ArgumentNullException();
}
DoSomething(); // OK, will use default value of ""
DoSomething(null); // Will throw
If you supply a null string reference, it will not be replaced by the default value. So you still need to check the input parameters for nulls.
To address your first question,
why do most MSDN library classes use
overloading instead of optional
parameters?
It is for backward compatibility.
When you open a C# 2, 3.0 or 3.5 project in VS2010, it is automatically upgraded.
Just imagine the inconvenience it would create if each of the overloads used in the project had to be converted to match the corresponding optional parameter declaration.
Besides, as the saying goes, "why fix what is not broken?". It is not necessary to replace overloads that already work with new implementations.
One benefit of using optional parameters is that you need not have to do a conditional check in your methods like if a string was null or empty if one of the input parameter was a string. As there would be a default value assigned to the optional parameter, the defensive coding will be reduced to a great extent.
Named parameters give the flexibility of passing parameter values in any order.
Can you please tell me what is the exact use of out parameter?
Related Question:
What is the difference between ref and out? (C#)
The best example of a good use of an out parameter are in the TryParse methods.
int result =-1;
if (!Int32.TryParse(SomeString, out result){
// log bad input
}
return result;
Using TryParse instead of ParseInt removes the need to handle exceptions and makes the code much more elegant.
The out parameter essentially allows for more than one return values from a method.
The out method parameter keyword on a
method parameter causes a method to
refer to the same variable that was
passed into the method. Any changes
made to the parameter in the method
will be reflected in that variable
when control passes back to the
calling method.
Declaring an out method is useful when
you want a method to return multiple
values. A method that uses an out
parameter can still return a value. A
method can have more than one out
parameter.
To use an out parameter, the argument
must explicitly be passed to the
method as an out argument. The value
of an out argument will not be passed
to the out parameter.
A variable passed as an out argument
need not be initialized. However, the
out parameter must be assigned a value
before the method returns.
An Example:
using System;
public class MyClass
{
public static int TestOut(out char i)
{
i = 'b';
return -1;
}
public static void Main()
{
char i; // variable need not be initialized
Console.WriteLine(TestOut(out i));
Console.WriteLine(i);
}
}
http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
Out parameters are output only parameters meaning they can only passback a value from a function.We create a "out" parameter by preceding the parameter data type with the out modifier. When ever a "out" parameter is passed only an unassigned reference is passed to the function.
using System;
class ParameterTest
{
static void Mymethod(out int Param1)
{
Param1=100;
}
static void Main()
{
int Myvalue=5;
MyMethod(Myvalue);
Console.WriteLine(out Myvalue);
}
}
Output of the above program would be 100 since the value of the "out" parameter is passed back to the calling part. Note
The modifier "out" should precede the parameter being passed even in the calling part. "out" parameters cannot be used within the function before assigning a value to it. A value should be assigned to the "out" parameter before the method returns.
Besides allowing you to have multiple return values, another use is to reduce overhead when copying a large value type to a method. When you pass something to a method, a copy of the value of that something is made. If it's a reference type (string for example) then a copy of the reference (the value of a reference type) is made. However, when you copy a value type (a struct like int or double) a copy of the entire thing is made (the value of a value type is the thing itself). Now, a reference is 4 bytes (on 32-bit applications) and an int is 4 bytes, so the copying is not a problem. However, it's possible to have very large value types and while that's not recommended, it might be needed sometimes. And when you have a value type of say, 64 bytes, the cost of copying it to methods is prohibitive (especially when you use such a large struct for performance reasons in the first place). When you use out, no copy of the object is made, you simply refer to the same thing.
public struct BigStruct
{
public int A, B, C, D, E, F, G, H, J, J, K, L, M, N, O, P;
}
SomeMethod(instanceOfBigStruct); // A copy is made of this 64-byte struct.
SomeOtherMethod(out instanceOfBigStruct); // No copy is made
A second use directly in line with this is that, because you don't make a copy of the struct, but refer to the same thing in the method as you do outside of the method, any changes made to the object inside the method, are persisted outside the method. This is already the case in a reference type, but not in value types.
Some examples:
public void ReferenceExample(SomeReferenceType s)
{
s.SomeProperty = "a string"; // The change is persisted to outside of the method
}
public void ValueTypeExample(BigStruct b)
{
b.A = 5; // Has no effect on the original BigStruct that you passed into the method, because b is a copy!
}
public void ValueTypeExampleOut(out BigStruct b)
{
b = new BigStruct();
b.A = 5; // Works, because you refer to the same thing here
}
Now, you may have noticed that inside ValueTypeExampleOut I made a new instance of BigStruct. That is because, if you use out, you must assign the variable to something before you exit the method.
There is however, another keyword, ref which is identical except that you are not forced to assign it within the method. However, that also means you can't pass in an unassigned variable, which would make that nice Try.. pattern not compile when used with ref.
int a;
if(TrySomething(out a)) {}
That works because TrySomething is forced to assign something to a.
int a;
if(TrySomething(ref a)) {}
This won't work because a is unassigned (just declared) and ref requires that you only use it with an assigned variable.
This works because a is assigned:
int a = 0;
if(TrySomething(ref a)) {}
However, in both cases (ref and out) any changes made to a within the TrySomething method are persisted to a.
As I already said, changes made to a reference type are persisted outside the method in which you make them, because through the reference, you refer to the same thing.
However, this doesn't do anything:
public void Example(SomeReferenceType s)
{
s = null;
}
Here, you just set the copy of a reference to s to null, which only exists within the scope of the method. It has zero effect on whatever you passed into the method.
If you want to do this, for whatever reason, use this:
public void Example1(ref SomeReferenceType s)
{
s = null; // Sets whatever you passed into the method to null
}
I think this covers all use-cases of out and ref.
from http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
One way to think of out parameters is that they are like additional return values of a method. They are very convenient when a method returns more than one value, in this example firstName and lastName. Out parameters can be abused however. As a matter of good programming style if you find yourself writing a method with many out parameters then you should think about refactoring your code. One possible solution is to package all the return values into a single struct.
In contrast ref parameters are considered initially assigned by the callee. As such, the callee is not required to assign to the ref parameter before use. Ref parameters are passed both into and out of a method.
The typical use case is a method that needs to return more than one thing, so it can't just use the return value. Commonly, the return value is used for a success flag while the out parameter(s) sets values when the method is successful.
The classic example is:
public bool TryGet(
string key,
out string value
)
If it returns true, then value is set. Otherwise, it's not. This lets you write code such as:
string value;
if (!lookupDictionary.TryGet("some key", out value))
value = "default";
Note that this doesn't require you to call Contains before using an indexer, which makes it faster and cleaner. I should also add that, unlike the very similar ref modifier, the compiler won't complain if the out parameter was never initialized.
In simple words pass any variable to the function by reference so that any changes made to that variable in side that function will be persistent when function returns from execution.
Jon Skeet describes the different ways of passing parameters in great detail in this article. In short, an out parameter is a parameter that is passed uninitialized to a method. That method is then required to initialize the parameter before any possible return.
generally we cannot get the variables inside a function if we don't get by a return value.
but use keyword "out" we can change it value by a function.