Reputation: 55
I love the Linq syntax and its power, but sometimes I just can't understand why things work as they work.
Like right now. I have the following piece of code:
Regex regex = new Regex( ... );
int result1 = stringList.Count(regex.IsMatch);
IEnumerable<string> result2 = stringList.Where (x => regex.IsMatch (x));
As you can see in the first query I can use the shorter method group 'regex.IsMatch', but in the second query I have to write 'x => regex.IsMatch (x)'.
As Count and Where both take the same argument of type
Func<string, bool>
I can't see why I get a compiler error when I do this:
IEnumerable<string> result2 = stringList.Where (regex.IsMatch);
Upvotes: 4
Views: 170
Reputation: 113472
Essentially, this is an overload resolution issue.
Count
has only one overload that takes two arguments (extended argument + predicate), but Where
has two (one where the predicate considers the item-index, and one that doesn't). To complicate matters, Regex.IsMatch
has multiple overloads of its own.
Now it turns out that the compiler is correct to complain about ambiguity since two of these overloads of IsMatch
are genuinely applicable (each one is compatible with a different overload of Where
):
// Where overload without item-index
Regex.IsMatch(string) is compatible with Where<string>(string, Func<string, bool>)
// Where overload with item-index
Regex.IsMatch(string, int) is compatible with Where<string>(string, Func<string, int, bool>)
...but there can be other related cases involving method-groups (when return-type analysis is required) where the compiler can complain about ambiguity even when there is no ambiguity for a human.
Upvotes: 5