sách gpt4 ăn đã đi

c# - 为什么 IEnumerator.Current 的错误处理不同于 IEnumerator.Current?

In lại 作者:IT王子 更新时间:2023-10-29 04:19:25 26 4
mua khóa gpt4 giày nike

我原以为对实现了 IEnumerable 的空集合执行以下代码会抛出异常:

var enumerator = collection.GetEnumerator();
enumerator.MoveNext();
var type = enumerator.Current.GetType(); // Surely should throw?

因为集合是空的,然后访问IEnumerator.Current无效,我本以为会有异常(exception)。但是,Danh sách 不会抛出异常.

Đây làthe documentation for IEnumerator.Current 允许的,其中指出 Hiện hành在以下任何条件下未定义:

  • 枚举数位于集合中第一个元素之前,紧接在枚举数创建之后。在读取 Current 的值之前,必须调用 MoveNext 将枚举数推进到集合的第一个元素。
  • 最后一次调用 MoveNext 返回 false,表示结束集合。
  • 枚举器因集合中的更改(例如添加、修改或删除元素)而失效。

(我假设“未能抛出异常”可以归类为“未定义行为”...)

但是,如果您执行相同的操作但使用 IEnumerable相反,你确实得到了一个异常(exception)。此行为由 the documentation for IEnumerator.Current 指定,其中指出:

  • 如果对 MoveNext 的最后一次调用返回 false,则 Current 应该抛出 InvalidOperationException,这表明集合结束。

我的问题是:为什么会有这种差异?是否有我不知道的充分的技术原因?

这意味着看似相同的代码可能会根据是否使用 IEnumerable 而表现出截然不同的行为。或 IEnumerable , 如以下程序所示(注意 showElementType1()showElementType1() 中的代码是如何相同的):

sử dụng Hệ thống;
sử dụng System.Collections;
sử dụng System.Collections.Generic;

namespace ConsoleApplication2
{
class Program
{
public static void Main()
{
var list = new List();

showElementType1(list); // Does not throw an exception.
showElementType2(list); // Throws an exception.
}

private static void showElementType1(IEnumerable collection)
{
var enumerator = collection.GetEnumerator();
enumerator.MoveNext();
var type = enumerator.Current.GetType(); // No exception thrown here.
Console.WriteLine(type);
}

private static void showElementType2(IEnumerable collection)
{
var enumerator = collection.GetEnumerator();
enumerator.MoveNext();
var type = enumerator.Current.GetType(); // InvalidOperationException thrown here.
Console.WriteLine(type);
}
}
}

câu trả lời hay nhất

IEnumerable 的问题是那个Hiện hành类型为 T . default(T) is returned 而不是抛出异常(它是从 MoveNextRare 设置的)。

sử dụng IEnumerable 时你没有类型,你不能返回默认值。

实际问题是你没有检查 MoveNext 的返回值.如果它返回 SAI , 你不应该调用 Hiện hành .异常没关系。我认为他们发现返回 default(T) 更方便在IEnumerable案例。

异常处理带来开销,返回default(T)没有(那么多)。也许他们只是认为从 Hiện hành 返回没有任何用处。 IEnumerable情况下的属性(property)(他们不知道类型)。该问题已在 IEnumerable 中“解决”使用 default(T) giờ.

根据这个bug report (感谢 Jesse 发表评论):

For performance reasons the Current property of generated Enumerators is kept extremely simple - it simply returns the value of the generated 'current' backing field.

这可能指向异常处理开销的方向。或者需要额外的步骤来验证 hiện hành 的值.

他们实际上只是将责任推给了foreach ,因为那是枚举器的主要用户:

Các vast majority of interactions with enumerators are in the form of foreach loops which already guard against accessing current in either of these states so it would be wasteful to burn extra CPU cycles for every iteration to check for these states that almost no one will ever encounter.

关于c# - 为什么 IEnumerator.Current 的错误处理不同于 IEnumerator.Current?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30840782/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress