tags:

views:

148

answers:

5

Here are two C# classes...

public class Address  
{  
    public string Country;  
    public string City;  
}

public class Traveller
{    
    public string Name;
    public List<Address> TravelRoute;
}

... and a list of data (filled somewhere) ...

List<Traveller> Travellers;

... and then this LINQ query:

var result = from t in Travellers
             where t.TravelRoute.Any(a => a.Country == "F")
             select t;

foreach (var t in result)
    System.Console.WriteLine(t.Name);

I do not understand the query: What means the "Any" function and what does the "=>" operator do?

Can someone explain me what's going on in this code? Thanks!

+7  A: 

It selects all travelers whose TravelRoute contains a country that is "F".

The Any functions returns true if any of the objects in the list satisfies the condition that is passed in to the function. From the method signature, you can see it takes a Func<> delegate that returns a bool. This means it takes any method that will return a boolean, including the lambda expression supplied.

This is different from Where, which will filter according to the condition that is passed in.

The => is a lambda expression. In this particular case, it is a shortcut to write an anonymous delegate.

Oded
It's probably worth pointing out that `Any` is a counterpart to `All`; `All` returns true when *every* element of the collection satisfies the condition (essentially a long string of `and` statements) and short-circuits to `false` on a failure, whereas `Any` returns true when *any* elements of the collection satisfies the condition (essentially a long string of `or` statements) and short-circuits to `true` on a pass.
Adam Robinson
I don't think this is expressed correctly. The 'where' keyword selects any object that satisfies the condition, in this case the condition being that there should be at least one TravelRoute for which the predicate returns true. I think it's important to note the difference.
Dave Van den Eynde
Thanks Adam, this explanation of "Any" was quite clear!
Slauma
@Dave Van den Eynde - Thanks for the correction. I updated my answer to reflect the differences.
Oded
A: 

It's a lambda expression. http://msdn.microsoft.com/en-us/library/bb397687.aspx It looks like it's selecting all of the travelers that have any travel route in "F", which is presumably a country.

Eric Mickelsen
A: 

=> is used in C# lambdas.

unwind
A: 

Any is a filter method which says "Accept any items which meet the following criteria." The a => ... business means "Given a parameter a, here's a method" -- as others have said, it's used for lambda expressions. Edit: changed "property" to "parameter"

expedient
How can the compiler know of what type the parameter a is? The type is not specified, there only a. But I even get Intellisense which offers me the Country member. It's nice and correct but hard to understand...
Slauma
Lambda expression are usually cryptic in their syntax, but small and efficient.
David Brunelle
The compiler can often infer type by how you are using it. In this case, the signature for the Any() function requires a parameter of type Func<string,bool>, meaning it wants a function that accepts a string and returns a bool -- a standard filter function. That's how the compiler knows how to treat the lambda, and if you wrote the lambda to return an int, for instance, you'd get a compiler error.
expedient
+1  A: 

The line

a => a.Country == "F"

would translate to something like this if it was a separated LINQ statement:

From a as Adress in t.TravelRoute
Where a.Country = "F"
Select a

The any means it : Any. In other word, it will return true if ANY of the objects in travelRoute has its Country property to "F"

Hope that helps

David Brunelle
So, does it mean that this "lambda expression" is only an abbreviation for another "nested" LINQ query? Only something to write code more compact?
Slauma
Lambda expression, also known as inline expression, are usually written for one-time function and are usually more compact. You don't have to specify a type for the argument as it will deduce it. I'de say yes you can replace it with a nested LINQ, but I don't know LINQ enough to say that writing the LINQ I wrote in another LINQ will work just like that.
David Brunelle
To be more exact, the lambda expression can also translate to an expression tree that is used by the LINQ provider to translate into some other piece of code, like a SQL expression.
Dave Van den Eynde