Invoke a lambda without creating a delegate; causes CS0149 Method name expected - c#

I would like to create a lambda expression and invoke it immediately and I would like to avoid creating a delegate; a trivial example1:
int i = (() => 42)();
This produces the error:
CS0149 Method name expected
There are two workarounds:
Declare a (local) method:
int Return42() => 42;
int i = Return42();
Create a delegate:
int i = ((Func<int>)(() => 42))();
It is possible to create and immediately invoke a lambda expression without creating a delegate and without naming it? And if possible, how can one create such a lambda?
1. In reality it is an async Task that I would like to use instead of Task.ContinueWith (I tried to follow what Stephen Cleary said: you should strive to replace ContinueWith with await); e.g:
Task<int> future = (async () =>
(await RetrieveLookupFromFarAway())["42"].First())();
With RetrieveLookupFromFarAway something like:
async Task<ILookup<string, int>> RetrieveLookupFromFarAway()
{
await Task.Delay(1000);
return Enumerable.Empty<int>().ToLookup((x) => x.ToString());
}

The concept of a lambda expression only exists as source code. It doesn't even have a type in itself (just like the null literal doesn't have a type). It has to be converted to either an expression tree or a delegate: that's what exists as far as the IL and the CLR are concerned. The compiler has to emit code to create something, and you need to tell it which type you want that to be.
The compiler doesn't play favourites in terms of delegate types: while it could "know" about Func<T> and use that as a default delegate type for a lambda expression with no parameters, it doesn't.
The closest you'll get to what you want is to have a convenience method that you can call accepting a Func<T>, which could either just return the function, or execute it and return the result. For example:
public static Func<T> CreateFunc<T>(Func<T> func) => func;
public static T ExecuteFunc<T>(Func<T> func) => func();
Then you can call it as:
CreateFunc(() => 42)();
or
ExecuteFunc(() => 42);

Related

c# Predicate with no parameters

I'm trying to pass a Predicate to a function but it has no input. I'm actually trying to delay the computation until the call is made.
Is there a way to use c# Predicate type for that? If not why.
I know a way to do this with Func
Func<bool> predicate = () => someConditionBool;
But I want to do this:
Predicate<> predicate = () => someConditionBool;
If it's just a readability problem, then you can create your own delegate which returns boolean and don't have any parameters:
public delegate bool Predicate();
And use it this way
Predicate predicate = () => someConditionBool;
NOTE: You should keep in mind that everyone is familiar with default Action and Func delegates which are used in .NET, but Predicate is your custom delegate and it will be less clear at first time for average programmer.
Is there a way to use c# Predicate type for that? If not why?
Looking at the signature of Predicate<T> is shows that it requires an argument or parameter:
public delegate bool Predicate<in T>(T obj)
So the quick answer here would be no. Because you have no parameters in your anonymous function.
But if you play a little around you can give the predicate some irrelevant object which it will not use anyway, like an alibi parameter:
Func<bool> predicate = () => 1 == 1;
Predicate<object> predicate2 = (x) => 1 == 1;
and the call would look like this:
Console.WriteLine(predicate());
Console.WriteLine(predicate2(null));
And this compiles and returns the correct result

lambda expression, anonymous function delegates in C#

do all anonymous functions need to be typed with delegate keyword? for example we have a Customer class,
delegate(Customer a)
{return a.name == "Michael";}
Is this anonymous function
(Customer a)
{return a.name == "Michael";}
a function or a delegate or both?
do all lambda expression also Predicate delegate by default? for example, we have a List of Customer, which is listCustomers, if we want to use TrueForAll function to see whether all customers called "Michael", we can just type as:
listCustomers.TrueForAll(x => x.name == "Michael);
But TrueForAll takes Predicate as parameter, as we know Predacate is a delegate, which means "x => x.name == "Michael" is also a Predicate delegate by default?
Forms of anonymous delegates:
// A: C# 2.0... No one uses it in new developments since years
delegate() { }
// B: C# 3.0 and above
() => { }
Why can I set an anonymous delegate to a given delegate?
Action a1 = () => Console.WriteLine("hello world");
Action<int> a2 = number => Console.WriteLine(number);
Func<bool> f1 = () => true;
This is called delegate type inference.
In summary, if the right side of an assignment fulfills the signature of the left side (i.e. the delegate type), the right side is infered as the type of the left side. This is also true for method parameters.
In the other hand, it's not the same a lambda expression than a delegate with lambda syntax:
Expression<Action> expr1 = () => Console.WriteLine("hello world");
Action a1 = () => Console.WriteLine("hello world");
The first is an expression tree, which is a data structure similar to an abstract syntax tree that can be used to extract info from the epxression and its childs, while the later is a delegate.
Expression trees can be compiled into delegates:
Action a2 = expr1.Compile();
a2();
Further reading
Lambda expressions
Delegate Type Inference in C#

Combining expression trees

I have the following expression:
public Expression<Func<T, bool>> UserAccessCheckExpression<T>(int userId) where T : class
{
return x => (IsAdmin || userId == CurrentUserId || userId == 0);
}
Then I want to apply this filter to several collections (IQueryable) like this one:
return tasks
.Where(t => t.TaskUsers
.Any(x => UserAccessCheckExpression<TaskUser>(x.User) && x.SomeBool == true));
I'm getting the following error while doing so:
Error 40 Cannot implicitly convert type System.Linq.Expressions.Expression<System.Func<TaskUser,bool>> to bool
I can't use workaround with interface inheritance (like TaskUser inherits interface with int UserId property (where T : IHasUserId)) since I want to combine logic.
The problem is that your UserAccessCheckExpression() method is returning an Expression while the Any() method is expecting a boolean.
Now, you can get your code to compile by compiling the Expression and invoking the method (using UserAccessCheckExpression<TaskUser>(x.User).Compile().Invoke(x.User)) but that would obviously fail on runtime because Linq-to-Entities wouldn't be able to translate your Any() to a store query as it no longer contains an Expression.
LinqKit is aiming to solve this problem using its own Invoke extension method that while letting your code compile, will make sure your Expression will get replaced back to its original form using another extension method named AsExpandable() that is extending the entity set.
Try this:
using LinqKit.Extensions;
return tasks
.AsExpandable()
.Where(t => t.TaskUsers.Any(
x => UserAccessCheckExpression<TaskUser>(x.User).Invoke(x)
&& x.SomeBool == true));
More on LinqKit
Yeah, so, you can't do that. There's a difference between an Expression<> and a Func<>. You're trying to use the UserAccessCheckExpression as a func. I'm not sure what you're trying to do, but you can compile it to a func and then use it sorta like you are:
var expr = UserAccessCheckExpression<TaskUser>(x.User);
var func = expr.Compile();
// Later use it like ...
var result = func();
But I expect you're using this with EF or Linq2Sql? That being the case you'll need to rewrite the expression. It can be done by hand (not easy) or, better, use a tool like PredicateBuilder.

How can I produce a Task<Task> to Unwrap

Can someone please explain the difference between these two statements:
Task<Task> bTask = backup.BackupCurrentDatabaseAsync()
.ContinueWith(_ => CompressArchiveAsync());
//unwrap the tasks to produce one entire task
Task t = bTask.Unwrap();
vs
Task<Task> bTask = backup.BackupCurrentDatabaseAsync()
.ContinueWith(_ =>
{
CompressArchiveAsync();
});
//unwrap the tasks to produce one entire task
Task t = bTask.Unwrap();
The methodsExtractArchiveAsync(), BackupCurrentDatabaseAsync(), RestoreDatabaseAsync() all return a Task.
Here, the first Continuation returns a Task<Task>. I can then Unwrap() this task to put Continuations on the resultant (inner) task.
The second version doesn't compile. The only different here is the braces around the CompressArchiveAsync().
I am trying to access the resultant (internal) Task to check the Task.Status. If I use the second method, the Task.Status is reporting the result of the BackupCurrentDatabaseAsync() task.
.ContinueWith(_ => CompressArchiveAsync());
is equivalent to:
.ContinueWith(_ =>
{
return CompressArchiveAsync();
});
Notice the return.
Your second code snippet doesn't compile because ContinueWith doesn't return a Task<Task>, but simply a Task, and there's nothing to unwrap.
The following is bound to a Func<Task, Task> (a function that takes a Task and returns a Task)
_ =>
{
return CompressArchiveAsync();
}
But the following is actually bound to an Action<Task> (a function that takes a Task but doesn't return anything):
_ =>
{
CompressArchiveAsync();
}
And the reference to the Task created by CompressArchiveAsync is never returned. Without a reference to it, you can't check the Task's status.
Note that:
ContinueWith<TResult>(Func<Task, TResult>) returns a Task<TResult>
ContinueWith(Action<Task>) returns a Task.
Therefore your ContinueWith(Func<Task, Task>) returns a Task<Task> that you can unwrap, but your ContinueWith(Action<Task>) simply returns a Task.
The difference is in the Lambda Expression syntax.
There are 2 types of Lambdas: Expression Lambdas and Statement Lambdas. Expression Lambdas have no braces and return the result of the expression while Statement Lambdas have braces containing zero or more statements (one of them can be a return statement).
So this Expression Lambda:
_ => CompressArchiveAsync()
Is equivalent to this Statement Lambda:
_ => { return CompressArchiveAsync(); }
So, the difference is that in the first continuation you are returning a task but in the second you are not, it's just a void anonymous delegate. That's why the first continuation is a Task<Task> while the second is just a Task.
Long comment to show 4.5 code.
If you could move to .Net 4.5 than code you are trying to write can be rewritten in more compact way with async/await which is essentially implements all that code internally:
async Task CompleteBackup()
{
await backup.BackupCurrentDatabaseAsync()
await CompressArchiveAsync());
await .....
}
In the first example, you are calling ContinueWith with a Func. Therefore, it will return a Task<T>. The second try will call the ContinueWith overload with an Action, because... well it's an action, it does not return anything. So it will return a simple Task without T.

LINQ Select Statement. Anonymous Method Returns Exception

When using an anonymous method in a LINQ Select statement does the anonymous method have to return a value?
When I do the following I get no errors:
await Task.WhenAll(list.Select(a => doSomething(a)));
But when I do this I get an error that says type arguments cannot be inferred from the usage:
await Task.WhenAll(list.Select(a => {
doSomething(a);
Log("Log Something");
UpdateUI();
}));
Why does the first work and the second doesn't?
Here is the doSomething method:
private async Task doSomething(string a)
{
HttpClient client = new HttpClient;
// Do stuff
string source = await client.PostAsync(a, content);
// Extract data from source and store in text file.
}
When using an anonymous method in a LINQ Select statement does the anonymous method have to return a value?
Yes. The signature of the Select method is:
public IEnumerable<TResult> Select<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, TResult> selector)
so the selector must return a value.
With your first code snippet the return statement is implicit. doSomething returns a value, and that value is what each item is projected to.
When you use a statement lambda, instead of an expression lambda, there is no implicit return statement. Since your second code block is not returning anything, it doesn't match what Select expects.
Now, as for your actual problem. What you want to do is project each task into a task that does something, then writes to the log when it's done and updates the UI. You can use an async lambda to do this. In an async lambda when there are no return statement it will still be returning a Task (just without a Result) instead of void. And that's exactly what you want to do, project each task into another task.
await Task.WhenAll(list.Select(async a => {
await doSomething(a);
Log("Log Something");
UpdateUI();
}));
The first one is a simple expression, so the type of that expression is used as the return type of the lambda.
From MSDN:
A lambda expression with an expression on the right side of the => operator is called an expression lambda. Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual Basic). An expression lambda returns the result of the expression
(Emphasis mine)
However, what you have is a statement lambda, which means that in order to return a value, you must have a return statement in the lambda body.
Yes, the function you pass to Select() has to return a value, because the purpose of Select is to change one set of values into another set of values. How about this:
Define this method:
private async Task DoSomethingLogAndUpdate(string a)
{
await doSomething(a);
Log("Log Something");
UpdateUI();
}
Then do:
await Task.WhenAll(list.Select(a => DoSomethingLogAndUpdate(a)));
Or to do this without defining a separate method:
await Task.WhenAll(list.Select(async a => {
await doSomething(a);
Log("Log Something");
UpdateUI();
}));

Categories

Resources