Why can't I have this? I mean it would spare a delegate declaration:
int X=delegate int(){...};
I know it can be done this way:
delegate int IntDelegate();
...
IntDelegate del=delegate(){return 25;};
int X=del();
A delegate is not an int.
If you use .Net 3.5 or newer you can use the built in Func instead of using a custom (Func also have generic types if you need arguments like Func which tages a string and return an int):
Func<int> X = delegate() { return 255; };
or with lambda expressions:
Func<int> X = () => 255;
Unfortunately, you can't say:
var X2 = () => 255;
in C# but you can do something similar in functional languages ex F#. Instead you would say the following in C#:
var X2 = new Func<int>(() => 255);
Tomas,
would this work for you:
delegate int IntDelegate();
// other stuff...
IntDelegate _del = () => 25;
jim
[edit] - oops, just realised, the question was re making it a one liner!! - i'll have a think
Because in the first example, you're trying to assign a delegate type into an int, rather than the output of a delegate into an int. A delegate is a type that stores a function, which just so happens to return a value that you're interested in.
Is there really a need for creating a delegate, executing it, and returning the value?
Why not just execute the code directly?
int x = new Func<int,int>(num => num*num) (3);
would return 9, but so would:
int x = 3*3;
Related
Why do the first and third expressions work but not the second?
var ss = new Func<int>(() => 0); //works
int x1 = new Func<int>(() => 0); //doesn't work --Cannot convert source type 'System.Func<int>' to target type 'int'
int x2 = new Func<string,int>((x) => 0)(""); //works
With
var ss = new Func<int>(() => 0);
the compiler is able to correctly infer the actual type of ss to be Func<int>. Func<int> is a delegate that can be invoked and returns an int. So:
ss() == 0 // is true
Notice that we had to invoke ss here (e.g. ss() ) in order for it to return an int.
So knowing what we do from above, the following can't be right
int x1 = new Func<int>(() => 0);
because you're now trying to store a function/delegate (identical to the previous one) into a variable typed as int. It's a delegate of type Func<int>... very different from an int, it's something that returns an int when called/invoked.
In this case
int x2 = new Func<string,int>((x) => 0)("");
you are declaring a function that takes a string as a parameter and returns an int, then immediately invoking it (supplying an unused empty string, "" as the parameter). The function then returns the int which you then store against x2.
Makes more sense now?
Have you tried adding the return type for your Func, like so,
int x1 = new Func<int, int>(() =<0);
You will notice, this also returns the same error.
var works because the value of var does not matter for type. C# is strongly typed so for int, the Func is expecting a value type of int.
Let's say I have a delegate declaration taking one int as argument:
public delegate void MyDelegate(int i);
private MyDelegate _myDelegate = null;
and I have some function that takes a string and an int as arguments
private MyFunc(string s, int i){
...
}
Now I'd like to create a MyDelegate from MyFunc by specifying the string argument already in advance but leaving the int argument open. something like:
_myDelegate = new MyDelegate(MyFunc("Hello", ?));
whereas the ? would mark the still open argument that would need to be passed when invoking _myDelegate. I know this is is possible in other languages (for example, the ? syntax is comming from Eiffel agents).
how to do this in C#?
You can use a lambda. Since the type can be inferred, you don't need to explicitly say new MyDelegate(...).
_myDelegate = i => MyFunc("Hello", i);
You can use a lambda expression to achieve this kind of partial-function application:
_myDelegate = new MyDelegate(i => MyFunc("Hello", i));
Since _myDelegate is of type MyDelegate, you can also assign it the lambda directly:
_myDelegate = i => MyFunc("Hello", i);
Delegate is clear to understand
delegate int del(int i);
but why can we use
del myDelegate = x => x * x;
Questions here:
How can I assure x is int type in the lambda expresison?
How can I know lambda expression return a int?
C# compiler is smart enough to implicitly figure out the type of x on the left side of => from the context. Since it knows that you are assigning the lambda to a variable of type del, the compiler knows that x is an int.
As far as the return type goes, the compiler knows that x is an int, therefore the type of the x * x expression must also be int. That's how the compiler knows the return type of the lambda.
Note that the same code would not have compiled without the exact type of myDelegate specified:
// This does not compile!
var myDelegate = x => x*x;
Because for you to have x, you had to give it a type. It will detect this type rather than making you tell it over and over what type it is.
Right now you're letting the compiler determine what the lamdba expression is doing. You can sublclass using Action and Func
Actions return type is void while Func's return type is whatever you specify as the last type parameter. You can specify additional inputs in both
Func<in, in2, in3, output>
For returning an int
var f = new Func<int, int>(x => x*x);
Consider this code snippet and try to guess what y1 and y2 evaluate to
static class Extensions
{
public static Func<T> AsDelegate<T>(this T value)
{
return () => value;
}
}
class Program
{
static void Main(string[] args)
{
new Program();
}
Program()
{
double x = Math.PI;
Func<double> ff = x.AsDelegate();
Func<double> fg = () => x;
x = -Math.PI;
double y1 = ff(); // y1 = 3.141..
double y2 = fg(); // y2 = -3.141..
}
}
You might say -Aha- double is a value type and so the value returned by the extension method is a copy of the main x. But when you change the above into delegates of classes the results are still different. Example:
class Foo
{
public double x;
}
Program()
{
Foo foo = new Foo() { x=1.0 };
Func<Foo> ff = foo.AsDelegate();
Func<Foo> fg = () => foo;
foo = new Foo() { x = -1.0 };
double y1 = ff().x; // y1 = 1.0
double y2 = fg().x; // y2 = -1.0
}
So the two functions must return two different instances of the same class. It is interesting to consider that ff() carries with it a reference to local variable foo, but fg() does not and it relies on what is in scope currently.
So what happens when these two delegates are passed on to other parts of the code which do not have visibility to foo instance? Somehow the question of who owns what information (data) is becoming less and less clear when extension methods are combined with delegates.
AsDelegate captures the variable value (the parameter of AsDelegate), while () => x captures the variable x. So if you change the value of x, the lambda expression will return a different value. Changing x doesn't change value though.
See: Outer Variable Trap
In AsDelegate, we are capturing the the argument "value". the value of this argement is taken as a copy of the value of the variable at the time the method is invoked, and never changes - so we see the original object.
The direct lambda captures the variable foo (not the value of the variable - the variable itself) - thus we do see changes to this.
Basically adding a method call changed the thigh being captured.
ff captures (binds) to the value of x at this line:
Func<double> ff = x.AsDelegate();
By contrast, fg binds to the variable x at this line:
Func<double> fg = () => x;
So, when the value of x changes, ff is unafected, but fg changes.
The AsDelegate extension method uses the value of x at the time AsDelegate is called whereas the lambda expression () => x captures the variable x and therefore the value of x is taken at the time the expression is invoked (rather than the value when it was defined).
() => x captures x value. Special class is created by compiler to handle lambdas or anonymous delegates, any variable used in the lambda is captured.
For example if you run following code:
List<Func<int>> list = new List<Func<int>>();
for (int i = 0; i < 5; i++)
{
list.Add(() => i);
}
list.ForEach(function => Console.WriteLine(function()));
you will see that numbers printed are the same.
You need to read about closures in C#. See also Wikipedia.
The first method creates a new delegate to a given function and stores it. It you later overwrite foo, your newly created delegate is not touched.
The second one is a lambda expression which lifts/*captures* its context, that means the foo variable. All changes to variables that has been lifted by lambdas expressions are seen by that lambda expression.
In c# we can create delegates via a variety of means (e.g. Action<>, Func<>, delegate, lambdas, etc). But when you invoke those methods, you have to provide the parameter values for the delegate you are invoking:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5);
Is there a way in c# to encapsulate a method delegate WITH parameter values? Essentially delay invocation of a fully parametrized method? So you don't have to supply parameter values at invocation time?
For example something like this invalid code:
delegate int del(int i);
del myDelegate(5) = x => x * x;
int j = myDelegate;
I'm aware the use case isn't immediately obvious. In the case I'm currently looking at, I have a non-deterministic method that I would like the caller to be able to invoke without having to contain or be aware of the parameters the method needs. One way to achieve this would be via creating a class that encapsulates both the parameter values and the method delegate and have that referenced and invoked by the caller. But I'm just curious if there is an alternate, more succinct way.
This is called currying.
For example:
Action curried = () => myFunc(5);
Or,
Func<int, int, int> multiplier = (x, y) => x * y;
Func<int, int> doubler = x => multiplier(x, 2);
int eight = doubler(4);
Func<int, int> myDelegate = x => x * x;
Func<int> myDelegate5 = () => myDelegate(5);
int j = myDelegate5();
You could always wrap one delegate in another. As SLaks mentioned, this is called currying:
Func<int, int> square = i => i * i;
Func<int> squareFive = () => square(5);
int j = squareFive();
This can be done reasonably nicely without lambdas, with the aid of some generic classes and helper functions. I used such an approach in some vb.net/vs2005 code. If the goal is to yield a MethodInvoker which calls a function with three arguments of types T, U, and V, then create a class ParamInvoker<T,U,V> which holds fields param1, param2, and param3 (as types T, U, and V), and Action (of type Action<T,U,V>) and has a method DoIt(void) which calls Action(param1, param2, param3). The generic classes and helper functions get repetitive, but the syntax is pretty nice. For example (vb syntax, from memory, and C# syntax, guessing):
TheMethodInvoker = MakeParamInvoker(AddressOf MyFunction, 5, "Hello")
or
TheMethodInvoker = MakeParamInvoker(MyFunction, 5, "Hello")
assuming MyFunction takes an Integer and a String.