Lazy Object Instantiation etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Lazy Object Instantiation etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

C# Lazy Obje Örnekleme (Lazy Object Instantiation)

Bir sınıf yarattığımızda bir çok eleman ekleriz fakat client tarafından bu elemanlar belkide hiç çağırılmayacaktır. Özellikle bu eleman büyük bir dataya sahipse kullanılmadığı halde her nesne yaratıldığında bellekte yer kaplayacaktır.

Örnek olarak bir MediaPlayer yazdığımızı düşünelim: Play, Pause, Stop metodları olsun MediaPlayer sınıfımızın bir de MediaPlayer'ımızın içerisindeki song objelerini tuttan bir AllTrack adında collection property'imiz olsun.

İlk hetapta Lazy Object Instantiation kullanmadan tasarlayalım MediaPlayer sınıfımızı:

class Song
    {
        public string Artist { get; set; }
        public string TrackName { get; set; }
        public double TrackLength { get; set; }
    }
class MediaPlayer
    {
        public void Play() { Console.WriteLine("Playing the song."); }
        public void Pause() { Console.WriteLine("Paused the song."); }
        public void Stop() { Console.WriteLine("Stoped the song."); }
        public List<song> AllTracks { get; set; }

        public MediaPlayer()
        {
            GetAllTracks();
        }

        private void GetAllTracks()
        {
            AllTracks.Add(new Song() { Artist = "Duman"
                   , TrackName = "Ah", TrackLength = 3.1 });
            AllTracks.Add(new Song() { Artist = "Mor ve Ötesi"
                   , TrackName = "Cambaz", TrackLength = 4.6 });
            AllTracks.Add(new Song() { Artist = "Kuban"
                   , TrackName = "Yobaz", TrackLength = 3.5 }); 
        }
    }

 class Program
    {
        static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            // play ve stop metodlarini cagirip
            // programimizi bitirdik fakat
            // AllTracks bosuna yüklendi
            player.Play();
            player.Stop();
        }
    }

Gördüğünüz gibi sadece Play ve Stop işleri yapılmasına rağmen tüm AllTrack listesi yüklendi. Programımızı şimdi birde Lazy Object Instantiation kullanarak yazalım bakalım nasıl bir değişiklik olacak:


class Song
    {
        public string Artist { get; set; }
        public string TrackName { get; set; }
        public double TrackLength { get; set; }
    }
    class MediaPlayer
    {
        public void Play() { Console.WriteLine("Playing the song."); }
        public void Pause() { Console.WriteLine("Paused the song."); }
        public void Stop() { Console.WriteLine("Stoped the song."); }
        public Lazy<List<Song>> LazyAllTracks { get; set; }

        public MediaPlayer()
        {
            LazyAllTracks = new Lazy<List<Song>>(() => GetAllTracks());
        }

        private List<Song> GetAllTracks()
        {
            List<Song> allTracks = new List<Song>();
            allTracks.Add(new Song() 
                { Artist = "Duman", TrackName = "Ah"
                   , TrackLength = 3.1 });
            allTracks.Add(new Song() 
                { Artist = "Mor ve Ötesi"
                , TrackName = "Cambaz", TrackLength = 4.6 });
            allTracks.Add(new Song() 
                { Artist = "Kuban", TrackName = "Yobaz"
                    , TrackLength = 3.5 });
            return allTracks;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MediaPlayer player = new MediaPlayer();
            Console.WriteLine("Sarki listesi yuklendi mi? {0}"
              , player.LazyAllTracks.IsValueCreated ? "Evet" : "Hayır");
            player.Play();
            player.Stop();
            Console.WriteLine("Sarki listesi yuklendi mi {0}"
              , player.LazyAllTracks.IsValueCreated ? "Evet" : "Hayır");
            foreach (Song song in player.LazyAllTracks.Value)
            {
                
            }
            Console.WriteLine("Sarki listesi yuklendi mi {0}"
              , player.LazyAllTracks.IsValueCreated ? "Evet" : "Hayır");
            Console.ReadLine();
        }
    }

Yukarıdaki kodla ilgili olarak Lazy<T> nesne örneğinin IsValueCreated property'si track listesinin dolup dolmadığını anlamamızı sağlar.

Çıktı:




Programımızın çıktısından anlaşılabileceği gibi MediaPlayer nesne örneği oluşturduğumuzda şarkı listesi oluşmadı. Ardından Play ve Stop metodlarını çalıştırdık ve hala liste oluşmadı. Sonra foreach içerisinde Lazy<T> nesne örneğinin value property'si istendi ve bununla birlikte liste oluştu. Kısacası liste istemci tarafından istenene kadar oluşturulmadı.

Lamda operatörü ile Lazy obje yaratılırken çalışacak extra işler yaptırabiliriz:

// Use a lambda expression to add additional code
// when the AllTracks object is made.
private Lazy allSongs = new Lazy( () =>
{
     Console.WriteLine("Creating AllTracks object!");
     return new AllTracks();
});

Örnek Proje: LazyObjectInstantiation.rar