What does the '=>' in this statement signify?
del = new SomeDelegate(() => SomeAction());
Is the above declaration the same as this one?
del = new SomeDelegate(this.SomeAction);
Thanks.
Basically it's specifying an anonymous function, that takes no parameters that calls SomeAction. So yes, they are functionally equivalent. Though not equal. Using the lambda is more equivalent to:
del = new SomeDelegate(this.CallSomeAction);
where CallSomeAction is defined as:
public void CallSomeAction()
{
this.SomeAction();
}
Hope that helps!
The "=>" can be read "goes to" (source: Eric Lippert), and simply separates the argument(s) from the operation in a lambda expression. In this case, a lambda is overkill. Better examples would be:
var subList = list.FindAll(item => item.Type == "Foo");
(find all items where the item's type is Foo)
etc. In C# 2.0, this can also be written:
var subList = list.FindAll(delegate(SomeType item) {
return item.Type == "Foo";});
And is a quick way of expression a function "inline", while also offering "closure" support - i.e. it could also be:
string itemType = ...
var subList = list.FindAll(item => item.Type == itemType);
To do this otherwise would require a type-definiton to pass in the item-type:
class Searcher {
public string itemType;
public bool Find(SomeType item) {return item.Type == itemType;}
}
...
Searcher searcher = new Searcher();
searcher.itemType = ...
var subList = list.FindAll(searcher.Find);
In fact, this is pretty-much exactly what the compiler does for us (both for "delegate" and lambda usage). The biggest difference is that a lambda can also express an Expression, for example for LINQ.
They do the same thing but the "() => ..." syntax is what is called a lambda expression and as such is the same as an anonymous function. You could probably leave out the delegate part altogether and just let the compiler infer the delegate type for you.
del = this.SomeAction;
Depending on what type "del" is seclared as.
Edit
Using lambdas or anonymous methods or just a regular method for starters enables you to map methods that didn't have the delegate's signature to the delegate.
For example, say you have a delegate with the signature bool myDelegate(int, int) but you wanted to have a method with the signature bool myMethod(string, string) handle the delegate. You could then use the lambda expression to let you do this inline with a short syntax like so.
delegate bool myDelegate(int x, int y);
// With lambdas...
myDelegate del = (int a, int b) => myMethod(a.ToString(), b.ToString());
// With anonymous methods...
myDelegate del2 = delegate(int a, int b) { return myMethod(a.ToString(), b.ToString()); };
// The good ol' way without lambdas or anonymous methods...
myDelegate del3 = SomeDelegateHandler;
... then write a method somewhere else ...
// Handler method
private bool SomeDelegateHandler(int a, int b)
{
return myMethod(a.ToString(), b.ToString());
}
So as you can see lambdas and anonymous methods are basically just a shorter/inline way of making a method to handle the delegate. In you case you might not need to make an extra method. It just depends on if the delegate signature is the same as your method signature, and to me, it seems like it is.
=> is the Lambda Operator, lambda expressions are like an evolution of the C# 2.0 anonymous methods.
You can use anonymous methods and lambda expressions in a very similar way to create delegate instances:
Func<string,int> wordCount;
wordCount = delegate (string text) { return text.Split().Length; };
Console.WriteLine (wordCount("Hello World"));
Using lambda expressions:
Func<string,int> wordCount;
wordCount = (string text) => { text.Split().Length; };
Console.WriteLine (wordCount("Hello World"));
Related
I'm just curious, in AS3 I can use the methods apply and call, as in:
aFn.apply( thisObj, arrayOfArgs );
or
aFn.call( thisObj, a, b, c );
is there an equivalent syntax in C#?
Preferably without using Reflection.
Thank you for reading.
Not quite. Given a particular instance method like say Object#Equals
You can use Delegate.CreateDelegate to create an "open" delegate. Which will unbind the "this" parameter. Unfortunately, it will not call that particular implementation of Equals, it will call this's class implementation. As Object#Equals is a virtual method.
Once you have your open delegate you can use dynamic invoke. To apply, but the first element in the array is the this.
You can do this::
var #this = new { a = 3, b = 4 };
var other = new { a = 3, b = 4 };
Func<object, object, bool> equalFn = Delegate.CreateDelegate(
typeof(Func<object, object, bool>),
typeof(object).GetMethod("Equals",
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance)) as Func<object, object, bool>;
equalFn.Invoke(#this, other); // call example
equalFn.DynamicInvoke(new[] { #this, other }); // apply example
Open delegates are fairly useful. I can't really recommend a good use for DynamicInvoke if you know your types though.
Am I missing something or is it not possible to return a value from a lambda function such as..
Object test = () => { return new Object(); };
or
string test = () => { return "hello"; };
I get a build error "Cannot convert lambda expression to type 'string' because it is not a delegate type".
It's like this syntax assigns the lambda rather than the result of the lambda, which I did not expect.
I can achieve the desired functionality by assigning the function to a Func and calling it by name, but is that the only way?
Please no "why would you need to do this?" regarding my example.
Thanks in advance!
It’s possible but you are trying to assign a lambda to a string. – You need to invoke the lambda:
Func<string> f = () => { return "hello"; };
string test = f();
The error message actually says it all:
Cannot convert lambda expression to type 'string'
… that’s exactly the issue here.
If you want to invoke the lambda inline – but really: why? – you can do that too, you just need to first make it into a delegate explicitly:
string test = (new Func<string>(() => { return "hello"; }))();
I have this code below.
delegate void TestDel(string str);
static void Main(string[] args)
{
TestDel td = name=> Console.WriteLine(name);
TestDel td = (string name) { Console.WriteLine(name);}
td("hello");
Console.ReadLine();
}
Here I have a delegate TestDel , which is created first by using a lambda expression which goes fine.
But the second method where I am using an anonymous method it doesn't compile but if do like below:
TestDel td = delegate(string name) { Console.WriteLine(name);};
Then everything is fine, my confusion is that why can I use lambda expression and not anonymous method while they are same , why do i need to put delegate with anonymous method but not with lambda expression ?
Your second example should be:
TestDel td = (string name) => { Console.WriteLine(name); };
Because anonymous methods are created using the delegate keyword: http://msdn.microsoft.com/en-us/library/0yw3tz5k%28v=vs.80%29.aspx That's how the language works.
Lambda expressions and anonymous methods are separate language features. A lambda looks like this:
a => Something(a)
And an anonymous method looks like this:
delegate (string a) { Something(a); }
Think of it as the difference between an anonymous type and a class, where the lambda is the anonymous method, and the delegate is the class.
This is a terminology question. In C#, I can do this:
delegate Stream StreamOpenerDelegate(String name);
void WorkMethod(StreamOpenerDelegate d)
{
// ...
}
void Exec1()
{
WorkMethod((x) =>
{
return File.OpenRead(x);
});
}
void Exec2()
{
StreamOpenerDelegate opener = (x) =>
{
return File.OpenRead(x);
};
WorkMethod(opener);
}
Q1
The Exec1() method demonstrates the use of an anonymous delegate, correct?
Q2
Inside Exec2(), would opener
be considered an anonymous delegate? It does have a name. If it's not an anonymous delegate, what should I call it? Is there a name for this syntax? "named anonymous delegate?" a local variable holding an anonymous delegate?
Q1: There's no such term as "anonymous delegate" (in the C# language specification) - but this uses a lambda expression which is one kind of anonymous function. See section 7.14 of the C# language specification for details.
Q2: opener is a variable. The variable is assigned a value created using a lambda expression. After it's been created, the delegate is just an instance of StreamOpenerDelegate. In other words, the concepts of lambda expression, anonymous function and anonymous method are source code concepts rather than execution time concepts. The CLR doesn't care how you created the delegate.
By the way, both of your lambda expressions can be expressed more concisely - fewer parentheses etc:
void Exec1()
{
WorkMethod(x => File.OpenRead(x));
}
void Exec2()
{
StreamOpenerDelegate opener = x => File.OpenRead(x);
WorkMethod(opener);
}
alternatively you could just use a method group conversion:
StreamOpenerDelegate opener = File.OpenRead;
No and no.
A1: This feature is new to C# 3.0 and is called a lambda expression. C# 2.0 has a similar feature called anonymous methods; for example:
button.Click += delegate {
//code
};
A2: opener is a regular variable that happens to hold a lambda expression.
By the way, a lambda expression that takes exactly one parameter doesn't need parentheses. Also, a lambda expression that consists only of a return statement doesn't need braces.
For example:
StreamOpenerDelegate opener = x => File.OpenRead(x);
Question: I have just wrote my first code using c# lambda expressions. It works, but I am not sure if this is the best way to do it. Any recommendations on a better way to do the lambda expression? It seems odd to have numerous lines of code in the expression like I do below.
Background: I have a generic list of delegates. Each delegate function returns an enum value indicating what happened in the function. Upon evaluation of the delegate, I need to add the enum to a List if it was not a specific enum value.
Disclaimer: Code here is very generic, the real code actually does stuff in the delegates to determine the return value!
class Class1
{
public enum WhatHappened
{
ThingA,
ThingB,
Nothing
}
private delegate WhatHappened del();
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened> { };
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
CheckValues.ForEach(x =>
{
WhatHappened wh = x();
if (wh != WhatHappened.Nothing)
returnValue.Add(wh);
});
return returnValue;
}
private static WhatHappened method1()
{
return WhatHappened.Nothing;
}
private static WhatHappened method2()
{
return WhatHappened.ThingA;
}
}
Note: I originally had the lambda like adding all the items (see below), then removing the ones I didn't want (WhatHappened.Nothing).
CheckValues.ForEach(x => returnValue.Add(x()));
Okay, a few suggestions:
Don't call your delegate del. In this case, I'd use Func<WhatHappened> - but if you do want to declare your own delegate type, give it a more descriptive name, and obey the .NET naming conventions.
Instead of using anonymous methods to add to CheckValues, you can just use:
CheckValues.Add(method1);
CheckValues.Add(method2);
The compiler will convert the method groups into delegates.
I'd recommend not using Pascal case for a local variable name to start with.
Your collection initializer for returnValues isn't really doing anything for you - just call the List<T> constructor as normal, or use my code below which doesn't require a local variable to start with.
If your list really only has two delegates in it, I'd just call them separately. It's a lot simpler.
Otherwise you can indeed use LINQ as Jared suggests, but I'd do it slightly differently:
return CheckValues.Select(x => x())
.Where(wh => wh != WhatHappened.Nothing)
.ToList();
EDIT: As suggested, here's the full example. It's not quite the same as Denis's though... I've made a couple of changes :)
public static List<WhatHappened> DoStuff()
{
var functions = new List<Func<WhatHappened>> { Method1, Method2 };
return functions.Select(function => function())
.Where(result => result != WhatHappened.Nothing)
.ToList();
}
(I'm assuming that method1 and method2 have been renamed to fit the naming convention. Of course in real life I'm sure they'd have more useful names anyway...)
I would simply use Linq, but that's just me:
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened>();
CheckValues.Add(method1);
CheckValues.Add(method2);
return CheckValues
.Select(dlg => dlg())
.Where( res => res != WhatHappened.Nothing)
.ToList();
}
Note that you can also use Func instead of declaring a Delegate type if you want, but that's less terse in that case.
Also, I'd return an IEnumerable<WhatHappened> instead of a List, but it's all about the context.
You can go lambda all the way by chaining Select (map) and Where (filter) instead of multiple FOR loops and IF statements
// get results from the list of functions
var results = CheckValues.Select(x => x());
// filter out only the relevant ones.
var returnValues = results.Where(x => x != WhatHappened.Nothing);
Basically, you should think more declaratively instead of imperatively when work ing with lambdas. It'll help you write more elegant code.
It's a bit more idiomatic to write the following instead of using the delegate keyword. It doesn't change the underlying functionality though.
CheckValues.Add( () => method1() );
Also, I find it more readable to rewrite the ForEach as the following
CheckValues = CheckValues.
Select(x => x()).
Where(wh => wh != WhatHappened.Nothing ).
ToList();
In my opinion, based on the example, it looks fine. You could refactor even more by replacing:
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
with:
CheckValues.Add(() => WhatHappened.Nothing);
CheckValues.Add(() => WhatHappened.ThingA);
Here's a LINQ-free solution:
return CheckValues
.ConvertAll<WhatHappened>(x => x())
.FindAll(y => y != WhatHappened.Nothing);
caveat
This is not the most performant solution, as it would iterate twice.
I can't fathom the purpose of the code.. however here goes.
Used delegate chaining
Update: and picked up some Enumerable goodness from Jon n Jared's posts
private delegate WhatHappened WhatHappenedDelegate();
public static List<WhatHappened> DoStuff()
{
WhatHappenedDelegate delegateChain = null;
delegateChain += method1;
delegateChain += method2;
return delegateChain.GetInvocationList()
.Select(x => (WhatHappened) x.DynamicInvoke())
.Where( wh => (wh != WhatHappened.Nothing))
.ToList<WhatHappened>();
}