Chúng tôi đang cố gắng sử dụng IEnumerable
làm nhà máy tạo ra các đối tượng khác nhau mỗi khi chúng ta lặp lại nó. Những người cần được GC'ed càng sớm càng tốt. Tuy nhiên, lưu ý rằng chúng tôi giữ một tham chiếu đến điều tra số để chúng tôi có thể gọi lại. Vì vậy, chương trình của chúng tôi về cơ bản trông như thế này:Khi sử dụng "lợi nhuận" tại sao loại trình biên dịch tạo ra cả IEnumerable và IEnumerator
public class YieldSpec
{
public static IEnumerable<string> Strings()
{
yield return "AAA";
yield return "BBB";
yield return "CCC";
}
public void YieldShouldAllowGC()
{
var e = Strings();
foreach (var a in e)
{
Console.WriteLine(a);
}
}
}
Nhìn vào đó mã trong trình gỡ lỗi:
Bạn có thể thấy rằng khi breakpoint là hit các IEnumerable có một tham chiếu đến "CCC ".
Điều này không thực sự xảy ra. IEnumerable chỉ nên tạo một IEnumerator khi GetEnumerator được gọi. Đây có phải là hành vi mong đợi mà IEnumerable có thể chứa trạng thái không?
Tôi không thể tạo lại. Chắc chắn bạn đã xử lý tất cả các trường hợp? Sử dụng [mã này] (https://dotnetfiddle.net/M4AdN8). –
Bạn đã loại bỏ cá thể thành 'Kiểm tra'? Nó không vứt bỏ toàn bộ thứ cho đến khi bạn vứt bỏ 'Test'. (nó là lười biếng) –
AFAIK phạm vi để lại 'Test()' (hoặc cụ thể hơn, sau khi 'foreach()' đã) sẽ làm cho điều tra viên đủ điều kiện thu gom rác thải. Vấn đề là gì? Đó là _directly_ sau khi gọi 'Test()', GC chưa khởi động? – CodeCaster