1

我在测试代码中看到了这个循环:

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<> 而不是方法?

共识似乎倾向于一种方法而不是委托。这同样适用于我的情况吗?

4

3 回答 3

0

我会选择第一个块:

foreach (StuffId Id in Result.GetIdList())
{
    if (Id.Level == 3)
    {
        Level3Id = Id.ToString();
    }
    if (Id.Level == 5)
    {
        Level5Id = Id.ToString();
    }
}

这只会循环一次集合。我看到你不担心这里的性能,但对我来说这不是性能或优化的问题。这是做一些逻辑上正确的事情的问题。如果可以一步完成,为什么要做两次(只要不损害可读性)。

额外的好处是您不必在Func<,>方法和相关的复杂性之间进退两难。就字符数或打字的难易程度而言,它几乎相同,除了你是水平书写(在第二种情况下)而不是垂直书写。您甚至可以在foreach块内的两行中编写上述内容。

如果您一心想分别编写这两个操作,我会根据该函数在这种情况下是否具有超出当前方法范围的相关性来做出选择。在我看来,它是一个微不足道的谓词,仅与两个任务相关。所以我喜欢:

var Ids = Result.GetIdList();
Func<int, string> IdFromLevel = level => Ids.Single(x => x.Level == level).Id.ToString();

Level3Id = IdFromLevel(3);
Level5Id = IdFromLevel(5);

更喜欢Single这里而不是First..

于 2013-06-29T08:45:41.433 回答
0

不确定利弊,但阅读这些文章可能会帮助您做出更好的决定:

http://msdn.microsoft.com/en-in/library/bb549151.aspx

http://msdn.microsoft.com/en-us/library/orm-9780596516109-03-09.aspx

http://msdn.microsoft.com/en-in/library/98dc08ac.aspx

于 2013-04-17T10:46:09.007 回答
0

这是一个重用的问题。如果您使用的方法可能在其他情况下可重用,则应单独定义它们。
但是,如果您只有简短的语句并且会有所不同,则应坚持使用匿名函数/ lambda 表达式,这些可能会导致更好的运行时行为。

SO

您发布的代码没有任何优势。在您的代码中,使用委托只会增加复杂性以及额外的运行时成本 - 所以您最好直接调用该方法。

但是,委托有很多用途。“传递”给其他方法是主要用法,尽管存储一个函数并在以后使用它也非常有用。

LINQ 完全建立在这个概念之上。当你这样做时:

var results = myCollection.Where(item => item == "Foo");

您将委托(定义为 lambda:item => item == "Foo")传递给WhereLINQ 库中的函数。这就是使它正常工作的原因。

于 2013-04-17T10:12:22.083 回答