I tried to use linq to get storyboard data in code and try following where clause:
Where(
delegate (abc<VisualStateGroup, VisualState> xyz)
{ return (xyz.state.Name == "PopupOpened");}
)
it gave me error:
An anonymous method expression cannot
be converted to an expression tree
how to write the right where clause for this case?
Use a lambda:
Where(xyz => xyz.state.Name == "PopupOpened");
Just use a lambda expression:
.Where( xyz => xyz.state.Name == "PopupOpened" );
If you don't need the operation as an expression tree, you can also write this as an anonymous delegate, but it would be more verbose.
As #itowlson says, if you are using this in a context where an expression tree is expected, you must supply a lamda, as only lambdas can be converted into expression trees - anonymous delegates cannot.
Related
I'm having a hard time grasping the expression trees. I would like to be able to build an expression tree manually for the following statement:
c => c.Property
A lot of the tutorials focus around comparing, while I just want it to return this one property. Any help?
ParameterExpression parameter = Expression.Parameter(typeof(YourClass), "c");
Expression property = Expression.PropertyOrField(parameter, "Property");
Expression<Func<YourClass, PropertyType>> lamda = Expression.Lambda<Func<YourClass, PropertyType>>(property, parameter);
What does Expression<T> do?
I have seen it used in a method similar to:
private Expression<Func<MyClass,bool>> GetFilter(...)
{
}
Can't you just return the Func<MyClass,bool> ?
Google and SO searches have failed me due to the < and > signs.
If TDelegate represents a delegate type, then Expression<TDelegate> represents a lambda expression that can be converted to a delegate of type TDelegate as an expression tree. This allows you to programatically inspect a lambda expression to extract useful information.
For example, if you have
var query = source.Where(x => x.Name == "Alan Turing");
then x => x.Name == "Alan Turning" can be inspected programatically if it's represented as an expression tree, but not so much if it's thought of as a delegate. This is particularly useful in the case of LINQ providers which will walk the expression tree to convert the lambda expression into a different representation. For example, LINQ to SQL would convert the above expression tree to
SELECT * FROM COMPUTERSCIENTIST WHERE NAME = 'Alan Turing'
It can do that because of the representation of the lambda expression as a tree whose nodes can be walked and inspected.
An Expression allows you to inspect the structure of the code inside of the delegate rather than just storing the delegate itself.
As usual, MSDN is pretty clear on the matter:
MSDN - Expression(TDelegate)
Yes, Func<> can be used in place of place of an Expression. The utility of an expression tree is that it gives remote LINQ providers such as LINQ to SQL the ability to look ahead and see what statements are required to allow the query to function. In other words, to treate code as data.
//run the debugger and float over multBy2. It will be able to tell you that it is an method, but it can't tell you what the implementation is.
Func<int, int> multBy2 = x => 2 * x;
//float over this and it will tell you what the implmentation is, the parameters, the method body and other data
System.Linq.Expressions.Expression<Func<int, int>> expression = x => 2 * x;
In the code above you can compare what data is available via the debugger. I invite you to do this. You will see that Func has very little information available. Try it again with Expressions and you will see a lot of information including the method body and parameters are visible at runtime. This is the real power of Expression Trees.
Does Groovy have any methods (out-of-the-box) that resemble the DefaultIfEmpty or FirstOrDefault methods found in LINQ?
DefaultIfEmpty can be covered by:
def list = []
def defaultIfEmpty = list ?: [ 'was empty' ]
FirstOrDefault is trickier, as I believe it returns the default value for a given type if there is no first element in the list... However, in Groovy (as it stands), there's no way of detecting the default type of the object (unless it is a native type)
You could do:
Integer defaultIfEmpty = list[ 0 ] ?: 0
It should be noticed however that the elvis operator ?: works on Groovy truth, so if the element on the left of the operator evaluates to false in Groovy (whether it be null, an empty list or string, the number 0, etc) it will return the right hand side)
It should also be noted that I am not a .NET expert, so may have the functionality of these two functions incorrect.
Are IEnumerables returned by LINQ methods such as Select or SelectMany "cast-hack" free? For instance, you can return from a function whose output type is IEnumerable an IList, but if you cast it back to IList you will be able to modify it. Does the same happen with IEnumerables returned by LINQ?
Yes. The LINQ methods return special iterator collection classes that wrap the original data source or employ the yield keyword. The reason is deferred execution.
For example:
Select and Where return an instance of the private class WhereSelectEnumerableIterator<TSource, TResult>.
Except and Distinct use the yield keyword to return the elements from the collections that match the condition.
You can use ILSpy to have a look at this code yourself.
I'm sure this is a trivial question but I couldn't find a good example. Suppose all you want to do is change one attribute for all objects in a list. I'd like to say something like:
List<SomeType> list = ...;
list.Select(x => x { x.Name = "Foo" } );
Notice the absence of the "new" keyword. I don't want to recreate objects that already exist, just execute one line of code (in this case a simple assignment) on every element of the list.
Is this possible in linq in some elegant way?
Thanks in advance!
Very easy. MSDN ForEach its actually just a method of the List class, but it allows for you to use Lambda expressions.
list.Foreach(x => x.Name = "Foo" );
It doesn't really fall under Linq if you want to mutate the collection. See Eric Lippert's post to see why.
Try List<T>.ForEach()