我正在查看以下代码
public IEnumerable<RoleRecord> GetRoles() {
var roles = _roleRepository.Table.Select(role => role);
return roles.ToList();
}
Table
为IQueryable<RoleRecord> Table { get; }
有没有更好的方法来写这个?
答案 0 :(得分:7)
Select(role => role)
有效地投射到自身 - 所以基本上什么也没做。
return _roleRepository.Table.ToList();
...将实现相同,或:
return _roleRepository.Table;
如果您很高兴返回可枚举而非已解析的列表。
这使得Table
有效IEnumerable<T>
的猜测符合Select()
或ToList()
的条件。
ToList
会完全迭代Table
枚举,但会以IEnumerable<T>
的形式返回。消费者将会迭代列表,这可能比迭代Table
更便宜。
更新:,返回IEnumerable<T>
(在您的情况下,从Select(role => role)
)和返回List<T>
之间的一个重要区别是如果使用List<T>
,则调用者可以将您的IEnumerable<T>
强制转换为List<T>
并对其进行修改:
IEnumerable<RoleRecord> results = GetRoles();
var asList = (List<RoleRecord>)results;
asList.Add(new RoleRecord());
asList.RemoveAt(0);
但是请注意,自我投影不是决定因素,事实上你使用迭代器块作为IEnumerable<T>
实现,而不是List<T>
也就是说,这种特殊的行为差异在你的情况下不会显而易见,因为你打电话给ToList()
,所以原始答案中的代码代表 - 它是等价的(技术上稍快一点)。
答案 1 :(得分:2)
如果没有任何过滤条件,则无需调用Select。
类似的东西:
public IEnumerable<RoleRecord> GetRoles() {
return _roleRepository.Table.ToList();
}
会更简单吗?调用.ToList()显然会使集合保持水分,但我认为这是你想要的。
答案 2 :(得分:1)
应该简化为:
public IEnumerable<RoleRecord> GetRoles() {
return _roleRepository.Table.ToList();
}
基本上,a => a
只是一个&#34;身份&#34;投影,即a
自成一体。在这种情况下,它真的不买任何东西。
在某些情况下,当您不想完成某项操作时,它偶尔会作为占位符使用。但是,在这种情况下,没有必要,因为最终结果只是在原始序列上执行ToList()
,这可以在没有Select()
的情况下直接完成。
当然,这是假设在原始方法中两条线之间没有其他任何东西。
答案 3 :(得分:1)
LINQ的Select(a => a)
做了什么?
它将序列的每个元素投影到一个新表单中,该表单只包含您指定的元素('a')。
答案 4 :(得分:1)
我相信你可以写:
public IEnumerable<RoleRecord> GetRoles() {
return _roleRepository.Table.ToList();
}
如果没有,那么你可以试试
return (from r in _roleRepository.Table select r).ToList();
答案 5 :(得分:1)
Select方法返回一个“投影” - 对可枚举源的每个单独元素的修改。在这种情况下,它将元素投射到自身,因此它是多余的。
如果我不得不猜测意图,我会说包含了选择,并且查询没有内联其“ToList()”终止符(强制评估Linq链以生成所有元素),所以它可以更容易调试,以确切查看查询生成的元素。或者,此查询最初可能是由精通SQL的人编写的,他认为所有LINQ查询都应该包含SQL SELECT查询的部分。
无论如何,除了删除Select之外,还可以在return:
中内联此查询public IEnumerable<RoleRecord> GetRoles() {
return _roleRepository.Table.ToList();
}