Pass multiple optional parameters to a C# function - c#

Is there a way to set up a C# function to accept any number of parameters? For example, could you set up a function such that the following all work -
x = AddUp(2, 3)
x = AddUp(5, 7, 8, 2)
x = AddUp(43, 545, 23, 656, 23, 64, 234, 44)

Use a parameter array with the params modifier:
public static int AddUp(params int[] values)
{
int sum = 0;
foreach (int value in values)
{
sum += value;
}
return sum;
}
If you want to make sure there's at least one value (rather than a possibly empty array) then specify that separately:
public static int AddUp(int firstValue, params int[] values)
(Set sum to firstValue to start with in the implementation.)
Note that you should also check the array reference for nullity in the normal way. Within the method, the parameter is a perfectly ordinary array. The parameter array modifier only makes a difference when you call the method. Basically the compiler turns:
int x = AddUp(4, 5, 6);
into something like:
int[] tmp = new int[] { 4, 5, 6 };
int x = AddUp(tmp);
You can call it with a perfectly normal array though - so the latter syntax is valid in source code as well.

C# 4.0 also supports optional parameters, which could be useful in some other situations. See this article.

1.You can make overload functions.
SomeF(strin s){}
SomeF(string s, string s2){}
SomeF(string s1, string s2, string s3){}
More info: http://csharpindepth.com/Articles/General/Overloading.aspx
2.or you may create one function with params
SomeF( params string[] paramArray){}
SomeF("aa","bb", "cc", "dd", "ff"); // pass as many as you like
More info: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params
3.or you can use simple array
Main(string[] args){}

Related

C# specify only second optional argument and use the default value for first [duplicate]

Is there a way to set up a C# function to accept any number of parameters? For example, could you set up a function such that the following all work -
x = AddUp(2, 3)
x = AddUp(5, 7, 8, 2)
x = AddUp(43, 545, 23, 656, 23, 64, 234, 44)
Use a parameter array with the params modifier:
public static int AddUp(params int[] values)
{
int sum = 0;
foreach (int value in values)
{
sum += value;
}
return sum;
}
If you want to make sure there's at least one value (rather than a possibly empty array) then specify that separately:
public static int AddUp(int firstValue, params int[] values)
(Set sum to firstValue to start with in the implementation.)
Note that you should also check the array reference for nullity in the normal way. Within the method, the parameter is a perfectly ordinary array. The parameter array modifier only makes a difference when you call the method. Basically the compiler turns:
int x = AddUp(4, 5, 6);
into something like:
int[] tmp = new int[] { 4, 5, 6 };
int x = AddUp(tmp);
You can call it with a perfectly normal array though - so the latter syntax is valid in source code as well.
C# 4.0 also supports optional parameters, which could be useful in some other situations. See this article.
1.You can make overload functions.
SomeF(strin s){}
SomeF(string s, string s2){}
SomeF(string s1, string s2, string s3){}
More info: http://csharpindepth.com/Articles/General/Overloading.aspx
2.or you may create one function with params
SomeF( params string[] paramArray){}
SomeF("aa","bb", "cc", "dd", "ff"); // pass as many as you like
More info: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params
3.or you can use simple array
Main(string[] args){}

NSubstitute Returns method and arrays

so I want to test roll results of dice set, but i can't pass an array as arg in Returns method like this:
[TestCase(new[]{2, 2, 3, 1, 5}, Category.Yahtzee, 0)]
public void AddPoints_ForGivenCategory_PointsAreStored(
int[] rollResults, Category selectedCategory, int expectedScore)
{
_randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE).Returns(rollResults); //<-rollResults not allowed
IDice[] dice = MakeNewDiceSet();
_game.NewGame("A");
_game.RollDice(dice);
_game.AddPoints(selectedCategory);
var result = _game.GameStatus().First()[selectedCategory];
Assert.AreEqual(expectedScore, result);
}
any tips or workarounds for this problem? Or am I forced to do this:
[TestCase(2, 2, 3, 1, 5, Category.Yahtzee, 0)]
public void AddPoints_ForGivenCategory_PointsAreStored(
int die1, int die2, int die3, int die4, int die5, Category selectedCategory, int expectedScore)
{
_randomizer.GetRandomNumber(MIN_VALUE, MAX_VALUE).Returns(die1, die2, die3, die4, die5);
IDice[] dice = MakeNewDiceSet();
/ ...
}
Using NSubstitute v3.1.0.0
NSubstitute does not have Returns<T>(T[] values) (or similar). Instead it has Returns<T>(T initialValue, params T[] otherValues) to indicate we should always specify at least one value to return. The aim at the time was to avoid the potentially confusing case of stubbing a call with "no values" in the case of an empty collection. (Is it a no-op? Or does it clear the call?)
There are a few ways to get the behaviour you want. One way is to split the values into "first" and "rest":
random.GetRandomNumber(1, 10)
.Returns(rollResults.First(), rollResults.Skip(1).ToArray());
Another approach is to use a Queue and stub GetRandomNumber() to consume this:
var rolls = new Queue<int>(rollResults);
random.GetRandomNumber(1, 10).Returns(_ => rolls.Dequeue());
If this is something you need frequently it might be worth creating your own Returns extension that explicitly defines how the empty case should be handled.

C# Impossible to convert method group to bool?

public void nbOccurences(int[] base1, int n, int m)
{
foreach (int i in base1)
{
if (n == 32)
{
m++;
}
}
}
static void Main(string[] args)
{
int chiffrebase = 32;
int occurence = 0;
int[] test123 = new int[] { 12, 32, 33, 64, 75, 46, 42, 32 };
Program n1 = new Program();
n1.nbOccurences(test123, chiffrebase, occurence);
Console.WriteLine(nbOccurences);
}
I keep getting a "Impossible to convert from method group to bool" message, what's causing the problem? I'm trying to use the method I made in the main program.
Console.WriteLine(nbOccurences);
nbOccurrences is a mehtod (returning void, by the way).
so compiler complains saying "I need something to print on writeline, maybe you want me to print a bool, but I can't convert a method to a bool"
Also, your nbOccurrences seems to do nothing useful: it iterates on an Array, checks some condition and eventually increase the parameter value. But calling code will not be aware of the m value, which remains internal to your function. You should change your method declaration returning an int (or using an out int m parameter, which would not be my choice)
This is my best guess as to what you're actually aiming at:
public int nbOccurrences(int[] base1, int n)
{
int count = 0;
foreach (int i in base1)
{
if (n == 32)
{
count++;
}
}
return count;
}
static void Main(string[] args)
{
int chiffrebase = 32;
int[] test123 = new int[] { 12, 32, 33, 64, 75, 46, 42, 32 };
int occurrences = nbOccurrences(test123, chiffrebase, occurrence);
Console.WriteLine(occurrences);
}
Your method nbOccurrences didn't return anything before, so how can it be used to do anything? There is a way to use an out or ref parameter to get values back from method via parameters, but you should NOT do that until you are much more expert.
The WriteLine method is looking for a string or something that can be converted to a string or have ToString run on it. Instead, you gave it the name of a method (not the result of a method call, the method itself). How would it know what to do with that?
One invokes a method using parentheses, so pay careful attention to note that nbOccurrences is NOT the same thing as nbOccurrences().
Finally, I'm gambling that you do NOT need new Program. It works, but probably isn't what you want. Instead, just call the method which is in the current, same program as the one you're running, Program.
Finally, while this may be too soon in your C# journey, note that this same task can be performed this way (add using System.Linq;):
static void Main(string[] args)
{
int chiffrebase = 32;
int[] test123 = new int[] { 12, 32, 33, 64, 75, 46, 42, 32 };
int occurrences = test123.Count(i => i == chiffrebase);
Console.WriteLine(occrurences);
}
P.S. Occurrences is spelled with two Rs. Not one.
The Console.WriteLine function has many overloads, one of which is expecting a bool as a parameter.
When you call a function like this
Console.WriteLine(1);
the compiler determines which version of the function you want to call (in my above example it should be the int version.
In your sample code, you simply need to add some brackets so it looks like this if you wanted to call the function.
It's worth noting that your nbOccurrences function does not actually return a value (it's return type is void) so this will likely still fail.
Console.WriteLine(nbOccurences());

C#: Create and pass variable straight in the method call

I would like to know how to declare new variable straight in the parameter brackets and pass it on like this:
MethodA(new int[]) //but how to fill the array if declared here? E.g. how to declare and set string?
MethodA(int[] Array)
...
and what if need to declare an object (class with constructor parameter)? Still possible within parameter list?
MethodA(new int[] { 1, 2, 3 }); // Gives an int array pre-populated with 1,2,3
or
MethodA(new int[3]); // Gives an int array with 3 positions
or
MethodA(new int[] {}); // Gives an empty int array
You can do the same with strings, objects, etc:
MethodB(new string[] { "Do", "Ray", "Me" });
MethodC(new object[] { object1, object2, object3 });
If you want to pass a string through to a method, this is how you do it:
MethodD("Some string");
or
string myString = "My string";
MethodD(myString);
UPDATE:
If you want to pass a class through to a method, you can do one of the following:
MethodE(new MyClass("Constructor Parameter"));
or
MyClass myClass = new MyClass("Constructor Parameter");
MethodE(myClass );
You can try this:
MethodA(new int[] { 1, 2, 3, 4, 5 });
This way you achieve the functionality you asked for.
There seems to be no way to declare a variable inside parameter list; however you can use some usual tricks like calling a method which creates and initializes the variable:
int[] prepareArray(int n)
{
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
return arr;
}
...
MethodA(prepareArray(5));
...
With the strings, why not just use string literal:
MethodB("string value");
?
Either new int[0] or new int {} will work for you. You can also pass in values, as in new int {1, 2, 3}. Works for lists and other collections too.
In your case you would want to declare MethodB(string[] strArray) and call it as MethodB(new string[] {"str1", "str2", "str3" })
P.S.
I would recomment that you start with a C# tutorial, for example this one.
Do you simply mean:
MethodA("StringValue"); ??
As a side note: if you add the params keyword, you can simply specify multiple parameters and they will be wrapped into an array automatically:
void PrintNumbers(params int[] nums)
{
foreach (int num in nums) Console.WriteLine(num.ToString());
}
Which can then be called as:
PrintNumbers(1, 2, 3, 4); // Automatically creates an array.
PrintNumbers(new int[] { 1, 2, 3, 4 });
PrintNumbers(new int[4]);

Explanation of Func

I was wondering if someone could explain what Func<int, string> is and how it is used with some clear examples.
Are you familiar with delegates in general? I have a page about delegates and events which may help if not, although it's more geared towards explaining the differences between the two.
Func<T, TResult> is just a generic delegate - work out what it means in any particular situation by replacing the type parameters (T and TResult) with the corresponding type arguments (int and string) in the declaration. I've also renamed it to avoid confusion:
string ExpandedFunc(int x)
In other words, Func<int, string> is a delegate which represents a function taking an int argument and returning a string.
Func<T, TResult> is often used in LINQ, both for projections and predicates (in the latter case, TResult is always bool). For example, you could use a Func<int, string> to project a sequence of integers into a sequence of strings. Lambda expressions are usually used in LINQ to create the relevant delegates:
Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);
foreach (string s in strings)
{
Console.WriteLine(s);
}
Result:
Value=3
Value=7
Value=10
A Func<int, string> eats ints and returns strings. So, what eats ints and returns strings? How about this ...
public string IntAsString( int i )
{
return i.ToString();
}
There, I just made up a function that eats ints and returns strings. How would I use it?
var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;
foreach( int i in lst )
{
str += IntAsString(i);
}
// str will be "12345"
Not very sexy, I know, but that's the simple idea that a lot of tricks are based upon. Now, let's use a Func instead.
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
Instead of calling IntAsString on each member, I created a reference to it called fnc (these references to methods are called delegates) and used that instead. (Remember fnc eats ints and returns strings).
This example is not very sexy, but a ton of the clever stuff you will see is based on the simple idea of functions, delegates and extension methods.
One of the best primers on this stuff I've seen is here. He's got a lot more real examples. :)
It is a delegate that takes one int as a parameter and returns a value of type string.
Here is an example of its usage:
using System;
class Program
{
static void Main()
{
Func<Int32, String> func = bar;
// now I have a delegate which
// I can invoke or pass to other
// methods.
func(1);
}
static String bar(Int32 value)
{
return value.ToString();
}
}
Func<int, string> accepts an int value parameter and returns a string value. Here's an example where an additional supporting method is unnecessary.
Func<int, string> GetDogMessage = dogAge =>
{
if (dogAge < 3) return "You have a puppy!";
if (dogAge < 7) return "Strong adult dog!";
return "Age is catching up with the dog!";
};
string youngDogMessage = GetDogMessage(2);
NOTE: The last object type in Func (i.e. "string" in this example) is the functions return type (i.e. not limited to primitives, but any object). Therefore, Func<int, bool, float> accepts int and bool value parameters, and returns a float value.
Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
{
if(intValue > 100 && boolValue) return 100;
return 1;
};
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);
HTH

Categories

Resources