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>
, whereD
is any delegate type.
Source: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types#expression-tree-types
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