![](/img/trans.png)
[英]Is yield break equivalent to returning Enumerable<T>.Empty from a method returning IEnumerable<T>
[英]Returning IEnumerable<T> with yield from IDisposable instance
我發現了一件有趣的事情。 C#,.NET 4.0。 我有一個代表 IDisposable 接口的類。 在提到的類中,我有一個函數,它返回 IEnumerable 並返回收益。 在調用時,控件跳過該函數。 不要介入。 示例:
class Program
{
static void Main(string[] args)
{
using (DispClass d = new DispClass())
{
d.Get2();
d.Get1();
}
}
}
public class DispClass: IDisposable
{
public DispClass()
{
Console.WriteLine("Constructor");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
public int Get1()
{
Console.WriteLine("Getting one");
return 1;
}
public IEnumerable<int> Get2()
{
Console.WriteLine("Getting 1");
yield return 1;
Console.WriteLine("Getting 2");
yield return 2;
}
}
輸出:“構造函數”“得到一個”“處置”
“獲得1”,“獲得2”在哪里? 如果沒有返回本地列表的收益回報,我可以看到這些......
請解釋!
這是預期的行為和設計。 當您使用yield
,實際發生的是Get2
方法返回一個由編譯器自動實現的類型的實例。 該類型實現IEnumerable<T>
接口。 在枚舉可枚舉對象之前,迭代器方法中的代碼實際上不會被調用。 由於您沒有枚舉Get2
調用的結果,因此永遠不會調用您的代碼。 要強制它,請使用ToArray()
或ToList()
:
d.Get2().ToList();
只有當您遍歷該方法返回的 IEnumerable 時,方法 Get2() 中的代碼才會執行。 由於在這種情況下 IEnumerable 包含兩個元素,它將兩次輸入此代碼 - 在第一次迭代期間,它將執行第一兩行並在“yield return 1”處退出函數;在下一次迭代期間,它將進入該函數並開始執行在 "Console.WriteLine("Getting 2");" 行,然后繼續從那里開始。
因此,如果您不迭代這兩個項目,即在獲得值 1 后,您不會移動到 IEnumerable 中的下一個項目,則不會再次輸入該函數。 嘗試將您的程序更改為以下代碼以獲得更好的理解。
static void Main(string[] args)
{
using (DispClass d = new DispClass())
{
var lst = d.Get2();
//d.Get1();
foreach (var a in lst)
{
break;
}
}
Console.ReadKey();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.