如果我有一个类型的变量,我有四个可用的命名空间IQueryable<T>
扩展方法:Where
Systm.Linq
public static IQueryable<T> Where<T>(this IQueryable<T> source,
Expression<Func<T, bool>> predicate);
public static IQueryable<T> Where<T>(this IQueryable<T> source,
Expression<Func<T, int, bool>> predicate);
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, bool> predicate);
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, int, bool> predicate);
(最后两个因为IQueryable<T>
继承自IEnumerable<T>
。)
如果我使用类型的变量ObjectQuery<T>
(在 namespace 中System.Data.Objects
),我有五个Where
可用的重载,即上面的四个(因为ObjectQuery<T>
实现IQueryable<T>
和IEnumerable<T>
其他接口)以及这个类的实例方法:
public ObjectQuery<T> Where(string predicate,
params ObjectParameter[] parameters);
如果我在使用其中一个时犯了同样的编程错误,IQueryable<T>
或者ObjectQuery<T>
我得到了非常不同的编译器错误。这是一个示例程序(VS2010 SP1中的标准C#控制台应用程序模板+System.Data.Entity.dll
程序集添加到项目引用中,编译器错误在四个示例下面的注释中):
using System.Data.Objects;
using System.Linq;
namespace OverloadTest
{
public class Test
{
public int Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
IQueryable<Test> queryable = null;
ObjectQuery<Test> objectQuery = null;
var query1 = queryable.Where(t => t.Name == "XYZ");
// no definition for "Name" in class OverloadTest.Test
var query2 = queryable.Where(t => bla == blabla);
// "bla", "blabla" do not exist in current context
var query3 = objectQuery.Where(t => t.Name == "XYZ");
// Delegate System.Func<Overload.Test,int,bool>
// does not take 1 argument
var query4 = objectQuery.Where(t => bla == blabla);
// Delegate System.Func<Overload.Test,int,bool>
// does not take 1 argument
}
}
}
“Squiggles”在编译器中看起来也不同:
我理解前两个错误。但是为什么编译器显然想Func<T, int, bool> predicate
在最后两个示例中使用重载号 4(带有 )并且没有告诉我“名称”没有在类中定义Test
并且“bla”和“blabla”不存在在当前情况下?
我曾期望编译器可以安全地排除重载号 5(我不传入 a string
as 参数)和重载号 2 和 4(我不传入带有两个参数的 lambda 表达式(t,i) => ...
),但我的期望没有似乎是正确的。
作为旁注:我在查看这个问题时遇到了这个问题。提问者在那里说问题中的第四个查询无法编译(它在上面的示例 3 和 4 中完全有编译器错误),但是这个查询正是他的问题的解决方案,对我来说似乎有些东西(一个变量或属性名称?)在查询中写错了(虽然他没有确认这一点)但是这个编译器错误并没有给出有用的指示什么是错误的。
编辑
参考下面马丁哈里斯的非常有用的评论:
例如,当我将鼠标悬停在曲线上时query4
,错误“ Delegate System.Func does not take 1 argument ”是工具提示窗口中显示的错误。在编译器输出窗口中实际上按此顺序有四个错误:
- 委托 System.Func 不接受 1 个参数
- “lambda 表达式”无法转换为“字符串”,因为“字符串”不是委托类型
- 当前上下文中不存在名称“bla”
- 当前上下文中不存在名称“blabla”
但是为什么编译器不抱怨前两个使用的示例的第一个错误IQueryable<T>
?