Why does the following fail to infer R:
static R Foo<R>(Func<Action<R>, R> call) { ... }
While pretty much the 'same', works:
static R Foo<R>(Func<Action, R> call) { ... }
Usage:
var i = Foo(ec => -1);
Ways the first sample 'must' be called to compile:
var i = Foo<int>(ec => -1);
-- or --
var i = Foo((Action<int> ec) => -1);
Thoughts: As can be seen in the second snippet, R is already determined by the return type of the 'lambda'. Why can't the same apply to the first? Even with usage of ec (which should be another compiler hint), it fails to infer.
I think that the problem is not that the compiler if failing to infer R for the function CallWithEscapeContinuation, it is that it is failing to infer a type for the lambda:
ec =>
{
Enumerable.Range(0, 100).Select(x =>
{
// Called here, the compiler has no idea what signature to expect for `ec`
// Could be Action<Int>, could be Action<Decimal> (for example).
if (x == 40) ec(x);
return x;
}).ToList();
return -1;
}
Whereas when you provide the int hint, it can infer what type the lambda is from that and the signature of CallWithEscapeContinuation.
When you just have Action (as opposed to Action<R>) the above is irrelevant because there are no type parameters affecting the possible signatures of the lambda.
Related
This question already has answers here:
Understanding how lambda expression works [closed]
(4 answers)
Closed 3 years ago.
[Route("{year:min(2000)}/{month:range(1,12)}/{key}")]
public IActionResult Post(int year, int month, string key)
{
var post = _db.Posts.FirstOrDefault(x => x.Key == key);
return View(post);
}
Hi,
I'm doing this in ASP.NET Core with C#.
Vague part for me is this: _db.Posts.FirstOrDefault(x => x.Key == key);
So what I'm guessing is that:
execute FirstOrDefault method.
parameter x is passed (I don't what it is being passed exactly though).
then, compare x.Key with key
what is next step?
parameter x is passed (I don't what it is being passed exactly though).
No, this does not happen. What is passed is an expression defining an anonymous function. Such expressions, when using the => operator, are commonly called lambda expressions. x is the part of the expression which determines how the function is called. It's a placeholder for the input variable used by the function expression.
It will help you understand if I give you a pretend version of how the FirstOrDefault() method might be implemented:
public T FirstOrDefault<T>(this IEnumerable<T> items, Func<T, boolean> predicate)
{
foreach(T item in items)
{
if(predicate(item)) return item;
}
return default(T);
}
Some things to understand in that code:
this in front of the first parameter turns the function into an extension method. Instead of calling the method with two arguments, you skip the first argument... call it with only the second argument as if it were a member of the type from the first argument. ie, _db.Posts.FirstOrDefault(foo) instead of FirstOrDefault(_db.Posts, foo).
The key variable in the expression is called a closure. It is available as part of the predicate() function inside this method, even though it's not passed as an argument. This is why the predicate(item) call is able to determine true or false with only item as an input.
The predicate() function call within this method was passed as an argument to the method. That is how the x => x.Key == key argument is interpreted; it becomes the predicate() method used by the FirstOrDefault() function. You can think of it as if predicate() were defined like this:
bool predicate(T x)
{
return x.Key == key;
}
The C# compiler makes this translation for you automatically, and even infers the correct run-time type for T and automatically handles scope for the key closure.
The other answers are close, but not completely correct.
I assume that _db is an Entity Framework DbContext, and _db.Posts is a DbSet<Post>.
As such the .FirstOrDefault() method you are seeing is actually an Extension method and the x => x.Key == key part is an Expression tree.
What happens behind the scenes is that the call to _db.Posts.FirstOrDefault(x => x.Key == key) is translated to a SQL statement like SELECT TOP(1) Key, Content, ... FROM posts WHERE Key = #key, the result of which is mapped into a Post entity.
There are a lot of language features at play to make all this work, so let's have a look!
Extension methods
Extension methods are static methods, but can be called like instance methods.
They are defined in static classes and have a 'receiver' argument. In the case of FirstOrDefault the extension method looks like this:
public static class Queryable {
public static T FirstOrDefault<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate = null) {
// do something with source and predicate and return something as a result
}
}
It's usage _db.Posts.FirstOrDefault(...) is actually syntactic sugar and will be translated by the C# compiler to a static method call a la Queryable.FirstOrDefault(_db.Posts, ...).
Note that extension methods are, despite the syntactic sugar, still static methods do not have have access to their receiver's internal state. They can only access public members.
Delegates
C# has support for pseudo-first-class functions, called delegates. There are several ways to instantiate a delegate.
They can be used to capture existing methods or they can be initialized with an anonymous function.
The most elegant way to initialize a delegate with an anonymous function is to use lambda style functions like x => x + 10 or (x, y) => x + y.
The reason you don't see type annotations in these examples is that the compiler can infer the types of the arguments in many common situations.
Here is another example:
// This is a normal function
bool IsEven(int x) {
return x % 2 == 0;
}
// This is an anonymous function captured in a delegate of type `Func<T1, TResult>`
Func<int, bool> isEven = x => x % 2 == 0;
// You can also capture methods in delegates
Func<int, bool> isEven = IsEven;
// Methods can be called
int a = IsEven(5); // result is false
// Delegates can be called as well
int b = isEven(4); // result is true
// The power of delegates comes from being able to pass them around as arguments
List<int> Filter(IEnumerable<int> array, Func<int, bool> predicate) {
var result = new List<int>();
foreach (var n in array) {
if (predicate(n)) {
result.Add(n);
}
}
return result;
}
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var evenNumbers = Filter(numbers, isEven); // result is a list of { 2, 4, 6 }
var numbersGt4 = Filter(numbers, x => x > 4); // result is a list of { 5, 6 }
Expression trees
The C# compiler has a feature that allows you to create an Expression tree with normal-looking code.
For example Expression<Func<int, int>> add10Expr = (x => x + 10); will initialize add10Expr not with an actual function but with an expression tree, which is an object graph.
Initialized by hand it would look like this:
Expression xParameter = Expression.Parameter(typeof(int), "x");
Expression<Func<int, int>> add10Expr =
Expression.Lambda<Func<int, int>>(
Expression.Add(
xParameter,
Expression.Constant(10)
),
xParameter
);
(which is super cumbersome)
The power of expression trees comes from being able to create, inspect and transform them at runtime.
Which is what Entity Framework does: it translates these C# expression trees to SQL code.
Entity Framework
With all of these features together you can write predicates and other code in C# which gets translated by Entity Framework to SQL, the results of which are "materialized" as normal C# objects.
You can write complex queries to the database all within the comfort of C#.
And best of all, your code is statically typed.
The x is the range variable of the object you called the function on. The same object you would get in foreach (var x in _db.Posts) It then iterates through that collection looking for x.Key == key and returns the first object that fulfills that. So that function will return the first object in db.Posts where Key == key
edit: corrected term
Your lambda expression with FirstOrDefault is equivalent to the following extension method
public static Post FirstOrDefault(this YourDBType _db, string Key)
{
foreach(Post x in _db.Posts)
{
if(x.Key == Key)
{
return x
}
}
return null
}
X isn't an parameter, its just a shorthand way of referring to the individual item in the collection you are working on like we would have in a foreach statement. The last step in your question is "either return the first Post that has the same key we are comparing against, or return the default value of a Post object (which is null for objects)"
TLDR: How does this compile?
class A{};
Expression<Func<A, int>> e = x => 24; // I don't understant what makes this compile
// and what happens at this assignment
What is the minimum class E to be able to compile E e = x => 24;
Some investigation
class E {};
E e = x => 24;
Visual Studio error is "Cannot convert lambda expression to type 'E' because it is not a delegate type" which is confusing because as far as I know a delegate is declared like this:
int delegate MyHandle();
and I didn't find any way of making a class a delegate.
Furthermore I have looked at the metadata of Expression -> LambdaExpression -> Expression<TDelegate> and wasn't able to identify what syntax/declaration makes Expression<TDelegate> act like a delegate.
Even more I have tried to create my own class E to mimic Expression<TDelegate> and I wasn't even able to compile the class
// basically a copy-paste of the metadata of `Expression<TDelegate>`
public sealed class E<TDelegate> : LambdaExpression
{
public TDelegate Compile() => default(TDelegate);
public TDelegate Compile(DebugInfoGenerator debugInfoGenerator) => default(TDelegate);
public TDelegate Compile(bool preferInterpretation) => default(TDelegate);
public Expression Update(Expression body, IEnumerable<ParameterExpression> parameters)
=> default(Expression);
protected override Expression Accept(ExpressionVisitor visitor) => null;
}
getting the error "'LambdaExpression' does not contain a constructor that takes 0 arguments"
Context (can be skipped):
I am getting started with Moq and because I just cannot take things for granted I am trying to understand how it works / how it is implemented. So this the first part of a series of inquiries about that.
I am now specifically trying to understand
public class A
{
public virtual int Foo() => throw new NotImplementedException();
public virtual int Bar() => throw new NotImplementedException();
}
var a = new Mock<A>();
a.Setup(x => x.Foo()).Returns(24); // ??
Console.WriteLine(a.Object.Foo());
I am trying to understand how the information "the method Foo" is passed to a
by passing that lambda? As far as I know a lambda is just a callable object, but somehow magically a knows the actual body of the lambda, i.e. will throw if you pass x => 24 or x => x.Foo() + x.Bar() but will accept x => x.Foo()
And I see that Setup parameter is of type Expression<Func<A, int>> hence my current question.
The C# specification gives special treatment to System.Linq.Expressions.Expression<D>; you cannot get the same treatment for your own type.
Expression trees permit lambda expressions to be represented as data structures instead of executable code. Expression trees are values of expression tree types of the form System.Linq.Expressions.Expression<D>, where D is any delegate type.
Source: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types#expression-tree-types
This is a Lambda expression:
x => 24
According to MSDN Lambda expressions a lambda expression can be used to create a delegate or an expression tree type.
A Func<T, int> is a delegate function that takes a T as input and returns an int as output. If you assign the lambda expression above to this Func, then the compiler assumes that the x in the lambda expression is the input of the Func, and the part after the => is the output of the Func:
Func<string, int> func = x => x.Length;
Here x is expected to be a string, the part after the => may use, but is not obliged to use, this x to produce the output which has to be an int.
Func<int, int> func = x => x = -x;
Here x is expected to be an int. The return of the function is -x which is also an int.
Expression is the base class of all kinds of expressions. Expressions represent an operation that return a value. The most basic expressions are constants, they represent just a constant value, like 24. Other expressions might be additions, which take as input two expressions and have one output value. Other expressions are multiplication, negation, etc, which return a "number", or boolean expressions like AND OR NOR etc which return a Boolean.
A special kind of expression (so a derived class) is a LambdaExpression. A LambdaExpression usually represents a function-like object: it has zero or more input parameters and one output parameter. You assign a value to a LambdaExpression using a lambda expression (note the space in lambda expression!):
Expression<Func<string, int>> myExpression = x => x.Length;
I wrote earlier what the lambda expression x => x.Length does. the statement above creates an object of type System.Linq.Expressions.Expression<TDelegate>, which is of type LambdaExpression, hence you can assign it to an Expression<Func<string, int>>.
Your question:
What is the minimum class E to be able to compile E e = x => 24?
Your class E will need a constructor (or assignment operator) that accepts a System.Linq.Expressions.Expression<Func<MyClass, int> as parameter. If you don't use the x from your lambda expression MyClass can be object
Of course it is also accepted if the constructor takes any of the base classes, like Expression. However, if you do so you won't be able to used any of the Expression<Func<MyClass, int> functionality.
About your Mock code
Apparently you have a class A with two functions Foo and Bar, and you want to instantiate a Mock object to mock the functionality of A.
var myAmock = new Mock<A>();
myAmock.Setup(x => x.Foo()).Returns(24);
This says, that myAmock is an object that should mock behaviour of class A. Whenever someone calls the Foo function it should return a value of 24.
I've searched a bit about type inference, but I can't seem to apply any of the solutions to my particular problem.
I'm doing a lot of work with building and passing around functions. This seems to me like it should be able to infer the int type. The only thing I can think of is that the lambda return type isn't checked by the type inference algorithm. I have stripped unnecessary logic to show the issue more clearly.
Func<T> Test<T>(Func<Func<T>> func)
{
return func();
}
this compiles:
Func<int> x = Test<int>(() =>
{
int i = 0;
return () => i;
});
but this gives the error "The type arguments for method cannot be inferred from the usage. Try specifying the type arguments explicitly":
Func<int> x = Test(() =>
{
int i = 0;
return () => i;
});
I guess I would just like to know why it works this way and any workarounds.
I would say that the correct answer to the question is given by E.Lippert in SO Why can't an anonymous method be assigned to var?
But let us play with your example a little:
Func<Func<int>> f = () =>
{
int i = 0;
return () => i;
};
Func<int> x = Test(f); //it compiles OK
No problem in type inference with your Func<T> Test<T>(Func<Func<T>> func) here.
The problem is hidden in that you use an anonymous lambda expression, the type of which cannot be inferred. Try this:
var f = () =>
{
int i = 0;
return () => i;
};
It gives Compiler Error CS0815, saying
Cannot assign lambda expression to an implicitly-typed local variable
and the explanation is:
An expression that is used as the initializer for an implicitly typed
variable must have a type. Because anonymous function expressions,
method group expressions, and the null literal expression do not have
a type, they are not appropriate initializers. An implicitly typed
variable cannot be initialized with a null value in its declaration,
although it can later be assigned a value of null.
Now let's try another thing:
var x = Test(() =>
{
Func<int> f = () => 0;
return f;
});
It compiles as well. So the problem with your original example was actually with this line:
return () => i;
We can go further and according to what Eric Lippert says in his answer provide another function to wrap this:
static Func<T> GetFunc<T>(Func<T> f) { return f; }
Now we can rewrite your code like:
var x = Test(() =>
{
int i = 0;
return GetFunc(() => i);
});
And it works as well.
However, as far as I understand, this all is an overhead and you should just provide an explicit type. While these workarounds are suitable, when you need to have a lambda, returning an object of anonymous type.
I have seen that is is possible to add compiled methods together.
Expression<Func<Customer, bool>> ln = c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fn = c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fdob = c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));
var filter = ln.Compile() + fn.Compile() + fdob.Compile();
Does it make sense to do this?
I would intend to use the filter in place of a lambda expression to filter a repository of customers:
IEnumerable<Customer> customersFound = _repo.Customers.Where(filter);
Depending on business logic, I may or may not add the three compiled methods together, but pick and choose, and possibly add more compiled methods as I go.
Can anyone explain if adding them together would build up a query string or not? Anyone got a better suggestion?
I could chain "Where" statements and use regular lambda expressions, but I am intrigued by what you might gain from compiling methods and adding them up!
That's a side-effect of the fact that the Compile method returns a delegate.
Internally, a delegate is a multicast-delegate, it can involve multiple chained references to methods.
The + is in this case just a quick way to chain them together. You can read more about combining delegates in the How to: Combine Delegates on MSDN.
Here's a LINQPad program that demonstrates:
void Main()
{
var filter = GetX() + GetY() + GetZ();
filter().Dump();
}
public int X() { Debug.WriteLine("X()"); return 1; }
public int Y() { Debug.WriteLine("Y()"); return 2; }
public int Z() { Debug.WriteLine("Z()"); return 3; }
public Func<int> GetX() { return X; }
public Func<int> GetY() { return Y; }
public Func<int> GetZ() { return Z; }
Output:
X()
Y()
Z()
3
Note that it thus seems to just disregard the return value from the first method calls, and returns only the last, although it fully calls the prior methods as well.
Note that the above code is similar to this:
void Main()
{
Func<int> x = X;
Func<int> y = Y;
Func<int> z = Z;
var filter = x + y + z;
filter().Dump();
}
public int X() { Debug.WriteLine("X()"); return 1; }
public int Y() { Debug.WriteLine("Y()"); return 2; }
public int Z() { Debug.WriteLine("Z()"); return 3; }
The short answer is thus that no, this does not do what you want it to do.
When you call Compile(), you are creating instances of type Func<Customer, bool>, which is a delegate.
Delegates overload the operator+ to return Multicast Delegates, which is what is happening here.
See MSDN: How to: Combine Delegates (Multicast Delegates)
So, no - adding them together would not build up a query string.
If this is for EF, you want to use Expression Trees, not Lambdas.
You can create and modify Expression Trees using the System.Linq.Expressions namespace:
MSDN: System.Linq.Expressions Namespace
and
MSDN: How to: Use Expression Trees to Build Dynamic Queries
It is a creative effort to chain predicates and too bad it does not work. The reason why has been explained excellently by Lasse and Nicholas (+2). But you also ask:
Anyone got a better suggestion?
The drawback of compiled expressions is that they're not expressions any more and thus, can't be used with IQueryables that are backed by SQL query providers (like linq to sql or linq to entities). I assume _repo.Customers is such an IQueryable.
If you want to chain expressions dynamically, LINQKit's PredicateBuilder is an excellent tool to do this.
var pred = Predicate.True<Customer>();
pred = pred.And(c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));
var customersFound = _repo.Customers.Where(pred.Expand());
This is what the Expand is for:
Entity Framework's query processing pipeline cannot handle invocation expressions, which is why you need to call AsExpandable on the first object in the query. By calling AsExpandable, you activate LINQKit's expression visitor class which substitutes invocation expressions with simpler constructs that Entity Framework can understand.
Or: without it an expression is Invoked, which causes an exception in EF:
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
BTW. If you use linq to sql/entities you may as well use c.lastname == _customer.lastName because it is translated into SQL and the database collation will determine case sensitiveness.
Using AutoMapper, I hit a place where a named argument would've fit very nicely:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false)))
But the compiler yelled at me:
An expression tree may not contain a named argument specification
So I had to revert to:
.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false)))
Does anyone know why the compiler disallows named arguments in this situation?
Consider the following:
static int M() { Console.Write("M"); return 1; }
static int N() { Console.Write("N"); return 2; }
static int Q(int m, int n) { return m + n; }
...
Func<int> f = ()=>Q(n : N(), m: M());
Expression<Func<int>> x = ()=>Q(n : N(), m: M());
Func<int> fx = x.Compile();
Console.WriteLine(f());
Console.WriteLine(fx());
You agree I hope that the last two lines must do exactly the same thing, right? Which is to print NM3.
Now, what expression tree library calls would you like the expression tree conversion to generate that ensure this? There are none! We are therefore faced with the following choices:
Implement the feature in the expression tree library. Add a transformation in the expression tree lowering engine that preserves the order of execution of the named arguments. Implement code in the Compile method that takes the execution order into account.
Make x = ()=>Q(n : N(), m: M()); actually be implemented as x = ()=>Q(M(), N()); and be incompatible with the non-expression-tree version.
Disallow named arguments in expression trees. Implement an error message to that effect.
(1) is nice, but expensive. (2) is a non-starter; we can't in good conscience introduce this kind of "gotcha". (3) is cheap but irritating.
We chose (3).