Circular Reference (การอ้างอิงแบบวนรอบ) ใน C#
Circular Reference เกิดขึ้นเมื่ออ็อบเจกต์สองตัวหรือมากกว่าอ้างอิงกันไปมาทำให้เกิด Dependency Cycle ซึ่งใน C# ปกติ Garbage Collector (GC) จัดการได้โดยอัตโนมัติ แต่ในบางกรณี (เช่น Unmanaged Resources หรือ Event Handlers ที่ไม่ถูก Unsubscribe) อาจทำให้ Memory Leak
ตัวอย่าง Circular Reference
public class A
{
public B Two { get; set; }
}
public class B
{
public A One { get; set; }
}
// การใช้งาน
A a = new A();
B b = new B();
a.Two = b;
b.One = a; // Circular reference
วิธีแก้ไข
- ใช้ Interface ตัด Dependency โดยให้อ้างอิงผ่าน Interface แทน Concrete Class
- WeakReference ใช้สำหรับ Cache หรือ Observer Pattern
- Unsubscribe Event Handlers ใน
Dispose()หรือFinalize - Nullify References ตั้งค่า Reference เป็น null เมื่อไม่ใช้แล้ว
ตัวอย่างแก้ไขด้วย Interface
public interface IMyInterface { }
public class A
{
public IMyInterface Two { get; set; }
}
public class B : IMyInterface
{
public A One { get; set; }
}
หมายเหตุ
- GC ใน .NET ใช้ Tracing Algorithm (Mark-and-Sweep) จึงสามารถเก็บ Circular Reference ได้โดยอัตโนมัติ หากไม่มี Root Reference ชี้เข้ามา
- ปัญหาหลักมักมาจาก Event Handlers ที่ไม่ Unsubscribe หรือ Static References