I have a pieces of code:
The method is as follows:
public IEnumerable<c> Test(){
var collection = new a();
IEnumerable<c> bs = collection.Where(item => item.Id > 10).Select(item => item);
return from item in collection
where item.Id > 10
select item;
}
(the first two lines compiles fine)
It doesn’t compile and fails with:
Cannot implicitly convert type
System.Collections.Generic.IEnumerable<Stackoverflow.b>toSystem.Collections.Generic.IEnumerable<Stackoverflow.c>
however the code below compiles just fine:
return from item in collection
where item.Id > 10
select new b(null);
since the type of the expression in the select clause is the same I’d expect it to compile in both cases or fail in both.
if I use method syntax instead of query comprehesion and write:
collection.Where(item => item.Id > 10).Select(item => item)
that too compiles
my question is “Is there something wrong with the universe” (is this a compiler bug) or am I missing something?
EDIT
I have no using System.Linq so the normal select and where methods is not in play only those below
The code is part of an academic exercise to try and stretch the pattern-based method overload resolution of LINQ. The signatures are deliberately weird/surprising and the where includes a projection though I believe this would generally be a pretty bad idea.
EDIT
The definitions of the classes in question and the select extension method
public static class Enumerable {
public static IEnumerable<c> Select(this IEnumerable<b> self, Func<b,b> selector){
return null;
}
}
public class a{
public IEnumerable<b> Where(Predicate<a> predicate){
return null;
}
public int Id { get; set; }
}
public class b{
}
public class c{
}
That’s all about query expressions translation. You might want to look at C# Language Specification 4.0 7.16.2 (or 7.15.2 for C# 3.0) for more details, but in short, expressions like:
Are translated just to
so your Enumerable.Select wouldn’t be called and you’ll get IEnumerable<b> as a result instead of IEnumerable<c>. Exactly what compiler is complaining about.