【发布时间】:2013-04-17 10:05:56
【问题描述】:
我在测试代码中看到了这个循环:
foreach ( StuffId Id in Result.GetIdList() )
{
if ( Id.Level == 3 )
{
Level3Id = Id.ToString();
}
if ( Id.Level == 5 )
{
Level5Id = Id.ToString();
}
}
其他测试意味着每个级别只有一个 Id,或者当每个级别有多个时,ID 将相同。
我现在对 LINQ 有点痴迷,我首先重构了这个:
IEnumerable<StuffId> Ids = Result.GetIdList();
Level3Id = Ids.Where( x => x.Level == 3 ).First().Id.ToString();
Level5Id = Ids.Where( x => x.Level == 5 ).First().Id.ToString();
然后代码重复困扰着我,所以我重构了这个:
IEnumerable<StuffId> Ids = Result.GetIdList();
Func<int,string> IdFromLevel =
level => Ids.Where( x => x.Level == level ).First().Id.ToString();
Level3Id = IdFromLevel(3);
Level5Id = IdFromLevel(5);
一位同事想知道为什么我没有使用方法代替委托。我的推理是一种方法会稍微“混乱”一些,因为我必须另外传入集合,并且使用委托对于简单的测试来说没什么大不了的(简洁、可读且没有分支是好的品质)。
当然,我查看了 SO,发现了这个看似相关的问题:
C#: Func<> instead of methods?
共识似乎倾向于一种方法而不是委托。我的情况也一样吗?
【问题讨论】:
-
是的,最好选择方法......出于同样的原因,在回答该问题时提到......
-
foreach代码使用最后一个元素的值,您的 linq 代码是第一个元素。所以它们不等价,除非只有一个匹配项,在这种情况下,您的 LINQ 代码应该使用Single而不是First。 -
您的 LINQ 的效率也低于原始循环,因为它会枚举集合两次。
-
@CodesInChaos:我在我的问题中承认了您的观点:“测试意味着每个级别只有一个 ID,或者当每个级别有多个 ID 时,ID 将是相同的”。在使用 First 之前,我可以按降序排列索引,但会是相同的(由其他测试保证)。
-
@Pranay Rana: 好的,所以你忽略了我认为有利于 lambda 的东西(简洁、可读、没有分支、对 lambda
有轻微的痴迷)但是 *为什么* 你打折吗?链接的答案不是测试代码,因此具有不同的意图。
标签: c# linq refactoring func