حسین احمدی
بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

Lazy Object Instantiation چیست؟ آشنایی با کلاس Lazy در سی شارپ

 همانطور که می دانید، ایجاد کردن اشیاء در زمان اجرا باعث اشغال حافظه Heap می شود. شاید برای تعداد اشیاء کم این موضوع چندان به چشم نیاید، اما فرض کنید می خواهید 10 هزار شئ از روی یک کلاس ایجاد کنید. بزارید با یک مثال این موضوع رو توضیح بدم، کلاسی داریم که در سازنده اون حدود 10 هزار شئ ساخته میشه و جایی ما از این کلاس قراره استفاده کنیم. شئ ساخته میشه، اما همون لحظه تصمیم به استفاده از اون نداریم و میخواهیم زمانی که می خواهیم عملیات ساخت اشیاء انجام بشه. کد زیر رو در نظر بگیرید:

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران
public class Order
{
    public int Id { get; set; }
    public string Title { get; set; }
    public DateTime Date { get; set; }
}

public class OrdersRepository
{
    private List<Order> allOrders;

    public OrdersRepository()
    {
        allOrders = new List<Order>();
        for (var counter = 0; counter < 10000; counter++)
        {
            allOrders.Add(new Order());
        }
    }

    public List<Order> All
    {
        get { return allOrders; }
    }
}

زمانی که شئ ای از روی OrdersRepository می سازیم، عملیات ساخت اشیاء انجام می شود که این کار Overhead زیادی بر روی سیستم اعمال می کند. برای حل این مشکل باید از مکانیزم Lazy Object Instantiation استفاده کنیم. یک راه آن تغییر کلاس OrdersRepository به صورت زیر است:

public class OrdersRepository
{
    private List<Order> allOrders;

    public List<Order> All
    {
        get
        {
            allOrders = new List<Order>();
            for (var counter = 0; counter < 10000; counter++)
            {
                allOrders.Add(new Order());
            }
            return allOrders;
        }
    }
}

تا زمانی که دسترسی به خصوصیت All انجام نشود، لیست اشیاء ساخته نمی شود. اما فرض کنید که باید حتماً در سازنده کلاس اینکار انجام شود. راه حل آن چیست؟ در دات نت، کلاسی داریم به نام Lazy که یک کلاس Generic است و این حالت را برای ما انجام می دهد. کافیست به صورت زیر کلاس OrdersRepository را استفاده کنیم:

Lazy<OrdersRepository> repository = new Lazy<OrdersRepository>();

foreach (var order in repository.Value.All)
{
                
}

با استفاده از مکانیزم بالا، عملیات ساخت شئ تا زمان استفاده از خصوصیت Value در کلاس Lazy به تاخیر می افتند. یکی از مزیت های استفاده از کلاس Lazy، قابلیت مشخص کردن روند ساخت شئ از طریق پارامتری است که به عنوان سازنده به این شئ پاس داده می شود. برای مثال، در کد زیر روند ساخت شئ از روی OrdersRepository را تغییر می دهیم:

Lazy<OrdersRepository> repository = new Lazy<OrdersRepository>(() =>
{
    Console.WriteLine("Creating repository of Orders!");
    return new OrdersRepository();
});

foreach (var order in repository.Value.All)
{
                
}

کدی که به عنوان پارامتر factory به کلاس Lazy پاس داده می شود، زمانی که از خصوصیت Value استفاده می کنیم اجرا می شود.

نویسنده: حسین احمدی

انجمن تخصصی فناوری اطلاعات ایران


حسین احمدی
حسین احمدی

بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

حسین احمدی ، بنیانگذار TOSINSO ، توسعه دهنده وب و برنامه نویس ، بیش از 12 سال سابقه فعالیت حرفه ای در سطح کلان ، مشاور ، مدیر پروژه و مدرس نهادهای مالی و اعتباری ، تخصص در پلتفرم دات نت و زبان سی شارپ ، طراحی و توسعه وب ، امنیت نرم افزار ، تحلیل سیستم های اطلاعاتی و داده کاوی ...

نظرات