Executing multicast delegates - c#

I have a Multiple target
Func<int,int,int> funHandler=Max;
funHandler+=square;
When i execute
Console.WriteLine(funHandler(10,10)); it return the square of 10 (i.e) 200.It did not fire Max.
i used something like
foreach(var v in funHandler.GetInvocationList())
{
Console.WriteLine(v(10,20));
}
'V' is a variable,but it is used like a method.How can i fire all methods that is in delegate's
invocation list?

Well, may be Max has no side effects and you can't notice it? When you execute multicast delegate it returns result of only last delegate.
Try this:
Func<int, int, int> funHandler = (x, y) => { Console.WriteLine(x); return x; };
funHandler += (x, y) => { Console.WriteLine(y); return y; };
int res = funHandler(1, 2);
Console.WriteLine(res);
See? it works
To use invocation list do this:
foreach (var v in funHandler.GetInvocationList())
{
((Func<int, int, int>)v)(1, 2);
}
Or:
foreach (Func<int, int, int> v in funHandler.GetInvocationList())
{
v(1, 2);
}

Multicast with a delegate that returns something doesn't make much sense to me. I'd guess it executes all of them but discards all results but one.

Related

Having issues with this lambda code not returning a value for all situations

I'm working on a project that requires that I use a few Lambdas. I am trying to create one that will have two strings and an int plugged into it, and if the two strings are the same, then the int++. Here is my code:
DelegateName tally = (x, y, z) => { if (x == y) z++; };
I understand how not all code paths return a value but I am not sure what direction to go to fix it. I essentially will run this 12 times in order to add a tally to one of 12 variables if the x string is the same as the y string. It is counting the number of matching strings and adding it to the appropriate variable (the int)
Here is the code that I am trying to replace with a lambda:
if (cellValue.ToString().Substring(0, 1) == "1")
{
variable1++;
}
Was hoping to clean it up by calling tally(cellValue.ToString().SubString(0,1), 1, variable1) instead
Your variable1 is a int (a Value type) so when you pass it as argument, you actually passing its value, so inside your tally lambda there will be another int variable z which is independent from variable1. So, when you do z++ inside tally, your variable1 is not changing.
If your tally is defined near variable1 you may just use it inside your lambda:
var variable1 = 0;
DelegateName tally = (x, y) => { if (x == y) variable1++; };
foreach (var cellValue in cells)
tally(cellValue.ToString().SubString(0,1), "1");
Another way is a LINQ:
using System.Linq;
var variable1 = cells.Select(c => c.ToString().FirstOrDefault()).Count(c => c == '1');
// or even better (thx #RufusL)
var variable2 = cells.Count(c => c.ToString().StartsWith("1"));
Think of a lambda as just shorthand for a regular method. The lambda you provided:
(x, y, z) => { if (x == y) z++; }
translates to:
void IncrementIfEqual(string x, string y, int z)
{
if (x == y) z++;
}
(Lambdas don't have a method name, so I just randomly called the method IncrementIfEqual). You aren't returning any value from inside the method, so the method returns void. Also, the argument z that you pass in gets incremented inside the method, but doesn't have any effect on the value of the original variable passed in. For example, if you called the method you wrote like this...
IncrementIfEqual(cellValue.ToString().Substring(0, 1), "1", variable1)
then variable1 would remain the same value after the call because the method incremented the argument z, which doesn't exist outside the method. You could write the method like this...
int IncrementIfEqual(string x, string y, int z)
{
return (x == y) ? ++z : z;
}
which increments the value z and returns it if x and y are equal, otherwise it just returns the original value passed in. You could then call it like this...
variable1 = IncrementIfEqual(cellValue.ToString().Substring(0, 1), "1", variable1)
In that case, the lambda expression you'd want is this...
(x, y, z) => { return (x == y) ? ++z : z; }
I'm not sure what DelegateName is, but if it has the Invoke() method, your full usage might be something like this...
DelegateName tally = (x, y, z) => { if (x == y) z++; };
variable1 = tally.Invoke(cellValue.ToString().Substring(0, 1), "1", variable1)

Func<T> get result of every single call?

I recently discovered that there is little difference between a delegate and an event. In fact you can "hook" multiple functions into a single Func<T>, for example:
Func<int> mFunction;
...
Func<int, int> getValue = value => {
Console.WriteLine("assigning {0}", value);
return value;
};
mFunction += () => getValue(6);
mFunction += () => getValue(5);
...
int x = 0;
Func<int> function = mFunction;
if (function != null)
x = function();
Console.WriteLine(x);
This calls each "hooked" function, and assigns each value to x in sequence, and x ends up with the last value assigned. In other words, the output is:
assigning 6
assigning 5
5
Is there a way to retrieve all of the return values of these function calls?
You can loop through each Func<int> in the GetInvocationList() method of your object:
foreach(Func<int> f in function.GetInvocationList())
{
var y = f();
//y holds the result
}
Per default, you only get the last return value. However, you can fetch all delegates using GetInvocationList() and then call each individually.
See Calling delegates individually?

Function variable calling itself [duplicate]

This question already has answers here:
C#: Recursive functions with Lambdas
(3 answers)
Closed 9 years ago.
How can you call a Func function from itself?
For example:
Func<int, int> f = x => {
// do stuff
if (x > 5) { return f(x); }
// do other stuff
};
Simple way to is to create the variable, assign it null, and then use it in your lambda:
Func<int, int> f = null;
f = x => {
// do stuff
if (x > 5) { return f(x); }
// do other stuff
};
By the time it comes to actually invoke the delegate in f, it will have been assigned to a non-null value.
If you prefer, you can also follow the approach shown in this (theory heavy) blog entry.
dlev's answer is fairly straight forward, but you can also do this way:
First declare a delegate type that accepts itself as a parameter:
public delegate TResult RecursiveFunc<TParam, TResult>(
TParam param1,
RecursiveFunc<TParam, TResult> func);
NOTE: of course the delegate doesn't have to be generic.
You can now create your lambda expression like this:
RecursiveFunc<int, int> f = (x, g) => {
// do stuff
if (x > 5) { return g(x, g); }
// do other stuff
};
f(123, f); // Invoke recursively

Lambda expression with a void input

Ok, very silly question.
x => x * 2
is a lambda representing the same thing as a delegate for
int Foo(x) { return x * 2; }
But what is the lambda equivalent of
int Bar() { return 2; }
??
Thanks a lot!
The nullary lambda equivalent would be () => 2.
That would be:
() => 2
Example usage:
var list = new List<int>(Enumerable.Range(0, 10));
Func<int> x = () => 2;
list.ForEach(i => Console.WriteLine(x() * i));
As requested in the comments, here's a breakdown of the above sample...
// initialize a list of integers. Enumerable.Range returns 0-9,
// which is passed to the overloaded List constructor that accepts
// an IEnumerable<T>
var list = new List<int>(Enumerable.Range(0, 10));
// initialize an expression lambda that returns 2
Func<int> x = () => 2;
// using the List.ForEach method, iterate over the integers to write something
// to the console.
// Execute the expression lambda by calling x() (which returns 2)
// and multiply the result by the current integer
list.ForEach(i => Console.WriteLine(x() * i));
// Result: 0,2,4,6,8,10,12,14,16,18
You can just use () if you have no parameters.
() => 2;
The lmabda is:
() => 2

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