gpt4 book ai didi

c# - 为什么在包含 yield return 的函数中重复调用 using(){} block ?

转载 作者:行者123 更新时间:2023-11-30 21:18:18 25 4
gpt4 key购买 nike

我有以下代码。执行该查询大约需要 30 秒。我发现每次 for each 尝试枚举迭代器时,都会调用顶部的 using block 。这意味着每次调用枚举器中的 MoveNext 都会执行查询。

那么为什么惰性评估一遍又一遍地重新初始化using。我知道解决方法,但我需要了解这样做的目的。

   private IEnumerable<FriendProfile> GetProfiles() {
var query = @"
SELECT VirtualNumber, City, Gender, Nick, Age
FROM Profiles
WHERE Not VirtualNumber In ( SELECT VirtualNumber FROM Messages)
ORDER BY Id DESC;";

using (var con = GetConnection()) {
using (var cmd = dbconnection.CreateCommand()) {
cmd.CommandText = query;
var reader = cmd.ExecuteReader();
while (reader.Read()) {
var fp = new FriendProfile();
fp.VirtualNumber = reader.GetString(0);
fp.City = reader.GetString(1);
fp.Gender = reader.GetString(2);
fp.Nick = reader.GetString(3);
fp.Age = reader.GetInt16(4).ToString();
yield return fp;

}
}
}
}


foreach(var fp in GetProfiles()){
.... //foreach item using(){} in GetProfile() is reinitializes. All usings blocks
}

最佳答案

我不是 100% 确定你指的是哪个 using block ,但如果我理解正确,你所说的应该不会发生。 yield 将从 GetProfiles() 方法返回执行控制,但是 yield 之后的代码(即 using block )直到 while 条件为 false 时才会执行。

这里有一个简单的例子可以证明这种行为:

使用此类显示 using block 的末尾何时执行:

public class Disposable : IDisposable
{
private readonly string name;

public Disposable(string name)
{
this.name = name;
}

public void Dispose()
{
Console.WriteLine("Disposing of {0}", name);
}
}

和这段代码:

private IEnumerable<int> Test()
{
using (new Disposable("outer"))
{
using (new Disposable("inner"))
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
}
}

...

foreach (int i in Test())
{
Console.WriteLine("item {0}", i);
}

输出是:

item 0item 1item 2item 3item 4item 5item 6item 7item 8item 9disposing of innerdisposing of outer

这表明 using block 在 for 循环退出之前不会退出。

关于c# - 为什么在包含 yield return 的函数中重复调用 using(){} block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4293652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com