While coding this morning, I needed to quickly find an entity object in an array, so I used the generic List's Find method.
Entity match = new List<Entity>(someEntityArray).Find(
delegate(Entity test) { return test.Id = someId; } );
Later, when I tried to build, I was getting a very unhelpful compiler errors.
error CS1502: The best overloaded method match for 'System.Collections.Generic.List.Find(System.Predicate)' has some invalid arguments
and
error CS1503: Argument '1': cannot convert from 'anonymous method' to 'System.Predicate'
These errors didn't make sense to me, but I tried creating a Predicate
object, then passing that into the Find method by moving some code around.
Predicate<Entity> pred = delegate(Entity test) { return test.Id = someId; };
Entity match = new List<Entity>(someEntityArray).Find(pred);At this point, I'm getting the compile errors
error CS1662: Cannot convert anonymous method block to delegate type 'System.Predicate' because some of the return types in the block are not implicitly convertible to the delegate return type
and
error CS0029: Cannot implicitly convert type 'long' to 'bool'
"Ah, now we're getting somewhere," I thought to myself, "but why would the anonymous method be converting long to bool? D'oh!"
I bet a good portion of other developers reading this blog (assuming anyone does) probably noticed the problem at once. The old single equals sign instead of double equals sign in a comparison. Going back to my original code and adding an equals sign compiles fine.
Entity match = new List<Entity>(someEntityArray).Find(
delegate(Entity test) { return test.Id == someId; } );
This all got me wondering why the compile error was so far off. I did a quick google for the original error message and came across
this blog post where Avner Kashtan had a similar problem and he ended up getting
feedback from Microsoft that this is the correct behavior, although misleading, and things should be improved with lambda expressions.
Labels: c#