C# Impossible to convert method group to bool? - c#

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());

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.

Code on Func and Action

http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/
The above code explains in simple terms about Action and Func.
Still I am not getting what it is for 100%. Or not able to make the code work for me.
public void SteamVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Steam, timeInMinutes);
}
public void FryVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Fry, timeInMinutes);
}
public void BakeVegetable(Vegetable vegetable, int timeInMinutes)
{
CookVegetable(vegetable, Bake, timeInMinutes);
}
public void CookVegetable(Vegetable vegetable,
Action<Vegetable, CookingTime> cookingAction,
int timeInMinutes)
{
Clean(vegetable);
cookingAction(vegetable, Minutes.Is(timeInMinutes));
Serve(vegetable);
}
Can someone help me to convert the code from vegetable to numbers and Steam --> Addition, Fry --> Multiplication, Bake --> subtraction when two operands are passed to it.
When I see the code working I can understand it better.
In the example you provided, Fry, Steam, and Bake are probably supposed to be methods.
Basically, Actions and Funcs let you pass a chunk of code into a method, then execute that chunk of code.
So, you could do
public void Foo(Action<int> actionToPerform, int someInt)
{
actionToPerform(someInt);
}
Then, you could use the Foo method with any "chunk of code" that takes an integer.
So,
public void Bar()
{
Action<int> writeToConsole = i => { Console.WriteLine(i); }
Action<int> writeToSomeLogger = i => { Logger.WriteLog(i); }
Foo(writeToConsole, 10);
Foo(writeToSomeLogger, 100);
}
I'm going to throw my example in.. I tried to make it simple, so hopefully this helps.
Take this for example:
class MathClass {
public int Add(int number1, int number2) {
return DoSomeMathOperation(number1, number2, theAddingIsActuallyDoneHere); // The method "theAddingIsActuallyDoneHere" below is what gets called.
}
private int theAddingIsActuallyDoneHere(int number1, int number2) {
return number1 + number2;
}
public int Multiply(int number1, int number2) {
return DoSomeMathOperation(number1, number2, theMultiplicationIsDoneHere); // The method "theMultiplicationIsDoneHere" is what gets called.
}
private int theMultiplicationIsDoneHere(int number1, int number2) {
return number1 * number2;
}
public int DoSomeMathOperation(int number1, int number2, Func<int, int, int> mathOperationFunc) {
return mathOperationFunc(number1, number2); // This is where you call the method passed in above.
}
}
The above code, can be used like this:
MathClass mathClass = new MathClass();
Console.WriteLine(mathClass.Add(5, 10)); // displays 15
Console.WriteLine(mathClass.Multiply(5, 5)); // displays 25
Imagine though, that you required a subtraction method. You can create one, via the DoSomeMathOperation function, which expects a Func<int, int, int>, which is a function that "takes 2 integer parameters and returns an integer". This would be implemented as follows:
Console.WriteLine(mathClass.DoSomeMathOperation(100, 50, (num1, num2) => num1 - num2)); // displays "50"
In the above code, you're passing the numbers 100 and 50 into the DoSomeMathOperation method, and those two parameters are being passed into the Func<int, int, int>. The result is then returned.
..hopefully that makes sense..
I might be wrong in understanding what you want, but I'll try to answer it. Note, that I omit many complex things in example, like I would use generics instead of plain int values, but this will just create redundant complexity in the example.
In example below I just define high-order function, which takes two int values, function, that transforms two values into string (i.e. encapsulate some behavior) and them embrace this result into enclosing and opening tags, one of which is passed in. Note, that I assume you are familiar with lambda notation in C#.
ApplyAndPrettyPrint(100, 3, "summ of 100 and 3 is equal to: ", (x,y) => (x*y).ToString("N0"));
ApplyAndPrettyPrint(100, 3, "100 to power 3 is: ", (x,y) => (Math.Pow(x,y)).ToString("N0"));
ApplyAndPrettyPrint(2, 33, "2 * root of 33 is: ", (x,y) => (x * Math.Sqrt(y)).ToString("N0"));
public void ApplyAndPrettyPrint( int firstNumber, int secondNumber, string startTag, Func<int, int, string> evaludationFunction)
{
string result = startTag;
result += evaludationFunction(firstNumber, secondNumber);
result += ";";
Console.WriteLine (result);
}
So that Func here is used like a box, with two integers as input and one string as output.
Second example shows how we can pass Action into method, that will be evaluated over some array of numbers. Again, I omit details of IEnumerable interfaces and generics.
int[] numbers = new []{ 1, 2, 4, 5, 6, 7 };
ApplyForEach(numbers, (x) => Console.WriteLine ("square of {0} is {1}", x, x*x));
public void ApplyForEach(int[] numbers, Action<int> someFunction)
{
foreach (var number in numbers)
{
someFunction(number);
}
}
The result will just print squares of integers with some descriptive chars. In other word Action is delegate with no outputs. You can think of them as box with some inputs, but with no outputs at all.
Hope that this will do the trick for your understanding. The bottom line is that the only difference between delegate types of Action and Func is the semantics of the last generic type: in Func it is the returning value, in Action returning value is void, so last generic type just goes to input parameter.
If you find this topic somewhat difficult, Jon Skeet describes delegates within Chapter 5 "Fast-tracked delegates" in his marvelous book "C# in Depth"

Pass multiple optional parameters to a C# function

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){}

Interesting "params of ref" feature, any workarounds?

I wonder if there's any way something like this would be possible for value types...
public static class ExtensionMethods {
public static void SetTo(this Boolean source, params Boolean[] bools) {
for (int i = 0; i < bools.Length; i++) {
bools[i] = source;
}
}
}
then this would be possible:
Boolean a = true, b, c = true, d = true, e;
b.SetTo(a, c, d, e);
Of course, this does not work because the bools are a value type so they are passed into the function as a value, not as a reference.
Other than wrapping the value types into reference types (by creating another class), is there any way to pass a variable into function by the reference (ref) while using params modifier?
This is not possible. To explain why, first read my essay on why it is that we optimize deallocation of local variables of value type by putting them on the stack:
https://web.archive.org/web/20100224071314/http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Now that you understand that, it should be clear why you cannot store a "ref bool" in an array. If you could, then you could have an array which survives longer than the stack variable being referenced. We have two choices: either allow this, and produce programs which crash and die horribly if you get it wrong -- this is the choice made by the designers of C. Or, disallow it, and have a system which is less flexible but more safe. We chose the latter.
But let's think about this a little deeper. If what you want is to pass around "thing which allows me to set a variable", we have that. That's just a delegate:
static void DoStuff<T>(this T thing, params Action<T>[] actions)
{
foreach(var action in actions) action(thing);
}
...
bool b = whatever;
b.DoStuff(x=>{q = x;}, x=>{r = x;} );
Make sense?
There isn't really a way. You could do something like this:
public static void Main(string[] args)
{
BooleanWrapper a = true, b = true, c = true, d = true, e = new BooleanWrapper();
b.SetTo(a, c, d, e);
}
public static void SetTo(this BooleanWrapper sourceWrapper, params BooleanWrapper[] wrappers)
{
foreach (var w in wrappers)
w.Value = sourceWrapper.Value;
}
public class BooleanWrapper
{
public BooleanWrapper() { }
public BooleanWrapper(Boolean value)
{
Value = value;
}
public Boolean Value { get; set; }
public static implicit operator BooleanWrapper(Boolean value)
{
return new BooleanWrapper(value);
}
}
But then again how is that any better than just doing this:
public static void Main(string[] args)
{
Boolean[] bools = new Boolean[5];
bools.SetTo(bools[1]); // Note I changed the order of arguments. I think this makes more sense.
}
public static void SetTo(this Boolean[] bools, Boolean value)
{
for(int i = 0; i < bools.Length; i++)
bools[i] = value;
}
After all, an array is a sequence of variables. If you need something that behaves like a sequence of variables, use an array.
Unfortunately the community of Java, and now .NET, developers decided that less flexibility in the name of "safety" is the preferred solution, and to achieve the same result with less lines of code you have to opt for extraordinary complexity (all those class structures, delegates, etc.).
In Delphi I could simply do something like this:
var
a: integer; f: double; n: integer;
sscanf(fmtstr, valuestr, [#a, #f, #n]);
//<-- "sscanf" is a function I wrote myself that takes an open array of pointers.
In C# You would have to do:
int a; double f; int n;
object [] o = new object[];
sscanf(fmtstr, valuestr, ref o);
a = o[0];
f = o[1];
n = o[2];
That's 5 lines of code to do what I could do in 1 line of Delphi code. I think there is a formula somewhere that the likelihood of bugs in code increases geometrically with the number of lines of code; so if you have 20 lines of code you're code is 4 times more likely to have bugs than if you have 10.
Of course, you can decrease your # lines of code by using the delegate with all those weird angle brackets and strange syntax, but I would think that's also a haven for bugs.
Here is some interesting solution:
public delegate RecursionRefFunc<T> RecursionRefFunc<T>(ref T arg);
public static RecursionRefFunc<T> Boo<T>(ref T input)
{
Console.WriteLine(input); // Work in here
return Boo;
}
public static void Main(string[] args)
{
int x1 = 1, x2 = 2, x3 = 3, x4 = 4, x5 = 5;
Boo(ref x1)(ref x2)(ref x3)(ref x4)(ref x5);
}
// Output: //
// 1
// 2
// 3
// 4
// 5
Delegate can declare in recursion.
Return a function outside and call again.
And you will be killed by the code reviewer.
Advertisement OW<: CWKSC/MyLib_Csharp
This would not be possible even if bools were reference types. While a class is a reference type, the variable in the Boolean[] is still a value, it's just that the value is a reference. Assigning the value of the reference just changes the value of that particular variable. The concept of an array of ref variables doesn't make sense (as arrays are, by their nature, a series of values).

Categories

Resources