Gần đây tôi đi qua SO article này và tinh chỉnh nó cho kịch bản của tôi mà sau:Tại sao việc sử dụng Object Initializer giữ một đối tượng còn sống?
using System;
using System.Collections.Generic;
namespace ConsoleApplication18
{
class Program
{
static void Main(string[] args)
{
Manager mgr = new Manager();
var obj = new byte[1024];
var refContainer = new RefContainer();
refContainer.Target = obj;
obj = null;
mgr["abc"] = refContainer.Target;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
Console.WriteLine(mgr["abc"] != null); // true (still ref'd by "obj")
refContainer = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
Console.WriteLine(mgr["abc"] != null); // false (no remaining refs)
}
}
class RefContainer
{
public object Target { get; set; }
}
class Manager
{
Dictionary<string, WeakReference> refs =
new Dictionary<string, WeakReference>();
public object this[string key]
{
get
{
WeakReference wr;
if (refs.TryGetValue(key, out wr))
{
if (wr.IsAlive)
return wr.Target;
refs.Remove(key);
}
return null;
}
set
{
refs[key] = new WeakReference(value);
}
}
}
}
Chạy chương trình này cung cấp cho các kết quả dự kiến như sau:
True
False
Press any key to continue . . .
Tuy nhiên thay đổi này:
var refContainer = new RefContainer();
refContainer.Target = obj;
Để điều này (sử dụng cú pháp Object Initializer):
var refContainer = new RefContainer() { Target = obj };
Cung cấp đầu ra sau đây:
True
True
Press any key to continue . . .
gì đang xảy ra ở đây? Tại sao tuổi thọ của tham chiếu lại khác nhau chỉ vì sử dụng Object Initializer?
Hmm ... nó in "False, False" cho tôi. Tôi không thể in được nó. Bạn đang chạy điều này dưới trình gỡ rối? Gỡ lỗi hoặc xây dựng bản phát hành? –
@ JonSkeet-Chạy dưới trình gỡ lỗi, vâng. – Jim
Tôi đã thử nó với các bài kiểm tra đơn vị, kết quả tương tự như được đăng. Nó khá thú vị, và thatswhy bạn không nên gây rối với GC: D –