Delphi 枚举器中的规范 MoveNext 是这样编写的:
function TListEnumerator.MoveNext: Boolean;
begin
Result := FIndex < FList.Count - 1;
if Result then
Inc(FIndex);
end;
这是整个 RTL、VCL 等使用的形式。这种形式似乎在 3 rd方代码中也很普遍。
我认为它可以更简单地写成这样:
function TListEnumerator.MoveNext: Boolean;
begin
Inc(FIndex);
Result := FIndex < FList.Count;
end;
为什么不能使用更简单的形式有什么好的理由吗?
我的推理如下。一旦MoveNext
返回False
,该Current
属性将不再被访问。不在列表末尾没关系,FIndex
因为它再也不会使用了。for in 循环实际上是这样实现的:
while Enumerator.MoveNext do
Enumerator.Current.DoSomething;
事实上FIndex
,越界对我来说实际上更有意义。这意味着如果有人使用手写的枚举器代码,那么如果在返回Current
后访问,他们将得到范围检查错误。MoveNext
False
更重要的FIndex
是-1
,在第一次调用MoveNext
. 这是左边列表中的一个。在最后一次调用 之后MoveNext
,返回的那个False
不是合适的,FIndex
就是Count
右边列表中的那个。