How can you use optional parameters in C#? - c#

Note: This question was asked at a time when C# did not yet support optional parameters (i.e. before C# 4).
We're building a web API that's programmatically generated from a C# class. The class has method GetFooBar(int a, int b) and the API has a method GetFooBar taking query params like &a=foo &b=bar.
The classes needs to support optional parameters, which isn't supported in C# the language. What's the best approach?

Surprised no one mentioned C# 4.0 optional parameters that work like this:
public void SomeMethod(int a, int b = 0)
{
//some code
}
Edit: I know that at the time the question was asked, C# 4.0 didn't exist. But this question still ranks #1 in Google for "C# optional arguments" so I thought - this answer worth being here. Sorry.

Another option is to use the params keyword
public void DoSomething(params object[] theObjects)
{
foreach(object o in theObjects)
{
// Something with the Objects…
}
}
Called like...
DoSomething(this, that, theOther);

In C#, I would normally use multiple forms of the method:
void GetFooBar(int a) { int defaultBValue; GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
// whatever here
}
UPDATE: This mentioned above WAS the way that I did default values with C# 2.0. The projects I'm working on now are using C# 4.0 which now directly supports optional parameters. Here is an example I just used in my own code:
public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender,
EDIVanInfo receiver,
EDIDocumentInfo info,
EDIDocumentType type
= new EDIDocumentType(EDIDocTypes.X12_814),
bool Production = false)
{
// My code is here
}

From this site:
https://www.tek-tips.com/viewthread.cfm?qid=1500861
C# does allow the use of the [Optional] attribute (from VB, though not functional in C#). So you can have a method like this:
using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
...
}
In our API wrapper, we detect optional parameters (ParameterInfo p.IsOptional) and set a default value. The goal is to mark parameters as optional without resorting to kludges like having "optional" in the parameter name.

You could use method overloading...
GetFooBar()
GetFooBar(int a)
GetFooBar(int a, int b)
It depends on the method signatures, the example I gave is missing the "int b" only method because it would have the same signature as the "int a" method.
You could use Nullable types...
GetFooBar(int? a, int? b)
You could then check, using a.HasValue, to see if a parameter has been set.
Another option would be to use a 'params' parameter.
GetFooBar(params object[] args)
If you wanted to go with named parameters would would need to create a type to handle them, although I think there is already something like this for web apps.

You can use optional parameters in C# 4.0 without any worries.
If we have a method like:
int MyMetod(int param1, int param2, int param3=10, int param4=20){....}
when you call the method, you can skip parameters like this:
int variab = MyMethod(param3:50; param1:10);
C# 4.0 implements a feature called "named parameters", you can actually pass parameters by their names, and of course you can pass parameters in whatever order you want :)

An easy way which allows you to omit any parameters in any position, is taking advantage of nullable types as follows:
public void PrintValues(int? a = null, int? b = null, float? c = null, string s = "")
{
if(a.HasValue)
Console.Write(a);
else
Console.Write("-");
if(b.HasValue)
Console.Write(b);
else
Console.Write("-");
if(c.HasValue)
Console.Write(c);
else
Console.Write("-");
if(string.IsNullOrEmpty(s)) // Different check for strings
Console.Write(s);
else
Console.Write("-");
}
Strings are already nullable types so they don't need the ?.
Once you have this method, the following calls are all valid:
PrintValues (1, 2, 2.2f);
PrintValues (1, c: 1.2f);
PrintValues(b:100);
PrintValues (c: 1.2f, s: "hello");
PrintValues();
When you define a method that way you have the freedom to set just the parameters you want by naming them. See the following link for more information on named and optional parameters:
Named and Optional Arguments (C# Programming Guide) # MSDN

Hello Optional World
If you want the runtime to supply a default parameter value, you have to use reflection to make the call. Not as nice as the other suggestions for this question, but compatible with VB.NET.
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace ConsoleApplication1
{
public class Class1
{
public static void SayHelloTo([Optional, DefaultParameterValue("world")] string whom)
{
Console.WriteLine("Hello " + whom);
}
[STAThread]
public static void Main(string[] args)
{
MethodInfo mi = typeof(Class1).GetMethod("sayHelloTo");
mi.Invoke(null, new Object[] { Missing.Value });
}
}
}

I agree with stephenbayer. But since it is a webservice, it is easier for end-user to use just one form of the webmethod, than using multiple versions of the same method. I think in this situation Nullable Types are perfect for optional parameters.
public void Foo(int a, int b, int? c)
{
if(c.HasValue)
{
// do something with a,b and c
}
else
{
// do something with a and b only
}
}

optional parameters are for methods. if you need optional arguments for a class and you are:
using c# 4.0: use optional arguments in the constructor of the class, a solution i prefer, since it's closer to what is done with methods, so easier to remember. here's an example:
class myClass
{
public myClass(int myInt = 1, string myString =
"wow, this is cool: i can have a default string")
{
// do something here if needed
}
}
using c# versions previous to c#4.0: you should use constructor chaining (using the :this keyword), where simpler constructors lead to a "master constructor".
example:
class myClass
{
public myClass()
{
// this is the default constructor
}
public myClass(int myInt)
: this(myInt, "whatever")
{
// do something here if needed
}
public myClass(string myString)
: this(0, myString)
{
// do something here if needed
}
public myClass(int myInt, string myString)
{
// do something here if needed - this is the master constructor
}
}

The typical way this is handled in C# as stephen mentioned is to overload the method. By creating multiple versions of the method with different parameters you effectively create optional parameters. In the forms with fewer parameters you would typically call the form of the method with all of the parameters setting your default values in the call to that method.

Using overloads or using C# 4.0 or above
private void GetVal(string sName, int sRoll)
{
if (sRoll > 0)
{
// do some work
}
}
private void GetVal(string sName)
{
GetVal("testing", 0);
}

You can overload your method. One method contains one parameter GetFooBar(int a) and the other contain both parameters, GetFooBar(int a, int b)

You can use default.
public void OptionalParameters(int requerid, int optinal = default){}

For a larger number of optional parameters, a single parameter of Dictionary<string,Object> could be used with the ContainsKey method. I like this approach because it allows me to pass a List<T> or a T individually without having to create a whole other method (nice if parameters are to be used as filters, for example).
Example (new Dictionary<string,Object>() would be passed if no optional parameters are desired):
public bool Method(string ParamA, Dictionary<string,Object> AddlParams) {
if(ParamA == "Alpha" && (AddlParams.ContainsKey("foo") || AddlParams.ContainsKey("bar"))) {
return true;
} else {
return false;
}
}

Instead of default parameters, why not just construct a dictionary class from the querystring passed .. an implementation that is almost identical to the way asp.net forms work with querystrings.
i.e. Request.QueryString["a"]
This will decouple the leaf class from the factory / boilerplate code.
You also might want to check out Web Services with ASP.NET. Web services are a web api generated automatically via attributes on C# classes.

A little late to the party, but I was looking for the answer to this question and ultimately figured out yet another way to do this. Declare the data types for the optional args of your web method to be type XmlNode. If the optional arg is omitted this will be set to null, and if it's present you can get is string value by calling arg.Value, i.e.,
[WebMethod]
public string Foo(string arg1, XmlNode optarg2)
{
string arg2 = "";
if (optarg2 != null)
{
arg2 = optarg2.Value;
}
... etc
}
What's also decent about this approach is the .NET generated home page for the ws still shows the argument list (though you do lose the handy text entry boxes for testing).

I have a web service to write that takes 7 parameters. Each is an optional query attribute to a sql statement wrapped by this web service. So two workarounds to non-optional params come to mind... both pretty poor:
method1(param1, param2, param 3, param 4, param 5, param 6, param7)
method1(param1, param2, param3, param 4, param5, param 6)
method 1(param1, param2, param3, param4, param5, param7)... start to see the picture. This way lies madness. Way too many combinations.
Now for a simpler way that looks awkward but should work:
method1(param1, bool useParam1, param2, bool useParam2, etc...)
That's one method call, values for all parameters are required, and it will handle each case inside it. It's also clear how to use it from the interface.
It's a hack, but it will work.

I had to do this in a VB.Net 2.0 Web Service. I ended up specifying the parameters as strings, then converting them to whatever I needed. An optional parameter was specified with an empty string. Not the cleanest solution, but it worked. Just be careful that you catch all the exceptions that can occur.

For just in case if someone wants to pass a callback (or delegate) as an optional parameter, can do it this way.
Optional Callback parameter:
public static bool IsOnlyOneElement(this IList lst, Action callbackOnTrue = (Action)((null)), Action callbackOnFalse = (Action)((null)))
{
var isOnlyOne = lst.Count == 1;
if (isOnlyOne && callbackOnTrue != null) callbackOnTrue();
if (!isOnlyOne && callbackOnFalse != null) callbackOnFalse();
return isOnlyOne;
}

optional parameters are nothing but default parameters!
i suggest you give both of them default parameters.
GetFooBar(int a=0, int b=0) if you don't have any overloaded method, will result in a=0, b=0 if you don't pass any values,if you pass 1 value, will result in, passed value for a, 0 and if you pass 2 values 1st will be assigned to a and second to b.
hope that answers your question.

In the case when default values aren't available the way to add an optional parameter is to use .NET OptionalAttribute class - https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.optionalattribute?view=netframework-4.8
Example of the code is below:
namespace OptionalParameterWithOptionalAttribute
{
class Program
{
static void Main(string[] args)
{
//Calling the helper method Hello only with required parameters
Hello("Vardenis", "Pavardenis");
//Calling the helper method Hello with required and optional parameters
Hello("Vardenis", "Pavardenis", "Palanga");
}
public static void Hello(string firstName, string secondName,
[System.Runtime.InteropServices.OptionalAttribute] string fromCity)
{
string result = firstName + " " + secondName;
if (fromCity != null)
{
result += " from " + fromCity;
}
Console.WriteLine("Hello " + result);
}
}
}

You can try this too
Type 1
public void YourMethod(int a=0, int b = 0)
{
//some code
}
Type 2
public void YourMethod(int? a, int? b)
{
//some code
}

Related

Invoke Function with async method delegate in C# [duplicate]

I have several methods all with the same parameter types and return values but different names and blocks. I want to pass the name of the method to run to another method that will invoke the passed method.
public int Method1(string)
{
// Do something
return myInt;
}
public int Method2(string)
{
// Do something different
return myInt;
}
public bool RunTheMethod([Method Name passed in here] myMethodName)
{
// Do stuff
int i = myMethodName("My String");
// Do more stuff
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
This code does not work but this is what I am trying to do. What I don't understand is how to write the RunTheMethod code since I need to define the parameter.
You can use the Func delegate in .NET 3.5 as the parameter in your RunTheMethod method. The Func delegate allows you to specify a method that takes a number of parameters of a specific type and returns a single argument of a specific type. Here is an example that should work:
public class Class1
{
public int Method1(string input)
{
//... do something
return 0;
}
public int Method2(string input)
{
//... do something different
return 1;
}
public bool RunTheMethod(Func<string, int> myMethodName)
{
//... do stuff
int i = myMethodName("My String");
//... do more stuff
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
}
You need to use a delegate. In this case all your methods take a string parameter and return an int - this is most simply represented by the Func<string, int> delegate1. So your code can become correct with as simple a change as this:
public bool RunTheMethod(Func<string, int> myMethodName)
{
// ... do stuff
int i = myMethodName("My String");
// ... do more stuff
return true;
}
Delegates have a lot more power than this, admittedly. For example, with C# you can create a delegate from a lambda expression, so you could invoke your method this way:
RunTheMethod(x => x.Length);
That will create an anonymous function like this:
// The <> in the name make it "unspeakable" - you can't refer to this method directly
// in your own code.
private static int <>_HiddenMethod_<>(string x)
{
return x.Length;
}
and then pass that delegate to the RunTheMethod method.
You can use delegates for event subscriptions, asynchronous execution, callbacks - all kinds of things. It's well worth reading up on them, particularly if you want to use LINQ. I have an article which is mostly about the differences between delegates and events, but you may find it useful anyway.
1 This is just based on the generic Func<T, TResult> delegate type in the framework; you could easily declare your own:
public delegate int MyDelegateType(string value)
and then make the parameter be of type MyDelegateType instead.
From OP's example:
public static int Method1(string mystring)
{
return 1;
}
public static int Method2(string mystring)
{
return 2;
}
You can try Action Delegate! And then call your method using
public bool RunTheMethod(Action myMethodName)
{
myMethodName(); // note: the return value got discarded
return true;
}
RunTheMethod(() => Method1("MyString1"));
Or
public static object InvokeMethod(Delegate method, params object[] args)
{
return method.DynamicInvoke(args);
}
Then simply call method
Console.WriteLine(InvokeMethod(new Func<string,int>(Method1), "MyString1"));
Console.WriteLine(InvokeMethod(new Func<string, int>(Method2), "MyString2"));
In order to provide a clear and complete answer, I'm going to start from the very beginning before showing three possible solutions.
A brief introduction
All .NET languages (such as C#, F#, and Visual Basic) run on top of the Common Language Runtime (CLR), which is a VM that runs code in the Common Intermediate Language (CIL), which is way higher level than machine code. It follows that methods aren't Assembly subroutines, nor are they values, unlike functional languages and JavaScript; rather, they're symbols that CLR recognizes. Not being values, they cannot be passed as a parameter. That's why there's a special tool in .NET. That is, delegates.
What's a delegate?
A delegate represents a handle to a method (the term handle is to be preferred over pointer as the latter would be an implementation detail). Since a method is not a value, there has to be a special class in .NET, namely Delegate, which wraps up any method. What makes it special is that, like very few classes, it needs to be implemented by the CLR itself and couldn't be simply written as a class in a .NET language.
Three different solutions, the same underlying concept
The type–unsafe way
Using the Delegate special class directly.
Example:
static void MyMethod()
{
Console.WriteLine("I was called by the Delegate special class!");
}
static void CallAnyMethod(Delegate yourMethod)
{
yourMethod.DynamicInvoke(new object[] { /*Array of arguments to pass*/ });
}
static void Main()
{
CallAnyMethod(MyMethod);
}
The drawback here is your code being type–unsafe, allowing arguments to be passed dynamically, with no constraints.
The custom way
Besides the Delegate special class, the concept of delegates spreads to custom delegates, which are declarations of methods preceded by the delegate keyword. They are type–checked the same way as “normal” method invocations, making for type-safe code.
Example:
delegate void PrintDelegate(string prompt);
static void PrintSomewhere(PrintDelegate print, string prompt)
{
print(prompt);
}
static void PrintOnConsole(string prompt)
{
Console.WriteLine(prompt);
}
static void PrintOnScreen(string prompt)
{
MessageBox.Show(prompt);
}
static void Main()
{
PrintSomewhere(PrintOnConsole, "Press a key to get a message");
Console.Read();
PrintSomewhere(PrintOnScreen, "Hello world");
}
The standard library's way
Alternatively, you can stick with a delegate that's part of the .NET Standard:
Action wraps up a parameterless void method;
Action<T1> wraps up a void method with one parameter of type T1;
Action<T1, T2> wraps up a void method with two parameters of types T1 and T2, respectively,
and so forth;
Func<TR> wraps up a parameterless function with TR return type;
Func<T1, TR> wraps up a function with TR return type and with one parameter of type T1;
Func<T1, T2, TR> wraps up a function with TR return type and with two parameters of types T1 and T2, respectively;
and so forth.
However, bear in mind that by using predefined delegates like these, parameter names won't be self-describing, nor is the name of the delegate type meaningful as to what instances are supposed to do. Therefore, refrain from using them in contexts where their purpose is not absolutely self-evident.
The latter solution is the one most people posted. I'm also mentioning it in my answer for the sake of completeness.
The solution involves Delegates, which are used to store methods to call. Define a method taking a delegate as an argument,
public static T Runner<T>(Func<T> funcToRun)
{
// Do stuff before running function as normal
return funcToRun();
}
Then pass the delegate on the call site:
var returnValue = Runner(() => GetUser(99));
You should use a Func<string, int> delegate, that represents a function taking a string argument and returning an int value:
public bool RunTheMethod(Func<string, int> myMethod)
{
// Do stuff
myMethod.Invoke("My String");
// Do stuff
return true;
}
Then invoke it this way:
public bool Test()
{
return RunTheMethod(Method1);
}
While the accepted answer is absolutely correct, I would like to provide an additional method.
I ended up here after doing my own searching for a solution to a similar question.
I am building a plugin driven framework, and as part of it I wanted people to be able to add menu items to the applications menu to a generic list without exposing an actual Menu object because the framework may deploy on other platforms that don't have Menu UI objects. Adding general info about the menu is easy enough, but allowing the plugin developer enough liberty to create the callback for when the menu is clicked was proving to be a pain. Until it dawned on me that I was trying to re-invent the wheel and normal menus call and trigger the callback from events!
So the solution, as simple as it sounds once you realize it, eluded me until now.
Just create separate classes for each of your current methods, inherited from a base if you must, and just add an event handler to each.
Here is an example Which can help you better to understand how to pass a function as a parameter.
Suppose you have Parent page and you want to open a child popup window. In the parent page there is a textbox that should be filled basing on child popup textbox.
Here you need to create a delegate.
Parent.cs
// declaration of delegates
public delegate void FillName(String FirstName);
Now create a function which will fill your textbox and function should map delegates
//parameters
public void Getname(String ThisName)
{
txtname.Text=ThisName;
}
Now on button click you need to open a Child popup window.
private void button1_Click(object sender, RoutedEventArgs e)
{
ChildPopUp p = new ChildPopUp (Getname) //pass function name in its constructor
p.Show();
}
IN ChildPopUp constructor you need to create parameter of 'delegate type' of parent //page
ChildPopUp.cs
public Parent.FillName obj;
public PopUp(Parent.FillName objTMP)//parameter as deligate type
{
obj = objTMP;
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
obj(txtFirstName.Text);
// Getname() function will call automatically here
this.DialogResult = true;
}
If you want to pass Method as parameter, use:
using System;
public void Method1()
{
CallingMethod(CalledMethod);
}
public void CallingMethod(Action method)
{
method(); // This will call the method that has been passed as parameter
}
public void CalledMethod()
{
Console.WriteLine("This method is called by passing it as a parameter");
}
If the method passed needs to take one argument and return a value, Func is the best way to go. Here is an example.
public int Method1(string)
{
// Do something
return 6;
}
public int Method2(string)
{
// Do something different
return 5;
}
public bool RunTheMethod(Func<string, int> myMethodName)
{
// Do stuff
int i = myMethodName("My String");
Console.WriteLine(i); // This is just in place of the "Do more stuff"
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
Read the docs here
However, if your method that is passed as a parameter does not return anything, you can also use Action. It supports up to 16 paramaters for the passed method. Here is an example.
public int MethodToBeCalled(string name, int age)
{
Console.WriteLine(name + "'s age is" + age);
}
public bool RunTheMethod(Action<string, int> myMethodName)
{
// Do stuff
myMethodName("bob", 32); // Expected output: "bob's age is 32"
return true;
}
public bool Test()
{
return RunTheMethod(MethodToBeCalled);
}
Read the documentation here
Here is an example without a parameter:
http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string
with params:
http://www.daniweb.com/forums/thread98148.html#
you basically pass in an array of objects along with name of method. you then use both with the Invoke method.
params Object[] parameters
class PersonDB
{
string[] list = { "John", "Sam", "Dave" };
public void Process(ProcessPersonDelegate f)
{
foreach(string s in list) f(s);
}
}
The second class is Client, which will use the storage class. It has a Main method that creates an instance of PersonDB, and it calls that object’s Process method with a method that is defined in the Client class.
class Client
{
static void Main()
{
PersonDB p = new PersonDB();
p.Process(PrintName);
}
static void PrintName(string name)
{
System.Console.WriteLine(name);
}
}
I don't know who might need this, but in case you're unsure how to send a lambda with a delegate, when the function using the delegate doesn't need to insert any params in there you just need the return value.
SO you can also do this:
public int DoStuff(string stuff)
{
Console.WriteLine(stuff);
}
public static bool MethodWithDelegate(Func<int> delegate)
{
///do stuff
int i = delegate();
return i!=0;
}
public static void Main(String[] args)
{
var answer = MethodWithDelegate(()=> DoStuff("On This random string that the MethodWithDelegate doesn't know about."));
}

How can set optional parameter in method [duplicate]

Note: This question was asked at a time when C# did not yet support optional parameters (i.e. before C# 4).
We're building a web API that's programmatically generated from a C# class. The class has method GetFooBar(int a, int b) and the API has a method GetFooBar taking query params like &a=foo &b=bar.
The classes needs to support optional parameters, which isn't supported in C# the language. What's the best approach?
Surprised no one mentioned C# 4.0 optional parameters that work like this:
public void SomeMethod(int a, int b = 0)
{
//some code
}
Edit: I know that at the time the question was asked, C# 4.0 didn't exist. But this question still ranks #1 in Google for "C# optional arguments" so I thought - this answer worth being here. Sorry.
Another option is to use the params keyword
public void DoSomething(params object[] theObjects)
{
foreach(object o in theObjects)
{
// Something with the Objects…
}
}
Called like...
DoSomething(this, that, theOther);
In C#, I would normally use multiple forms of the method:
void GetFooBar(int a) { int defaultBValue; GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
// whatever here
}
UPDATE: This mentioned above WAS the way that I did default values with C# 2.0. The projects I'm working on now are using C# 4.0 which now directly supports optional parameters. Here is an example I just used in my own code:
public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender,
EDIVanInfo receiver,
EDIDocumentInfo info,
EDIDocumentType type
= new EDIDocumentType(EDIDocTypes.X12_814),
bool Production = false)
{
// My code is here
}
From this site:
https://www.tek-tips.com/viewthread.cfm?qid=1500861
C# does allow the use of the [Optional] attribute (from VB, though not functional in C#). So you can have a method like this:
using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
...
}
In our API wrapper, we detect optional parameters (ParameterInfo p.IsOptional) and set a default value. The goal is to mark parameters as optional without resorting to kludges like having "optional" in the parameter name.
You could use method overloading...
GetFooBar()
GetFooBar(int a)
GetFooBar(int a, int b)
It depends on the method signatures, the example I gave is missing the "int b" only method because it would have the same signature as the "int a" method.
You could use Nullable types...
GetFooBar(int? a, int? b)
You could then check, using a.HasValue, to see if a parameter has been set.
Another option would be to use a 'params' parameter.
GetFooBar(params object[] args)
If you wanted to go with named parameters would would need to create a type to handle them, although I think there is already something like this for web apps.
You can use optional parameters in C# 4.0 without any worries.
If we have a method like:
int MyMetod(int param1, int param2, int param3=10, int param4=20){....}
when you call the method, you can skip parameters like this:
int variab = MyMethod(param3:50; param1:10);
C# 4.0 implements a feature called "named parameters", you can actually pass parameters by their names, and of course you can pass parameters in whatever order you want :)
An easy way which allows you to omit any parameters in any position, is taking advantage of nullable types as follows:
public void PrintValues(int? a = null, int? b = null, float? c = null, string s = "")
{
if(a.HasValue)
Console.Write(a);
else
Console.Write("-");
if(b.HasValue)
Console.Write(b);
else
Console.Write("-");
if(c.HasValue)
Console.Write(c);
else
Console.Write("-");
if(string.IsNullOrEmpty(s)) // Different check for strings
Console.Write(s);
else
Console.Write("-");
}
Strings are already nullable types so they don't need the ?.
Once you have this method, the following calls are all valid:
PrintValues (1, 2, 2.2f);
PrintValues (1, c: 1.2f);
PrintValues(b:100);
PrintValues (c: 1.2f, s: "hello");
PrintValues();
When you define a method that way you have the freedom to set just the parameters you want by naming them. See the following link for more information on named and optional parameters:
Named and Optional Arguments (C# Programming Guide) # MSDN
Hello Optional World
If you want the runtime to supply a default parameter value, you have to use reflection to make the call. Not as nice as the other suggestions for this question, but compatible with VB.NET.
using System;
using System.Runtime.InteropServices;
using System.Reflection;
namespace ConsoleApplication1
{
public class Class1
{
public static void SayHelloTo([Optional, DefaultParameterValue("world")] string whom)
{
Console.WriteLine("Hello " + whom);
}
[STAThread]
public static void Main(string[] args)
{
MethodInfo mi = typeof(Class1).GetMethod("sayHelloTo");
mi.Invoke(null, new Object[] { Missing.Value });
}
}
}
I agree with stephenbayer. But since it is a webservice, it is easier for end-user to use just one form of the webmethod, than using multiple versions of the same method. I think in this situation Nullable Types are perfect for optional parameters.
public void Foo(int a, int b, int? c)
{
if(c.HasValue)
{
// do something with a,b and c
}
else
{
// do something with a and b only
}
}
optional parameters are for methods. if you need optional arguments for a class and you are:
using c# 4.0: use optional arguments in the constructor of the class, a solution i prefer, since it's closer to what is done with methods, so easier to remember. here's an example:
class myClass
{
public myClass(int myInt = 1, string myString =
"wow, this is cool: i can have a default string")
{
// do something here if needed
}
}
using c# versions previous to c#4.0: you should use constructor chaining (using the :this keyword), where simpler constructors lead to a "master constructor".
example:
class myClass
{
public myClass()
{
// this is the default constructor
}
public myClass(int myInt)
: this(myInt, "whatever")
{
// do something here if needed
}
public myClass(string myString)
: this(0, myString)
{
// do something here if needed
}
public myClass(int myInt, string myString)
{
// do something here if needed - this is the master constructor
}
}
The typical way this is handled in C# as stephen mentioned is to overload the method. By creating multiple versions of the method with different parameters you effectively create optional parameters. In the forms with fewer parameters you would typically call the form of the method with all of the parameters setting your default values in the call to that method.
Using overloads or using C# 4.0 or above
private void GetVal(string sName, int sRoll)
{
if (sRoll > 0)
{
// do some work
}
}
private void GetVal(string sName)
{
GetVal("testing", 0);
}
You can overload your method. One method contains one parameter GetFooBar(int a) and the other contain both parameters, GetFooBar(int a, int b)
You can use default.
public void OptionalParameters(int requerid, int optinal = default){}
For a larger number of optional parameters, a single parameter of Dictionary<string,Object> could be used with the ContainsKey method. I like this approach because it allows me to pass a List<T> or a T individually without having to create a whole other method (nice if parameters are to be used as filters, for example).
Example (new Dictionary<string,Object>() would be passed if no optional parameters are desired):
public bool Method(string ParamA, Dictionary<string,Object> AddlParams) {
if(ParamA == "Alpha" && (AddlParams.ContainsKey("foo") || AddlParams.ContainsKey("bar"))) {
return true;
} else {
return false;
}
}
Instead of default parameters, why not just construct a dictionary class from the querystring passed .. an implementation that is almost identical to the way asp.net forms work with querystrings.
i.e. Request.QueryString["a"]
This will decouple the leaf class from the factory / boilerplate code.
You also might want to check out Web Services with ASP.NET. Web services are a web api generated automatically via attributes on C# classes.
A little late to the party, but I was looking for the answer to this question and ultimately figured out yet another way to do this. Declare the data types for the optional args of your web method to be type XmlNode. If the optional arg is omitted this will be set to null, and if it's present you can get is string value by calling arg.Value, i.e.,
[WebMethod]
public string Foo(string arg1, XmlNode optarg2)
{
string arg2 = "";
if (optarg2 != null)
{
arg2 = optarg2.Value;
}
... etc
}
What's also decent about this approach is the .NET generated home page for the ws still shows the argument list (though you do lose the handy text entry boxes for testing).
I have a web service to write that takes 7 parameters. Each is an optional query attribute to a sql statement wrapped by this web service. So two workarounds to non-optional params come to mind... both pretty poor:
method1(param1, param2, param 3, param 4, param 5, param 6, param7)
method1(param1, param2, param3, param 4, param5, param 6)
method 1(param1, param2, param3, param4, param5, param7)... start to see the picture. This way lies madness. Way too many combinations.
Now for a simpler way that looks awkward but should work:
method1(param1, bool useParam1, param2, bool useParam2, etc...)
That's one method call, values for all parameters are required, and it will handle each case inside it. It's also clear how to use it from the interface.
It's a hack, but it will work.
I had to do this in a VB.Net 2.0 Web Service. I ended up specifying the parameters as strings, then converting them to whatever I needed. An optional parameter was specified with an empty string. Not the cleanest solution, but it worked. Just be careful that you catch all the exceptions that can occur.
For just in case if someone wants to pass a callback (or delegate) as an optional parameter, can do it this way.
Optional Callback parameter:
public static bool IsOnlyOneElement(this IList lst, Action callbackOnTrue = (Action)((null)), Action callbackOnFalse = (Action)((null)))
{
var isOnlyOne = lst.Count == 1;
if (isOnlyOne && callbackOnTrue != null) callbackOnTrue();
if (!isOnlyOne && callbackOnFalse != null) callbackOnFalse();
return isOnlyOne;
}
optional parameters are nothing but default parameters!
i suggest you give both of them default parameters.
GetFooBar(int a=0, int b=0) if you don't have any overloaded method, will result in a=0, b=0 if you don't pass any values,if you pass 1 value, will result in, passed value for a, 0 and if you pass 2 values 1st will be assigned to a and second to b.
hope that answers your question.
In the case when default values aren't available the way to add an optional parameter is to use .NET OptionalAttribute class - https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.optionalattribute?view=netframework-4.8
Example of the code is below:
namespace OptionalParameterWithOptionalAttribute
{
class Program
{
static void Main(string[] args)
{
//Calling the helper method Hello only with required parameters
Hello("Vardenis", "Pavardenis");
//Calling the helper method Hello with required and optional parameters
Hello("Vardenis", "Pavardenis", "Palanga");
}
public static void Hello(string firstName, string secondName,
[System.Runtime.InteropServices.OptionalAttribute] string fromCity)
{
string result = firstName + " " + secondName;
if (fromCity != null)
{
result += " from " + fromCity;
}
Console.WriteLine("Hello " + result);
}
}
}
You can try this too
Type 1
public void YourMethod(int a=0, int b = 0)
{
//some code
}
Type 2
public void YourMethod(int? a, int? b)
{
//some code
}

Change value inside an (void) extension method

So I have this mock extension method which change a value to another value:
public static void ChangeValue(this int value, int valueToChange)
{
value = valueToChange;
}
When I try using it:
int asd = 8;
asd.ChangeValue(10);
Debug.Log(asd);
It returns 8 instead of 10.
While the value did change inside the ChangeValue method, it didn't change the value of "asd". What do I need to add to the method, to make it update "asd"?
You can't do that without using either a return value, or a ref parameter. The latter doesn't work alongside this (extension methods), so your best bet is a return value (rather than void).
The old answer is not valid anymore since newer C# versions support this ref. For further details refer to this answer.
Old Answer:
int is a struct so it's a value-type. this means that they are passed by value not by reference. Classes are reference-types and they act differently they are passed by reference.
Your option is to create static method like this:
public static void ChangeValue(ref int value, int valueToChange)
{
value = valueToChange;
}
and use it:
int a = 10;
ChangeValue(ref a, 15);
Old question, but on newer versions of C# it looks like you can now do this for value types by using the this and ref keywords together. This will set value to be the same as valueToChange, even outside of this extension method.
public static void ChangeValue(this ref int value, int valueToChange)
{
value = valueToChange;
}
I believe this change was made to the compiler on version 15.1, which I think corresponds to C# 7 (or one of its sub versions). I did not immediately find a formal announcement of this feature.
According to this answer: https://stackoverflow.com/a/1259307/1945651, there is not a way to do this in C#. Primitive types like int are immutable, and cannot be modified without an out or ref modifier, but the syntax won't allow out or ref here.
I think your best case is to have the extension method return the modified value instead of trying to modify the original.
Apparently this is possible in VB.NET and if you absolutely needed it, you could define your extension method in a VB.NET assembly, but it is probably not a very good practice in the first place.
I know it's too late, but just for the record, I recently really wanted to do this, I mean...
someVariable.ChangeValue(10);
...apparently looks way neat than the following (which is also perfectly fine)
ChangeValue(ref someVariable, 10);
And I managed to achieve something similar by doing:
public class MyClass
{
public int ID { get; set; }
public int Name { get; set; }
}
public static void UpdateStuff(this MyClass target, int id, string name)
{
target.ID = id;
target.Name = name;
}
static void Main(string[] args)
{
var someObj = new MyClass();
someObj.UpdateStuff(301, "RandomUser002");
}
Note that if the argument passed is of reference type, it needs to be instantiated first (but not inside the extension method). Otherwise, Leri's solution should work.
Because int is value type, so it copied by value when you pass it inside a function.
To see the changes outside of the function rewrite it like:
public static int ChangeValue(this int value, int valueToChange)
{
//DO SOMETHING ;
return _value_; //RETURN COMPUTED VALUE
}
It would be possible to do using ref keyowrd, but it can not be applied on parameter with this, so in your case, just return resulting value.

Parameter Action<T1, T2, T3> in which T3 can be optional

I have the following code:
public static MyMethod()
{
...Do something
ProtectedMethod(param1, param2);
...Do something
}
protected static void ProtectedMethod(IEnumerable<string> param1, string param2, int param3 = 1)
{
... Do something
}
Take notice of the optional param3 parameter.
Now for quite a few reasons I need to extract the code of the MyMethod method into its own class but I cannot extract ProtectedMethod with it because of all the classes that are inheriting from this one and I need to keep the changes small and isolated. So I figured I could have an Action<> delegate in the new class with the same signature as ProtectedMethod.
The problem is that if I declare the delegate like this:
protected readonly Action<IEnumerable<string>, string, int> m_ProtectedMethod;
The extracted code does not like it because it says the method is only being invoked with two parameters.
And if I declare the delegate like so:
protected readonly Action<IEnumerable<string>, string> m_ProtectedMethod;
When I send it as a parameter to the new class it does not like it either because the method is defined as having three parameters not two.
So far the only way I have thought of to solve this is to create an overloaded version of ProtectedMethod to eliminate the optional parameter.
Is this the only option or is there another way of doing it since now the preferred choice is to have optional parameters instead of overloaded methods?
Optional parameters are an attribute of a method or delegate parameter. When you call a signature (method or delegate) that has a known optional parameter at compile-time, the compiler will insert the optional parameter value at the callsite.
The runtime is not aware of optional parameters, so you can't make a delegate that inserts an optional parameter when it's called.
Instead, you need to declare a custom delegate type with an optional parameter:
public delegate void MyDelegate(IEnumerable<string> param1, string param2, int param3 = 1);
When calling this delegate, you will be able to omit the third parameter, regardless of the declaration of the method(s) it contains.
It would depend on how m_ProtectedMethod would be consumed, but I found a compromise in my own situation, where I use one overload more than the other.
Simply define a simpler (having less generic parameters) Action<> variable, which calls the more complex supplied Action variable method. This can be accomplished either in (i) local scope on use; or (ii) object scope upon assignment of Action property or object construction.
Because there is no such thing as variable/property overloading, you need two different names, for the resulting two related Action variables.
EG i: Local Scope (probably not the most suitable for your scenario)
public MyMethod(Action<IEnumerable<string>, string, int> m_ProtectedMethod2)
{
Action<IEnumerable<string>, string> m_ProtectedMethod = (p1,p2) => {
m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter
}
...Do something
m_ProtectedMethod(param1, param2);
...Do something
...If something
m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly
...Do something
}
EG ii: Object Scope
private Action<IEnumerable<string>, string, int> m_ProtectedMethod2 = null;
private Action<IEnumerable<string>, string> m_ProtectedMethod = null;
protected Action<IEnumerable<string>, string, int> ProtectedMethod
{
get { return m_ProtectedMethod2; }
set {
m_ProtectedMethod2 = value;
m_ProtectedMethod = (p1,p2) => {
m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter
}
}
}
public MyMethod()
{
...Do something
m_ProtectedMethod(param1, param2);
...Do something
...If something
m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly
...Do something
}
Note in both cases I designed the default setting value to be the more awkwardly named variable, having the 2 suffix, such that upon consumption the simpler overload has the more basic variable name.
Hoping to help others with what I find as being a more elegant implementation of overloading mixed with the (delegate-oriented) strategy pattern.
public class OverloadExample {
private Action<int, bool> _implementation;
public OverloadExample() {
_implementation = defaultImplementation;
}
public OverloadExample(Action<int, bool> implementation) {
_implementation = implementation;
}
protected void defaultImplementation(int aInt, bool aBool) {
//
}
public void Implementation(int someInt, bool someBool = true) {
_implementation(someInt, someBool);
}
}
Usage:
new OverloadExample().Implementation(9001);
new OverloadExample().Implementation(9001, false);

How to dispatch C# generic method call into specialized method calls

I have the following C# class:
public class MyType<T>
{
public void TryParse(string p_value)
{
T value ;
Parser.TryParse(p_value, out value);
// Do something with value
}
}
The point is to call the right Parser.TryParse method, depending on the generic type T.
This uses the following static class:
static public class Parser
{
static public void TryParse(string p_intput, out object p_output)
{
// Do something and return the right value
}
static public void TryParse(string p_intput, out double p_output)
{
// Do something and return the right value
}
static public void TryParse(string p_intput, out int p_output)
{
// Do something and return the right value
}
}
I expected this to work: In the worst case, the "object" TryParse would be called. Instead, I have two compilation errors:
CS1502: The best overloaded method match for 'Parser.TryParse(string, out object)' has some invalid arguments
CS1503: Argument 2: cannot convert from 'out T' to 'out object'
Question 1: I don't understand why this doesn't work: I can be naive, but aren't all C# objects supposed to derive from "object" ? Why T cannot be converted to object?
Question 2: How can I dispatch a method with generic type T into the right non-generic methods (i.e. MyType<T>.TryParse calling the right Parser.TryParse according to the right type of T) ?
Note
The question was edited to reflect the original question intent (as written in the title: How to dispatch C# generic method call into specialized method calls)
Actually, ref and out parameters do not allow type variation. So, to pass a variable to a method expecting an out object parameter, that variable must be declared as object.
From the specification (§10.6.1.2 and §10.6.1.3)
When a formal parameter is a reference parameter, the corresponding argument in a method invocation must consist of the keyword ref followed by a variable-reference (§5.3.3) of the same type as the formal parameter.
When a formal parameter is an output parameter, the corresponding argument in a method invocation must consist of the keyword out followed by a variable-reference (§5.3.3) of the same type as the formal parameter.
See: Why do ref and out parameters not allow type variation? for some insight into why.
Bonus question: How can I dispatch a method with generic type T into the right non-generic methods (i.e. MyType<T>.TryParse calling the right Parser.TryParse according to the right type of T)?
I'm going to turn it back around on you. Why are you doing this? If you are invoking MyType<T>.TryParse as, say, MyType<int>.TryParse, why not call Int32.TryParse directly? What is this extra layer buying you?
I know this is somewhat low-tech, but I have had the same problem, where I solved it by making a Dictionary<Type, Parser> containing the individual parsers. I will be interested in what answers this questions bring.
Regards,
Morten
Current solution
The current solution I use at work is based on dynamic dispatch, that is, the keyword dynamic as defined on C# 4.0.
The code is something like (from memory) :
public class Parser
{
static public void TryParse<T>(string p_input, out T p_output)
{
// Because m_p is dynamic, the function to be called will
// be resolved at runtime, after T is known...
m_p.DoTryParse(p_input, out p_output) ;
}
// The dynamic keyword means every function called through
// m_p will be resolved at runtime, at the moment of the call
private dynamic m_p = new Parser() ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private void DoTryParse(string p_input, out double p_output)
{ /* Do something and return the right value */ }
private void DoTryParse(string p_input, out int p_output)
{ /* Do something and return the right value */ }
// etc.
private void DoTryParse<T>(string p_input, out T p_output)
{
// fallback method... There are no dedicated method for T,
// so p_output becomes the default value for T
p_output = default(T) ;
}
}
The elegant part is that it can't fail (the fallback function will be called, if none with a better signature match is found), and that it follows a simple pattern (overload the function).
Of course, the real-life, production code is somewhat different, and more complicated because, with but one public static method, I want to :
parse both reference objects (classes) and value objects (structs)
parse enums
parse nullable types
I want to offer the user the possibility to derive from Parser to offer its own overloads in addition to the default ones
But I guess the use of dynamic in the current solution is, in the end, the same thing as doing reflection as done in the original answer below. Only the "notation" changes.
Conclusion, I now have the following method :
public class Parser
{
static public void TryParse<T>(string p_input, out T p_output)
{
// etc.
}
}
which is able to parse anything, including in situations where T is not known at compile time (because the code is generic).
Original answer
Jason's answer was right about the first question (about the compiler errors). Still, I had no solution to my problem (dispatching from a generic method to non-generic methods according to the runtime generic type T).
I tried LukeH's answer, but it didn't work: The generic method is always called, no matter what (even when removing the out qualifier of the second parameter).
Morten's answer is the most sane one that should works, but it doesn't make use of reflection.
So, to solve my own problem, I used reflection. This needs the rewriting of the generic TryParse method:
public class MyType<T>
{
public void TryParse(string p_value)
{
T value = default(T);
// search for the method using reflection
System.Reflection.MethodInfo methodInfo = typeof(Parser).GetMethod
(
"TryParse",
new System.Type[] { typeof(string), typeof(T).MakeByRefType() }
);
if (methodInfo != null)
{
// the method does exist, so we can now call it
var parameters = new object[] { p_value, value };
methodInfo.Invoke(null, parameters);
value = (T)parameters[1];
}
else
{
// The method does not exist. Handle that case
}
}
}
I have the source code available if needed.
This problem intrigued me, so I did some research and found a nice thing by Paul Madox. This seems to do the trick.
public static T SafeParseAndAssign<T>(string val) where T: new()
{
try
{
T ValOut = new T();
MethodInfo MI = ValOut.GetType().
GetMethod("Parse", new Type[] { val.GetType() });
return (T)MI.Invoke(ValOut, new object[] { val });
}
catch
{
// swallow exception
}
return default(T);
}

Categories