老实说,有时候使用Funcs和Actions会受到情境的影响。比方说,如果你正在使用以下三个Func:
Func<DataClasses.User, String> userName = user => user.UserName
Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10
Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10
正如您所见,第一个示例使用lambda表达式替换以获取用户名,第二个示例替换了用于检查ID是否小于10的lambda表达式,第三个示例现在应该很容易理解了。
注意:这只是一个愚蠢的例子,但它确实有效。
var userList =
from user in userList
where userIDOverTen(user)
select userName;
对比
var otherList =
userList
.Where(IDIsBelowNumber)
.Select(userName)
在这个例子中,第二种方法较少冗长,因为扩展方法可以充分利用Func,但Linq表达式不能,因为它只查找布尔值而不是返回布尔值的Func。然而,在这种情况下,使用表达式语言可能更好。假设您已经有一个需要传入用户以外参数的方法:
private Boolean IDIsBelowNumber(DataClasses.User user,
Int32 someNumber, Boolean doSomething)
{
return user.UserID < someNumber;
}
注意:doSomething只是为了where扩展方法可以接受一个接受用户和整数并返回布尔值的方法而存在。对于这个例子来说有点恼人。
现在,如果您看一下Linq查询:
var completeList =
from user in userList
where IDIsBelowNumber(user, 10, true)
select userName;
你做得很好。现在是扩展方法:
var otherList =
userList
.Where(IDIsBelowNumber????)
.Select(userName)
如果没有 lambda 表达式,我实在无法调用那个方法。现在我需要做的是创建一个方法,它可以基于原始方法调用创建一个 Func。
private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
{
return user => IDIsBelowNumber(user, number, true);
}
然后插入它:
var otherList =
userList
.Where(IDIsBelowNumberFunc(10))
.Select(userName)
所以你可以看到,有时候使用查询方法可能更容易一些。