我有一段代码:
方法如下:
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;
}
(前两行编译好)
它无法编译并失败:
无法隐式将
System.Collections.Generic.IEnumerable<Stackoverflow.b>
类型转换为System.Collections.Generic.IEnumerable<Stackoverflow.c>
但是下面的代码编译得很好:
return from item in collection
where item.Id > 10
select new b(null);
因为select子句中表达式的类型是相同的,我希望它在两种情况下都能编译,或者两者都失败。
如果我使用方法语法而不是查询comprehesion并写:
collection.Where(item => item.Id > 10).Select(item => item)
太编译了
我的问题是“Is there something wrong with the universe”(这是编译器错误)还是我错过了什么?
修改
我没有using System.Linq
所以正常选择和方法不在其中只有下面的那些
该代码是学术练习的一部分,旨在尝试和扩展LINQ基于模式的方法重载解析。签名是刻意的奇怪/令人惊讶的,其中包括一个投影,但我相信这通常是一个非常糟糕的主意。
修改
有问题的类的定义和选择扩展方法
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{
}
答案 0 :(得分:6)
这就是查询表达式的翻译。您可能需要查看C#语言规范4.0 7.16.2(或C#3.0的7.15.2)以获取更多详细信息,但简而言之,表达式如下:
from x in c
where f(x)
select x
仅翻译为
c.Where(x => f(x))
所以你的Enumerable.Select不会被调用,你将获得IEnumerable&lt; b&gt;结果而不是IEnumerable&lt; c&gt;。正是编译器抱怨的是什么。
答案 1 :(得分:1)
正如错误消息所示。
您没有返回与方法签名相同的值。
如果您阅读错误消息,则表示它期望C但是得到B
答案 2 :(得分:0)
尝试
return from item in collection
where item.Id > 10
select (c)item;
似乎所有你缺少的是从b到c的演员阵容。可能是使用.Select扩展方法,编译器可以自动计算出这个转换。我已经看到编译器使用基于返回类型的正确泛型方法。因此,不是说MyItem item = GenericMethod<MyItem>(input)
可以说MyItem item = GenericMethod(input)
而是编译器知道要使用哪种类型。