有没有更有效的方法来编写此代码

时间:2016-08-29 09:52:05

标签: c#

我认为标题说明了一切,

这里是代码:)

private void listBoxComponents_MouseDoubleClick(object sender, MouseEventArgs e)
   {
        object item = listBoxComponents.SelectedItem;
        string name = listBoxComponents.GetItemText(item);

        if (e.Button == MouseButtons.Left)
        {
            for (int i = 0; i < terrains.Count; i++)
            {
                if (terrains[i].name == name)
                    terrains[i].EnableBoundingBox(true);
                else
                    terrains[i].EnableBoundingBox(false);
            }
        }
    }

我在整个过程中都有相同的代码,我只是希望他们能用更简洁,更快捷的方式来完成相同的事情。也许用LINQ?

谢谢:)。

3 个答案:

答案 0 :(得分:6)

你还没有说“你更有效率”究竟是什么意思,所以我会冒昧地把它解释为“更容易阅读和输入”:

您可以替换循环:

for (int i = 0; i < terrains.Count; i++)
{
    if (terrains[i].name == name)
        terrains[i].EnableBoundingBox(true);
    else
        terrains[i].EnableBoundingBox(false);
}

有了这个:

foreach (var terrain in terrains)
{
    terrain.EnableBoundingBox(terrain.name == name);
}

请注意,通常,foreach循环在运行时可能比for循环有效 。但差异可能很小,除了在更极端的实时/高性能场景外,绝对无需担心。从积极的方面来说,最终会得到更简单的源代码。

顺便说一句,使用string.Equals(string, string, StringComparison)方法比较字符串可能更好,因为这样可以更明确地将比较文化和区分大小写用于其中。

另外,您已经提到过LINQ。 LINQ在这里不合适;让我简单解释一下原因:理论上可以编写一个自定义LINQ运算符ForEach,它接受​​一个Action<T>委托。它可以实现为foreach循环,为源序列中的每个项调用委托。然后你可以写下面的单行:

terrains.ForEach(terrain => terrain.EnableBoundingBox(terrain.name == name));

在我看来,普通foreach循环实际上更容易阅读,即使它占用更多的代码行。但最重要的是,请记住LINQ代表的内容:“语言集成查询”。 LINQ表达式应该查询数据,而不是修改它(即有副作用)。然而,ForEach自定义运算符将涉及副作用;这就是为什么它不适合LINQ范例并且不包含在框架中。

(作为最后的评论,我的回答基本上是代码审核。如果这是你想要的,也许Code Review SE网站可能是发布你的问题的更合适的地方。)

答案 1 :(得分:3)

您的问题可能更适合代码审查SO网站,因为它的工作原理,但您想要优化它。

我建议你研究terrains的另一个数据结构。将它用作数组并不是非常有效。如果在name属性上创建字典,则将避免对某个命名地形进行常量迭代。

更新:由于我最初的建议有缺陷,我想出另一个。

我坚持改变数据结构的想法。您应该创建一个TerrainList,在您的示例中公开启用边界框的功能,从而避免在整个应用程序中传播地形处理代码。

您的代码看起来像这样:

    if (e.Button == MouseButtons.Left)
    {
        terrains.highlight(name);
    }

然后可以优化highlight函数的实现,而不会对代码的其他部分产生副作用。

答案 2 :(得分:1)

代码本身很好。 LINQ不一定效率更高,尽管有时代码字符较少(如果有的话,它会带来额外的开销,但在IL编译期间通常会被删除,而且我倾向于发现LINQ的可读性低于传统的积木/循环)。

如果你使用LINQ,它最终会编译成类似于你所写的东西,所以它真的只是合成糖/代码糖果。

代码是可读的,你不会在循环中浪费资源......你还想要什么?

但是,我个人会将事件处理程序中的UI逻辑分解为它自己的方法。