-2

我决定今天学习一些 Python (IronPython) 语法。在这样做的过程中,我对它允许的循环结构印象深刻。

Pythonelse在其循环上支持一个子句。一个else循环基本上是说,“如果这个循环正常完成,那么进入这个子句”。

请允许我演示使用 C#。

这段代码:

Something something = SomeCallToSetThisUp();
bool isCompatable = false;
foreach (Widget widget in widgets)
{
   isCompatable = widget.IsCompatableWithSomething(something);

   if (!isCompatable)
      break;
}
if (isCompatable)
   compatableSomethings.Add(something);

可能成为此代码(无效的 C#):

Something something = SomeCallToSetThisUp();
foreach (Widget widget in widgets)
{
   if (!widget.IsCompatableWithSomething(something));
      break;
}
else
   compatableSomethings.Add(something);

从来没有见过这个,它让我觉得很酷。一旦你学会了它,它看起来就像我见过的任何代码一样可读。

虽然不是普遍需要(有时您想影响列表中的每个项目),但我确实认为它会很有用。

所以,我的问题是:为什么这不在 C# 中?

我有几个想法为什么:

  • break会使调试更加困难,因此设计者不想鼓励它。
  • 并非所有闪亮的东西都能融入语言。(范围有限)。

但这些只是猜测。 我要求一个实际的规范原因

4

3 回答 3

3

通常的答案是因为没有人要求它,或者开发和维护它的成本超过了收益。

来自 Eric Lippert 的博客:

我已经多次链接到 Eric Gunnerson 关于 C# 设计过程的精彩帖子。Eric 的帖子中最重要的两点是:(1)这不是减法过程;我们不会从 C++ 或 Java 或 Haskell 开始,然后决定是否将它们的某些特性排除在外。(2) 仅仅作为一个好的特性是不够的。功能必须如此引人注目,以至于它们值得设计、实施、测试、记录和发布功能的巨额成本。它们必须值得付出使语言复杂化并使将来设计其他功能变得更加困难的成本。

在我们完成了对 C# 3.0 各个部分的最后一分钟的小规模重新设计之后,我们列出了我们能想到的所有可能进入 C# 未来版本的特性。我们花了很多很多时间研究该列表中的每个功能,试图“存储”它。每个功能都放入一个独特的存储桶中。这些桶被标记为:

Pri 1:必须在下一个版本中

Pri 2:应该在下一个版本中

Pri 3:很高兴在下一个版本中有

Pri 4:可能需要多年深入研究才能做到

Pri 5:坏主意

显然,我们立即停止在下一个版本的背景下考虑四和五。然后,我们将前三个存储桶中的功能成本相加,将它们与我们可用的设计、实施、测试和文档资源进行比较。成本大大高于可用资源,因此我们削减了存储桶 2 和 3 中的所有内容,以及存储桶 1 中的大约一半。结果发现其中一些“必须拥有”实际上是“应该拥有”。

当我谈论在那个冗长的论坛主题中建议的一些功能时,理解这个分桶过程将有所帮助。建议的许多功能都非常好,但落入了第 3 类。它们没有弥补 100 分的差距,只是不够引人注目。

http://blogs.msdn.com/b/ericlippert/archive/2008/10/08/the-future-of-c-part-one.aspx

此外,您需要权衡现有/新开发人员是否容易理解该功能。恕我直言else,循环不是很可读,特别是因为“如果前一个完成OK,则执行此块”的关键字是finally.

更重要的是,我认为Enumerable.Any/Enumerable.All方法在这种情况下要好得多。

于 2013-06-20T23:26:58.990 回答
1

遍历集合和检查条件是不同的事情,因此它们应该是不同的语言结构。

于 2013-06-20T23:29:37.907 回答
0

因为 for else 循环是来自 python 等语言的 hack。如果您觉得需要一个 for else 循环,您可能应该将该代码放在一个单独的函数中。

于 2013-06-20T23:29:14.247 回答