Basically, this is shorthand for a method. Where there's a method that takes a delegate, and the delegate defines one incoming parameter, you can put the name of the parameter to pass into the method on the left side of the "=>" symbol, and code representing the return parameter on the right.

So you have, as the signature of your method:

List<T>.FindIndex(Predicate<T> predicate)

When you have a List<Feature>, this turns into:

List<Feature>.FindIndex(Predicate<Feature> predicate).

Predicate<T> is a delegate that takes a parameter of type T, and returns a boolean. So when I write:

FindIndex(f => f.Value == "NoTest")

The compiler recognizes that I want to create, on the fly, a method that takes a parameter of type Feature, and names that parameter "f". On the right side of the arrow, it uses that parameter variable, f, to generate the return parameter. In this case, the return parameter is boolean, and is equal to the evaluation of "f.Value == "NoTest"".

So FindIndex will now roll through each "Feature" object in your list, and test to see if "Value" equals "NoTest". If it does, it returns true, and the FindIndex function will then return the index of the item that matches the value.

To simplify, the following lambda expression is identical to the method immediately below it.

f => f.Value == "NoTest"

bool FindNoTest(Feature f)

{

return f.Value == "NoTest";

}

Because it's a lambda expression, there's no need for a method name, and it kind of takes care of the details for you, including the type of "f" and what is returned.