C# Linq'的设计原因是什么;s扩展方法不接受true System.谓词?
我在编程时注意到了一些东西。我决定不使用Exists()和Find()这样的谓词:C# Linq'的设计原因是什么;s扩展方法不接受true System.谓词?,c#,linq,predicate,C#,Linq,Predicate,我在编程时注意到了一些东西。我决定不使用Exists()和Find()这样的谓词: 谓词pred=cov=>cov.EmployeeId==EmployeeId; 如果(EmployeeCoverage终止存在(pred)) { var foundCoverage=EmployeeCoverageTerminated.Find(pred); } 我尝试使用FirstOrDefault作为替换,并尝试传入谓词,但意识到它不起作用 //does not work
谓词pred=cov=>cov.EmployeeId==EmployeeId;
如果(EmployeeCoverage终止存在(pred))
{
var foundCoverage=EmployeeCoverageTerminated.Find(pred);
}
我尝试使用FirstOrDefault作为替换,并尝试传入谓词,但意识到它不起作用
//does not work
Predicate<dynamic> pred = cov => cov.EmployeeId == EmployeeId;
var foundCovarage = EmployeeCoverageCurrent.FirstOrDefault(pred);
//works fine
var foundCoverage = EmployeeCoverageCurrent.FirstOrDefault(cov => cov.EmployeeId == EmployeeId);
//also works fine
Func<dynamic, bool> func = cov => cov.EmployeeId == EmployeeId;
var foundCoverage = EmployeeCoverageCurrent.FirstOrDefault(func);
//不起作用
谓词pred=cov=>cov.EmployeeId==EmployeeId;
var foundCovarage=员工覆盖率current.FirstOrDefault(pred);
//很好
var foundCoverage=employeecoverage current.FirstOrDefault(cov=>cov.EmployeeId==EmployeeId);
//也很好用
Func Func=cov=>cov.EmployeeId==EmployeeId;
var foundCoverage=EmployeeCoverage当前.FirstOrDefault(func);
我不禁要问,为什么它的设计需要一个
当Find()和Exists()都可以使用谓词时,Func
而不是Predicate
。我的意思是,即使参数输入名也被称为谓词
我能想到的唯一一件事是,它们作为和单独实现,是列表的一部分,而它们是Linq扩展方法的一部分
我猜这个想法是因为Lambda表达式可以在需要时转换为Func或Predicate,而且因为大多数人都使用它们,所以人们会继续使用它们,而没有意识到新的linqapi实际上有不同的参数/没有包含任何重载
无论如何,这个设计决策背后的原因是什么?因为泛型
列表
类自.Net 2.0(以及谓词
)以来就存在,并且它必须保持向后兼容。但是Func
(以及Expression
)和Linq只在.Net 3.5中引入,因此新的Linq方法(例如FirstOrDefault()
)能够依赖新的Func
类型,而不需要考虑向后兼容问题。此外,还必须区分“谓词”术语和谓词
类型。将Func
传递给Where()
或FirstOrDefault()
可以肯定地被视为一个“谓词”(请参阅),值得注意的是,如果public bool f(int t)=>true
f
将隐式转换为谓词
,用于旧的列表
方法,或Func
用于新的LINQ扩展方法。@EdPlunkett,你能澄清一下吗,我无法使该代码段正常工作。@AlexanderRyanBaggett,你想让我猜猜是什么打破了它吗?没有,但是。不管怎么说,haim770对为什么要这样做有正确的答案。正如我们经常在.NET中发现的奇怪的不一致之处,“似乎是历史造成的”。
//does not work
Predicate<dynamic> pred = cov => cov.EmployeeId == EmployeeId;
var foundCovarage = EmployeeCoverageCurrent.FirstOrDefault(pred);
//works fine
var foundCoverage = EmployeeCoverageCurrent.FirstOrDefault(cov => cov.EmployeeId == EmployeeId);
//also works fine
Func<dynamic, bool> func = cov => cov.EmployeeId == EmployeeId;
var foundCoverage = EmployeeCoverageCurrent.FirstOrDefault(func);