在 PHP 和 C# 中,为什么 foreach 没有内置的空数组/列表检查?



在PHP, c#和其他语言中,为什么不开发语言来减少不必要的代码编写?

为什么例如foreach在null数组或列表上执行循环?

我不是一个专业的程序员,但我认为这是一个常识。

谢谢。

c#

因为foreach不是汇编级指令

foreach关键字是"语法糖";从语言中,而不是在生成的代码中。代码

List<string> myList = new List<string>();
// ... fill list
foreach(var s in myList)
{
// ...
}

实际上被翻译成

IEnumerator it = myList.GetEnumerator();
while (it.MoveNext())
{
string s = it.Current;
// ...
}

在这段代码中,检查myList是否为null会非常难看,因为它需要引入嵌套的if。myList不需要是一个简单的变量,它可以是任何类型的表达式,甚至是一个方法调用。这不是不可能的,但会使编译器的事情变得相当复杂,甚至在不需要的情况下也会添加额外的代码。

一般来说,让程序在出现错误时崩溃也是一个好主意,因为这样可以及早发现错误。. net运行时通常展示了尽早抛出错误的概念,而不是试图尽可能长时间地隐藏错误。这是否"更好";这是一个哲学问题,其他语言也在走不同的道路,但对于c#来说,这种行为始终如一。

虽然很少见,但从技术上讲,列表可以是值类型,其中null测试是错误的,需要编译器进行类型测试。

c#

如果它真的激怒了你,也许你可以使用扩展方法来解决这个问题。因为它是一个扩展方法,您甚至可以在null数组或列表上调用它。


public static class EnumerableExtensionMethods
{
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
if (source is null)
{
return Enumerable.Empty<T>();
}
return source;
}
}

你可以这样使用这个方法:

List<string> nullList = null;
foreach (var entry in nullList.EmptyIfNull())
{
// code here
}

当然你也可以不使用扩展方法来写:

foreach (var entry in nullList ?? Enumerable.Empty<string>())
{
// code here
}

这不会抛出异常,因为扩展方法(第二个例子中的空合并操作符)阻止了foreach求值的可枚举对象不等于null

上网试试

最新更新