At various times while programming in C# I've found myself in situations where I'd like to define a lambda (or anonymous delegate) and call it in the same line. At this point, the 'cleanest' way I've been able to do this is like this:
bool foo_equals_bar = new Func<String, bool>(str => str.Equals("foo"))("bar");
I would love to be able to do write something like the following instead:
bool foo_equals_bar = (str => str.Equals("foo"))("bar");
Unfortunately, this doesn't seem to work. I would love to know:
- Is there a simpler way of writing the line of code above?
- What is returned from
(str => str.Equals("foo"))
such that is can be used to initialize aFunc<String, bool>
, but can not be evaluated like aFunc<String, bool>
?
I should point out that I'm working in C# 3 (VS2008), so if a solution only exists in C# 4, please mention that. (I'd still like to know, even if the solution isn't available to me at the moment).
Thanks
You would need a set of helper methods to make compiler infer lambda types, e.g.:
public static class Functional
{
public static Func<TResult> Lambda<TResult>(Func<TResult> func)
{
return func;
}
public static Func<T, TResult> Lambda<T, TResult>(Func<T, TResult> func)
{
return func;
}
public static Func<T1, T2, TResult> Lambda<T1, T2, TResult>(Func<T1, T2, TResult> func)
{
return func;
}
}
Now you can write:
bool foo_equals_bar = Functional.Lambda(str => str.Equals("foo"))("bar");
str => str == "A"
is the same as
delegate (string str) { return str == "A";};
So no, there's no way to get just the lambda, since the compiler wouldn't know what type str is if you just said
bool result = (str => str == "A")("B");
EDIT:
Yes, you can add types to lambda expressions, like (string str) => str == "A";
but still, they can't be implicit for some reason. Not sure why. Thanks for the comment, Yuriy.
What is returned from (str => str.Equals("foo")) such that is can be used to initialize a Func, but can not be evaluated like a Func?
Just using built-in types, there's:
Expression<Func<string, bool>> a = str => str.Equals("foo");
Expression<Predicate<string>> b = str => str.Equals("foo");
Expression<Action<string>> c = str => str.Equals("foo");
Func<string, bool> a1 = str => str.Equals("foo");
Predicate<string> b1 = str => str.Equals("foo");
Action<string> c1 = str => str.Equals("foo");
All of which are valid interpretations of the lambda expression. That's just the built-in types that I can think of off the top of my head. There's also any delegate that matches the signature.
At various times while programming in C# I've found myself in situations where I'd like to define a lambda (or anonymous delegate) and call it in the same line.
Those are strange situations. Avoid them. This is not possible because the compiler cannot infer the type. This could work when you pass the anonymous delegate to some method from which the compiler can infer the types.
And in any cases:
bool foo_equals_bar = "bar".Equals("foo");
is far more readable than*:
bool foo_equals_bar = (str => str.Equals("foo"))("bar");
* assuming such syntax was possible
You have to cast the lambda to a func or delegate
((Func<string, bool>)(str => str.Equals("bar")))("baz")
using System.Threading.Tasks;
using System.Threading;
Task.Run(()=>{
//do something
});
You can add a 500ms delay with
Task.Run(()=>{
Thread.Sleep(500);
//do something
});
Not sure when MS added it but it wasn't C#3
this programming style can accomplish anything and you can basically ignore the rest of C# specs once you learn this
精彩评论