Lambda expressions, or just "lambdas" for short, were introduced in C# 3.0 as one of the core building blocks of Language Integrated Query (LINQ). They are just a more convenient syntax for using delegates.
They are actually two very different things. "Delegate" is actually the name for a variable that holds a reference to a method or a lambda, and a lambda is a method without a permanent name. Lambdas are very much like other methods, except for a couple subtle differences.
Anonymous Method is an inline code that can be used wherever a delegate type is expected. Microsoft introduced Anonymous Methods in C# 2.0 somewhere around 2003. Lambda expression is an anonymous method that you can use to create delegates or expression tree types.
No, there isn't. Lambda expressions are optimised (in terms of syntax) for the single parameter case. I know that the C# team feels your pain, and have tried to find an alternative. Whether there ever will be one or not is a different matter.
A lambda expression can either be converted to a delegate type or an expression tree - but it has to know which delegate type. Just knowing the signature isn't enough. For instance, suppose I have:
public delegate void Action1();
public delegate void Action2();
...
Delegate x = () => Console.WriteLine("hi");
What would you expect the concrete type of the object referred to by x
to be? Yes, the compiler could generate a new delegate type with an appropriate signature, but that's rarely useful and you end up with less opportunity for error checking.
If you want to make it easy to call Control.Invoke
with an Action
the easiest thing to do is add an extension method to Control:
public static void Invoke(this Control control, Action action)
{
control.Invoke((Delegate) action);
}
Tired of casting lambdas over and over?
public sealed class Lambda<T>
{
public static Func<T, T> Cast = x => x;
}
public class Example
{
public void Run()
{
// Declare
var c = Lambda<Func<int, string>>.Cast;
// Use
var f1 = c(x => x.ToString());
var f2 = c(x => "Hello!");
var f3 = c(x => (x + x).ToString());
}
}
Nine tenths of the time people get this because they are trying to marshal onto the UI thread. Here's the lazy way:
static void UI(Action action)
{
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(action);
}
Now that it's typed, the problem goes away (qv Skeet's anwer) and we have this very succinct syntax:
int foo = 5;
public void SomeMethod()
{
var bar = "a string";
UI(() =>
{
//lifting is marvellous, anything in scope where the lambda
//expression is defined is available to the asynch code
someTextBlock.Text = string.Format("{0} = {1}", foo, bar);
});
}
For bonus points here's another tip. You wouldn't do this for UI stuff but in cases where you need SomeMethod to block till it completes (eg request/response I/O, waiting for the response) use a WaitHandle (qv msdn WaitAll, WaitAny, WaitOne).
Note that AutoResetEvent is a WaitHandle derivative.
public void BlockingMethod()
{
AutoResetEvent are = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem ((state) =>
{
//do asynch stuff
are.Set();
});
are.WaitOne(); //don't exit till asynch stuff finishes
}
And a final tip because things can get tangled: WaitHandles stall the thread. This is what they're supposed to do. If you try to marshal onto the UI thread while you have it stalled, your app will hang. In this case (a) some serious refactoring is in order, and (b) as a temporary hack you can wait like this:
bool wait = true;
ThreadPool.QueueUserWorkItem ((state) =>
{
//do asynch stuff
wait = false;
});
while (wait) Thread.Sleep(100);
Peter Wone. you are da man. Taking your concept a bit further, I came up with these two functions.
private void UIA(Action action) {this.Invoke(action);}
private T UIF<T>(Func<T> func) {return (T)this.Invoke(func);}
I place these two functions into my Form app, and I can make calls from background workers like this
int row = 5;
string ip = UIF<string>(() => this.GetIp(row));
bool r = GoPingIt(ip);
UIA(() => this.SetPing(i, r));
Maybe a bit lazy, but i don't have to setup worker done functions, which comes in super handy in cases such as this
private void Ping_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
int count = this.dg.Rows.Count;
System.Threading.Tasks.Parallel.For(0, count, i =>
{
string ip = UIF<string>(() => this.GetIp(i));
bool r = GoPingIt(ip);
UIA(() => this.SetPing(i, r));
});
UIA(() => SetAllControlsEnabled(true));
}
Essentially, get some ip addresses from a gui DataGridView, ping them, set the resulting icons to green or red, and reenable buttons on the form. Yes, it is a "parallel.for" in a backgroundworker. Yes it is a LOT of invoking overhead, but its negligible for short lists, and much more compact code.
I tried to build this upon @Andrey Naumov's answer. May be this is a slight improvement.
public sealed class Lambda<S>
{
public static Func<S, T> CreateFunc<T>(Func<S, T> func)
{
return func;
}
public static Expression<Func<S, T>> CreateExpression<T>(Expression<Func<S, T>> expression)
{
return expression;
}
public Func<S, T> Func<T>(Func<S, T> func)
{
return func;
}
public Expression<Func<S, T>> Expression<T>(Expression<Func<S, T>> expression)
{
return expression;
}
}
Where type parameter S
is the formal parameter (the input parameter, which is minimum required to infer rest of the types). Now you can call it like:
var l = new Lambda<int>();
var d1 = l.Func(x => x.ToString());
var e1 = l.Expression(x => "Hello!");
var d2 = l.Func(x => x + x);
//or if you have only one lambda, consider a static overload
var e2 = Lambda<int>.CreateExpression(x => "Hello!");
You can have additional overloads for Action<S>
and Expression<Action<S>>
similarly in the same class. For other built in delegate and expression types, you will have to write separate classes like Lambda
, Lambda<S, T>
, Lambda<S, T, U>
etc.
Advantage of this I see over the original approach:
One less type specification (only the formal parameter needs to be specified).
Which gives you the freedom to use it against any Func<int, T>
, not just when T
is say, string
, as shown in examples.
Supports expressions straight away. In the earlier approach you will have to specify types again, like:
var e = Lambda<Expression<Func<int, string>>>.Cast(x => "Hello!");
//or in case 'Cast' is an instance member on non-generic 'Lambda' class:
var e = lambda.Cast<Expression<Func<int, string>>>(x => "Hello!");
for expressions.
Extending the class for other delegate (and expression) types is similarly cumbersome like above.
var e = Lambda<Action<int>>.Cast(x => x.ToString());
//or for Expression<Action<T>> if 'Cast' is an instance member on non-generic 'Lambda' class:
var e = lambda.Cast<Expression<Action<int>>>(x => x.ToString());
In my approach you have to declare types only once (that too one less for Func
s).
One another way to implement Andrey's answer is like not going fully generic
public sealed class Lambda<T>
{
public static Func<Func<T, object>, Func<T, object>> Func = x => x;
public static Func<Expression<Func<T, object>>, Expression<Func<T, object>>> Expression = x => x;
}
So things reduce to:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
That's even less typing, but you lose certain type safety, and imo, this is not worth it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With