Code on Func and Action - c#

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"

Related

Call a method with an unknown signature

I'm using C# 4.6.2, though could upgrade to 4.7.2 if it's possible there.
In many places in our code we have a loop with wait statements to check for a specific value when a function is called, wait and retry if it's not what we wanted until a maximum number of retries.
I'd like to abstract this out, but the only implementation I can think of requires you pass in a method with a variable number of arguments of variable types, which after much searching of Google appeared to not be possible about 5 years ago. There has been many improvements to C# since then, so
is it still not possible?
If it is now possible how do I do it?
If it isn't possible can you think of any other way I can achieve my goal?
The sort of thing I'm looking for is:
public bool GenericLoopWait(int maxWaitSeconds, int waitMsPerIteration,??? DoSomething,object expectedResult,...)
int maxRetries = maxWaitSeconds*1000/waitMsPerIteration;
SomeType result=null;
for(int i=0; i<maxRetries; i++){
result = DoSomething(...);
if(result==expectedResult) break;
Thread.Sleep(waitMsPerIteration);
}
return result==expectedResult
}
And then both of these would work:
GenericLoopWait(5,500,Browser.Webdriver.FindElements(selector).Any(),true);
GenericLoopWait(5,500,Api.GetSpecificObject(api,objectName),"expectedOutcome");
You could use generics and Func and wrap the actual calls parameters when you call through to the method.
public bool GenericLoopWait<T>(int maxWaitSeconds, int waitMsPerIteration, Func<T> DoSomething, T expectedResult = default(T))
{
int maxRetries = maxWaitSeconds * 1000 / waitMsPerIteration;
T result = default(T);
for (int i = 0; i < maxRetries; i++)
{
result = DoSomething();
if (expectedResult.Equals(result)) break;
Thread.Sleep(waitMsPerIteration);
}
return expectedResult.Equals(result);
}
Calling code:
GenericLoopWait(5, 500, () => Browser.Webdriver.FindElements(selector).Any(), true);
GenericLoopWait(5, 500, () => Api.GetSpecificObject(api,objectName), "expectedOutcome")
Working dotnetfiddle
The general pattern is to create a "Wrapper" method that accepts an Action or a Func as a parameter. Your wrapper can do it's own logic, and Invoke the parameter at the correct time.
As a simple generic example:
public void MethodWrapper(Action action)
{
Console.WriteLine("begin");
action.Invoke();
Console.WriteLine("end");
}
You could then do this:
void Main()
{
var a = 1;
var b = 2;
MethodWrapper(() => DoSomething(a));
MethodWrapper(() => DoSomethingElse(a,b));
}
public void DoSomething(int a)
{
Debug.WriteLine($"a={a}");
}
public void DoSomethingElse(int a, int b)
{
Debug.WriteLine($"a={a}, b={b}");
}
To generate this output:
begin
a=1
end
begin
a=1, b=2
end
For your specific case, your wrapper could take additional parameters specifying things like number of retries, time between calls, or acceptance criteria.

Is it better to write 2 nearly identical functions, or to determine the logic based on the input variables

For simplicity, lets assume I have to write 2 functions :
int f1(int number, int var1) {
return number/var1;
}
and
int f2(int number, int var2) {
return number-var2;
}
Could I combine the two like this:
int f3(int number, int var1, int var2) {
return number/var1 - var2;
and call the
function f3(num, 1, var)
to achieve f2's functionality and like this:
function f3(num, var, 0)
to achieve f1's functionality.
Lets assume the code is slightly longer and duplicating the function is something I prefer not to do, but the change in functionality is as simple as I wrote above.
EDIT: slightly, as in about 10 lines of code.
Thanks
I would continue to make f1 and f2 the public interface to your functionality and make f3 a private implementation detail:
public int f1(int number, int var1) {
return f3(num, var, 0);
}
public int f2(int number, int var2) {
return f3(num, 1, var) ;
}
private int f3(int number, int var1, int var2) {
return number/var1 - var2;
}
This maximizes reuse whilst not littering calling code with what seems, fundamentally, an implementation detail (that the implementations are currently practically identical).
My two cents: If the functions do different things - which they appear to do based on your examples - they should be separate functions. And, you should give them names that help indicate the function being performed.
It depends on the context.
You can also try this:
int f3(int number, int var1 = 1, int var2 = 0) =>
number/var1 - var2;
and call it:
f3(number, var1: 10);
f3(number, var2: 10);
f3(number, 10, 10);

Delegate instances vs passing function directly

I am curious as to what is the point of creating instances of delegates. I understand that they are function pointers but what is the purpose of the using delegate instances?
public delegate bool IsEven(int x);
class Program
{
static void Main(string[] args)
{
int[] nums = new int[] { 1, 3, 4, 5, 6,7, 8, 9 };
// creating an instance of delegate and making it point to 'CheckEven' function
IsEven isEven = new IsEven(CheckEven);
// using delegate for parameter to get sum of evens
int tot1 = Sums(nums, isEven);
// passing in the function directly as parameter and not delegate instance
int tot2 = Sums(nums, CheckEven);
// using lambda expressions
int tot3 = Sums(nums, x=> x%2==0);
ReadKey();
}
public static int Sums(int[] nums, IsEven isEvenOdd)
{
int sum = 0;
foreach(int x in nums)
{
if (isEvenOdd(x))
sum += x;
}
return sum;
}
public static bool CheckEven(int x)
{
if (x % 2 == 0)
return true;
else
return false;
}
}
At first thought opting to always use lambdas seems like the best idea if the functionality of the function you are going to pass does not have complex implementation, otherwise why wouldn't I just pass my function directly into the parameters? Also with Lambdas it is much easier to change it to compute the sum of odds as oppose to creating an entire new method as I would have to with delegates.
You already used delegates even if you passed the method directly, the Sums method could not receive the method name if it's not set its expectation by the delegate definition.
Consider changing the delegate name to public delegate bool EvenOddStatus(int x);
you can send either your CheckEven method or this method:
public static bool CheckOdd(int x)
{
if (x % 2 != 0) // here changed
return true;
else return false;
}
(of course you can use lambda here, but not in more complicated scenarios)
Now your Sums method can sum up either odd or even numbers based on the calling code (either pass CheckEven or CheckOdd).
Delegates are pointers to methods. you define how the code want the method to receive and return, and the calling code can pass a pre-defined implementation later, either a method or delegate.
What if your Main is another method that doesn't know what to sum, odds or evens? it will have a delegate from a calling code up the stack.

How to write a function that takes an integer as a parameter and calculates and returns the squared value

Ahoy! I have just started methods but I am a tad confused when it comes to methods with math. First post so be nice :) I'm aware I out in NumberToSquare way too many times!
Write a program that asks the user to enter a number. In your program write a function called SquareValue that takes an integer parameter and calculates the square of integer parameter and returns this squared value. Your program should take this returned square value and display it. An example of the output is:
Please enter a number to square: 8
/ 8 squared is: 64
What I have so far is not so comprehensible. I thought along a few different avenues and was unsure as to what to delete. Help please.
namespace SquareValue
{
class Program
{
static void Main(string[] args)
{
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
string output;
Console.ReadKey();
}
public int SquareValue(NumberToSquare, NumberToSquare);
{
int result = NumberToSquare * NumberToSquare;
return result;
Console.WriteLine("{0} squared is "+result");
}
public int NumberToSquare()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = Console.ReadLine();
return NumberToSquare;
}
}
I see no reason to over complicate this:
public int Square(int x)
{
return (x * x);
}
or
public int Square(int x)
{
return Math.Pow(x,2);
}
Or just use Math.Pow as it exists with 2 as the Power Of number.
You seem very green on programming and I'm not sure SO is a place to go to learn the basics, but I'll run through what you've done and explain what's going wrong.
Your original program concept is fine but there are many issues with basic syntax. I understand you mightn't be familiar with reading compiler errors so I'll explain the errors that I see just reading through the code...
You put a ; at the end of the SquareValue(..., ...) method which teeminates the declaration so the body in braces isn't part of the method, then things go haywire later on.
You're not passing in the value captured from the NumberToSquare method...
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
NumberToSquare isn't a defined variable so NumberToSquare * NumberToSquare can't calculate, what you'd want is number * number where `number is the value entered by the user.
Your definition of int SquareValue(NumberToSquare, NumberToSquare) expects two parameters although you haven't speified the type. It should be
int SquareValue(int NumberToSquare, int NumberToSquare)
but you have the same variable declared twice which is another error and then you aren't passing two parameters anyway. You want to multiply a number by itself therefore you only have a single source number so why declared two parameters? You need a single parameter method
int SquareValue(int NumberToSquare)
and call like this
int number=NumberToSquare();
SquareValue(number);
Now the SquareValue() method returns an int but you never capture it in the calling code and display the result in the method. Follow the idea in this app that the Main method will do all the orchestration and display, but the SquareValue() method should ONLY do a calculation and not any I/O. I'd also rename the NumberToSquare() method a as what is actually happening ... GetNumberToSquareFromUser().
And there's also a stray " before the closing bracket.
Console.WriteLine("{0} squared is " + result");
And you defined a string output variable which is never used.
And your methods need to be static because main(..) is a static method, not instance. If you declare a Squaring class and instantiated it then you could call non static methods from that.
Also ReadLine() returns a string which can't be assigned to an int.
And finally the result line is implicitly using String.Format behind the scenes but you haven't specified the original number for the {0} token. You could also use interpolation. You could do either of these
Console.WriteLine("{0} squared is " + result, number);
Console.WriteLine($"{number} squared is " + result);
So here's your program revised
class Program
{
static void Main(string[] args)
{
int number = GetNumberToSquareFromUser();
int result = SquareValue(number);
Console.WriteLine("{0} squared is " + result, number);
Console.ReadKey();
}
public static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
public static int GetNumberToSquareFromUser()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = int.Parse(Console.ReadLine());
return NumberToSquare;
}
}
I hope this help, I know it's alot to take in, but I hope you take the time to read and really understand rather than just blindly submit the revised version.
When writing your methods, make them reusable. When you start using a method to output to the console in addition to its primary purpose (i.e. to square a number), its re-usability becomes minimal. It is much better to keep specific code in your main method, and put sub tasks into separate methods, such as squaring a number. Now, whenever you need to square a number, you already have a perfectly good method for that.
I didn't handle the case for users entering bad input, but that can be done in the else of the TryParse if block.
static void Main(string[] args)
{
int squredNum = 0;
int NumberToSquare = 0;
Console.WriteLine("Please enter a number to square: ");
if(int.TryParse(Console.ReadLine(), out NumberToSquare))
{
squredNum = SquareValue(NumberToSquare);
Console.WriteLine("{0} squared is {1}", NumberToSquare, squredNum);
}
Console.ReadKey();
}
static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
p.s. I would not recommend using Math.Pow() to square a number. No need to kill a fly with a bazooka!
Here is an example of such program with robust handling:
using System;
namespace ConsoleApp1
{
internal static class Program
{
private static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter value to square or X to exit");
var line = Console.ReadLine();
if (line == null)
continue;
if (line.Trim().Equals("X", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("Exitting ...");
break;
}
int result;
if (!int.TryParse(line, out result))
continue;
Console.WriteLine(result * result);
}
}
}
}
See the docs online, understand each statement, write your very own program then as your teacher will likely figure out you didn't pull that solely by yourself :)

How to find product of arithmetic progression?

I need to write a function to find a product of arithmetic progression elements (using recursion). I have only vague idea how to do it – something like this:
public static int product(int n)
{
if (n == 0)
return 0;
else
return <some code> * product(n-1);
}
Could you at least give me a hint?
The following code should do the trick:
public static int Product(int arithInitial, int arithDifference, int n)
{
if (n == 1)
return GetArithmeticSeriesTerm(arithInitial,arithDifference,1);
else
return GetArithmeticSeriesTerm(arithInitial,arithDifference,n) * Product(arithInitial, arithDifference, n-1);
}
public static int GetArithmeticSeriesTerm(int initial, int difference, int position)
{
return initial+difference*(position-1);
}
I have created a new method to get the elements of the arithmetic progression. I've also changed the base case of the recursion to be n==1 and then put the call to the arithmetic series term.
It should hopefully be pretty self explanatory as to what it does.
For the first four terms of the series 1,3,5,7,... you would call it as
int result = Product(1,2,4)`
Note: You don't need two methods for this but I feel that introducing the second method makes it clearer what the code is doing. You could of course just inline the expression and of course your base case can in fact be simplified to just initial if you wanted to make it a bit cleaner. Using the full method though makes it very intuitive of why we are doing that.
you need to write a function which take 3 arguments first Term(f) , common difference(d) , and total number of term (n) in AP.
int fun(int f,int d,int n){
if(n==0) return 1;
else (f+(n-1)*d) * fun(f,d,n--);
}

Categories

Resources