Explain 2 pairs of parentheses in expression.Compile()() - c#

Could you please explain what this strange code does?
expression.Compile()();
Why are there 2 pairs of parentheses here? I didn't find anything in google. The full method is
public Validator NotEmpty(Expression<Func<IEnumerable<T>>> expression)
{
var member = (MemberExpression)expression.Body;
string propertyName = member.Member.Name;
IEnumerable<T> value = expression.Compile()();
if (value == null || !value.Any())
{
ValidationResult.AddError(propertyName, "Shouldn't be empty");
}
return this;
}
It is used like this:
_validator.NotEmpty(() => request.PersonIds); // request.PersonIds is List<int>
This method checks if a collection is empty or null. Everything works fine but I am a little bit confused with that code. I have never seen using 2 pairs of parentheses before in C#. What does it mean?

Well, you pass list of int into the method as expression tree. This expression produces the value of IEnumerable<T> (in this case IEnumerable<int>).
To get value of expression you need to compile this expression into a delegate Func<IEnumerable<T>> and then invoke the delegate.
In fact, I can write two separate lines of code instead of the shorter syntax used above:
Func<IEnumerable<T>> del = expression.Compile();
IEnumerable<T> value = del();

The two brackets () is actually an operator which invokes a method or delegate. See here.
The expression "expression.Compile()" seems to deliver a delegate that can be invoked. The second pair of brackets then invokes this delegate.
You could also rewrite this as:
var del = expression.Compile();
del();

Related

How to detect actual type of an expression result? [duplicate]

I have a method that accepts a Expression<Func<T, object>> instance. I want to get at the actual data type being returned by a specific expression instance, rather than object.
I can get it to work for direct property references, so if I pass in the expression x => x.IntegerProperty I can get a Type reference for an integer. This approach requires converting it to a MemberExpression.
However, I can't get it to work for arbitrary expressions. For instance, if the expression is x => x.IntegerProperty.ToString() I want to get a Type reference for a string. I can't compile this to a MemberExpression, and if I just .Compile() it and check the return type I get "object".
How can I look at the specific expression instance and derive the actual return type?
Something like this might do the trick. It probably doesn't cover every possibility, but it's a start.
public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
if ((expr.Body.NodeType == ExpressionType.Convert) ||
(expr.Body.NodeType == ExpressionType.ConvertChecked))
{
var unary = expr.Body as UnaryExpression;
if (unary != null)
return unary.Operand.Type;
}
return expr.Body.Type;
}
While not impossible, this is particularly difficult. It would require walking the expression tree and doing some potentially complex logic. For example, what would you want to see if I passed in the following expression?
Func<bool, object> expr = switch => switch ? 1 : "False";
This method could either return an int or a string.
Now, you might be able to make more headway by offloading some of this logic on the compiler. You could change your method parameter from Func<T, object> to Func<T, TReturn> and use typeof(TReturn) within the method to determine what the compiler decided the return type of the expression was.
Of course, in the case of my example, you'll still be working against object. But, your example of x => x.IntegerProperty.ToString() will yield string, which is what you're looking for.
Bit of a cheeky way (and it involves actually invoking the Func), but you can do this:
using System;
class Program
{
static Func<T,object> MakeFunc<T>()
{
return x => 23;
}
static Type GetReturnType<T>(Func<T,object> f)
{
return f(default(T)).GetType();
}
static void Main(string[] args)
{
Type t = GetReturnType(MakeFunc<string>());
Console.WriteLine(t);
}
}
It's not guaranteed to work in all situations, I should add - particularly if the default(T) isn't a valid parameter to the Func. But it's a potential starting point at least.

Lambda Expression definition (pedant )?

By just briefing a book (leading one) , one thing caught my eyes - the lambda expression definition :
A lambda expression is an unnamed method written in place of a
delegate instance.
in place of delegate instance ???
A delegate instance is an object that refers-to/encapsulate target method/s :
In the following sample The right side(where the lambda expression would be) is not a delegate instance. it is a method.
TransformerDelegate t = SquareMethod;
So the definition should have been corrected-to/mention :
lambda expression are unnamed method written in place of a method(!)
being referenced by delegate variable.
TransformerDelegate sqr = x => x * x;
^
|
---------------+
|
this is the location for method/anonymous methods.
do you see what I mean ? Am I right?
p.s. I did understand the msdn's one : ( but want to see if the book had made a mistake)
A lambda expression is an anonymous function that can contain
expressions and statements, and can be used to create delegates or
expression tree types.
The value of a lambda expression is a delegate instance.
So the book is probably referring to code like:
MySquareDelegate f1 = x => x * x;
MySquareDelegate f2 = new MySquareDelegate(MySquareMethod);
MySquareDelegate f3 = MySquareMethod; // just shorthand for the previous line
It is tricky stuff to explain in 1 sentence, your own version
lambda expression are unnamed method written in place of a method(!) being referenced by delegate variable.
is talking about "a method instead of a method", the original about "a method instead of a delegate instance" where the method is implicitly converted to a delegate instance. Both seem incomplete at least.
A definition of a lambda should also include that it is an inline method.
Other answers miss the fact that lambda expressions do not necessarily represent methods. Sometimes, they represent expression trees.
The compiler implicitly converts lambda expressions to one type of object or the other, depending on context.
To specify a method, you need to specify parameters and a body. In a lambda expression, these are separated by =>. Examples:
() => 4; //empty parameter list
x => x.ToString(); //one parameter
(a, b) => a.Equals(b); //two parameters
// ^^^^^^ ^^^^^^^^^^^^
// | |
// parameter list body
These lambda expressions can be converted to Func<int>, Func<object, string>, and Func<object, object, bool> respectively. The could also be converted to Expression<Func<int>>, Expression<Func<object, string>>, and Expression<Func<object, object, bool>> respectively.
An anonymous method:
delegate (object p, object q) { return string.Concat(p, q); }
// ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// parameter list body
Here are two examples of lambda conversion:
Func<object, object, bool> aDelegate = (o1, o2) => object.Equals(o1, o2);
Expression<Func<object, object, bool>> anExpressionTree = (o1, o2) => object.Equals(o1, o2);
In method group conversion, the parameters and method body are specified by overload resolution. To simplify a bit, the compiler looks at the methods with the indicated name and chooses the correct overload based on the context. For example, consider these overloads of SquareMethod:
int SquareMethod(int a) { return a * a; }
double SquareMethod(double a) { return a * a; }
These statements involve method group conversion and overload resolution:
Func<int, int> squareAnInt = SquareMethod;
Func<double, double> squareADouble = SquareMethod;
Finally, statement lambdas cannot be translated to expression trees:
Action<object> anAction = o => { Console.WriteLine(o); };
Func<object, int> aFunc = o =>
{
var s = (o ?? "").ToString();
Console.WriteLine(s);
return s.Length;
};
The C# language specification (somewhat confusingly) uses the term "anonymous function" to cover both lambda expressions and anonymous methods. Anonymous functions can be implicitly converted to a compatible delegate type, and so can method groups. Therefore, if we have a delegate type called DelegateType, and a declaration/assignment like this:
DelegateType d = [something];
Then [something] can be a method group or an anonymous function. In other words, it can be a method group, an anonymous method or a lambda expression.
So, your correction to the book's text would be better to say "in place of a method group", but I would say
A lambda expression is an unnamed method that, like a named method group, can be used to create a delegate instance.
I might also add
In some cases, a lambda expression can be used to create an expression tree rather than a delegate instance.
Basically a delegate is nothing but an object that knows how to call a specific method. So a delegate instance literally acts as a delegate for the caller: the caller invokes the delegate, and then the delegate calls the target method.

what is the use of ()=> in silverllight

Can you say what is the use of the ()=> and =>? I saw this in a code. I did not get any reference for this.
this.Dispatcher.BeginInvoke(()=>
{
//some thing..
};
=> is the lambda operator in C# and is read as "goes to". A lambda expression is an anonymous function and can be used to create a delegate.
Your example takes no arguments as indicated by the empty parens preceding the lambda operator. A lambda expression with one argument might look like this:
n => n.toString()
That expression would return the string representation of n, when invoked. A lambda expression can have multiple arguments as well, contained in parentheses:
(n, f) => n.toString(f)
A common use would be in a Func<T>:
Func<int, string> getString = n => n.toString();
int num = 7;
string numString = getString(num);
This is, of course, a silly example, but hopefully helps to illustrate its use.
This notation is that of a lambda expression which takes no argument. If the lambda expression made use of arguments they would be declared in the empty set of parenthesis as in say...
this.Dispatcher.BeginInvoke((x, y) => { do some' with x and/or y }, 12, somevar);
In a nutshell, lambda expressions allows creating "nameless" functions, right where they are needed.
In the example of the question, the BeginInvoke() method requires its first parameter to be a delegate (a "pointer to a method"), which is exactly what this lambda expression provides.
It's a lambda expression that has no parameters.
Check out this page http://codebetter.com/karlseguin/2008/11/27/back-to-basics-delegates-anonymous-methods-and-lambda-expressions/
If you don’t have any parameters, like in our example, you use empty
paranthesis:
() => {…}

Expression trees - different compiler behaviour for Action<T> in C# and VB.NET

Given a simple piece of code which can return the name of a property in VB.NET:
Function NameForProperty(Of T)(ByVal field As Expression(Of Action(Of T))) As String
Dim expression = DirectCast(field.Body, MemberExpression)
Return expression.Member.Name
End Function
Which works like this:
NameForProperty(Of String)(Function (s) s.Length) ' ==> returns "Length"
And what I thought would have been the equivalent in C#:
string NameForProperty<T>(Expression<Action<T>> field)
{
var expression = (MemberExpression)field.Body;
return expression.Member.Name;
}
When I try to call the C# version:
NameForProperty<string>(s=>s.Length);
It returns a compiler error:
Only assignment, call, increment, decrement, and new object
expressions can be used as a statement
My question is: what is the difference between the two pieces of code?
EDIT
Ivan has provided an answer as to why the code does not work in C#. I am still curious as to why it does work in VB.NET.
EDIT#2
To be clear, I'm not looking for code which works -- simply why the code would work in VB.NET and not C#.
public static class TypeMember<TClass>
{
public static string PropertyName<TProp>(Expression<Func<TClass, TProp>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
throw new ArgumentException("'expression' should be a property expression");
return body.Member.Name;
}
}
var propName = TypeMember<string>.PropertyName(s => s.Length);
The problem with your version lies in the fact that you're trying to use Action<T>. It returns nothing and thus lambda's body (s.Length) should be a statement. And it is not a statement actually. So compiler complains about it.
It would complain in the same way if you'd wrote
public void A()
{
string s = "abc";
s.Length;
}
It is the same thing.
I'm not an expert in VB.NET though, so I can't explain why it is working in VB, sorry.
I would try changing the method to Func instead of Action.
Your statement is not valid as the error says. If you change the Action to Func it's ok, because Length is the return value.
Maybe the VB compiler has other checks / requirements.

What is actually happening with IQueryable.Where()?

This is is returning a boolean based on whether or not there are some matching IDs.
from t in getAll
select new Result
{
...
bool DetailsAvailable =
(db.SaveTrackings.Where(s => s.BundleID == t.bundleID
&& s.UserID == t.userID)
.Count() > 0) ? true : false;
}
This is what I think understand: .Where() is returning all the entries with the matching IDs and then the .Count() is just seeing how many are there. I only feel like I half understand what we need s for.
I know what to expect from this code since it's been in use I just don't understand how it works and some of the documentation from MSDN is using some terminology that is confusing me.
All lambda expressions use the lambda
operator =>, which is read as "goes
to". The left side of the lambda
operator specifies the input
parameters (if any) and the right side
holds the expression or statement
block. The lambda expression x => x *
x is read "x goes to x times x."
So how am I suppose to understand what my code means based on this, .Where(s "goes to" s.BundleID == t.BundleID...) so what's happening here? What does "goes to" mean? Is it comparing every ID in s to everyone one available in t? How do I understand why it's called "goes to" and what exactly is happening?
And then it gets more confusing...
The => operator has the same
precedence as assignment (=) and is
right-associative.
Lambdas are used in method-based LINQ
queries as arguments to standard query
operator methods such as Where.
When you use method-based syntax to
call the Where method in the
Enumerable class (as you do in LINQ to
Objects and LINQ to XML) the parameter
is a delegate type System.Func. A lambda expression is the
most convenient way to create that
delegate.
What is a delegate type System.Func<T, TResult> and how is it created with this "goes to" operator?
I can't just use code because I know that it's working, I need to understand how/why.
Maybe it would help to see this function implemented by hand:
using System;
using System.Collections.Generic;
namespace CSharpSandbox
{
class Program
{
static IEnumerable<T> Where<T>(IEnumerable<T> input, Func<T, bool> predicate)
{
foreach (T item in input)
{
if (predicate(item))
yield return item;
}
}
static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> evens = Where(numbers, n => n % 2 == 0);
foreach (int even in evens)
{
Console.WriteLine(even);
}
}
}
}
The construct name => someEvaluation creates an anonymous function consisting of the following parts:
name is simply the name of a parameter, its type is inferred from its usage. You need a name so you can refer to the argument passed in the function.
=> is the start of your anonymous functions body, the scope of the body is a single expression.
someEvaluation is the body of your anonymous function composed of a single expression.
In our case, Func<T, bool> defines a function which takes a single parameter of type T and returns an output of type bool. (If we had used Func<T, U, bool>, we'd take two inputs of type T and U and return a bool. The last type parameter in the Func definition is the return value.)
You can invoke an instance of Func exactly as you invoke any other function. If the func takes params, you pass them in as expected, your parameters are bound to the variable names you defined. When you invoke the function, control flow will jump inside your function and evaluate its results.
In principle, you don't need to create a Func anonymously. You can pass in any function which has a compatible type signature, such as:
static bool IsEven(int n)
{
return n % 2 == 0;
}
static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> evens = Where(numbers, IsEven);
foreach (int even in evens)
{
Console.WriteLine(even);
}
}
This program produces the same output. In fact, behind the scenes, the syntax name => expression is syntax sugar; when it gets compiled, C# will produce a produce a private function with a hidden name and convert it to the format above.
If it helps, think of s as a variable of type SaveTracking. It's iterating over each s in your collection/table, and testing the value of its BundleID.
The t is same idea - it's like it's iterating through all the return collection from the getAll.
It's like the SQL pseudocode:
SELECT * FROM SaveTracking INNER JOIN GetAll
ON BundleID AND UserID
For a deeper technical description of what's going on with lambda expressions, check out Jon Skeet's book C# In Depth. Chapter 9 , p 230. I found this book very helpful.
Lambda expressions are just a way to shorten the code but it does exactly the same things as declaring a method that corresponds to the delegate type System.Func<T, TResult>
I believe that C# converts your lamba to a method in the background when you compile and it looks like this :
bool LambdaExpression(YourType s)
{
return s.BundleID == t.bundleID && s.UserID == t.userID;
}

Categories

Resources