dotnet-musahibe-suallari-toplusu--captured-variables

.NET müsahibə sualları toplusu: Captured Variables

C# dilinə lambda ifadələrin əlavə edilməsi ilə birlikdə aktuallaşan mövzulardan biri də “captured variables” mövzusudur.

Captured Variables verilənlərin  kompilyasiya vaxtı aldıqları qiymətə görə yox, runtime vaxtı operativ yaddaş qiymətinə görə işləməsini təmin edir.

Adətən bu tipli situasiyalarla deleqatlar istifadə edən zaman rastlaşırıq. Çünki lambda ifadələr  2 fazada(mərhələdə) formalaşırlar. Birinci faza onların elan olunması, ikinci faza isə işə salınmasıdır. Digər mexanizmlərdən (metod, deleqat vəs.) fərqli olaraq lambda ifadələr daxil oduqların kontekstin bütün informasiyalarına birbaşa əl çata bilirlər. Onların görünmə sahəsi öz daxil olduqları kontekslə məhdudlaşır. Aşağıdakı sadə bir nümunəyə baxaq:

         string name = "Fuad";

            //deleqata lambda ifadə vasitəsilə dəyişəni ötürürük
            // həmin an dəyişənin dəyəri "Fuad"dır.
            Action myDelegate = () => Console.WriteLine(name);

            //dəyər dəyişilir..
            name = "Şamil";

            //deleqat işə düşən zaman dəyişənin ən son qiymətinə baxır
            // yeni ekranda artıq "Şamil" sözü görünəcək
            myDelegate();

Yuxarıdakı nümunədə deleqat ilkin olaraq “Fuad” dəyərini götürsə də , həmin an işə düşmədiyiniə görə sonradan dəyərin dəyişilməsi deleqata da təsir edir. Ona görə ilkin verilən dəyər yox, sonradan əlavə dəyişilmiş dəyər ekranda görünür.

               Captured Variables bütün sintaktik vahidlərdə eyni cür işləmir. Beləki foreach operatoru ilə verilmiş massivdəki elementləri ekranda göstrəən nümunəyə baxaq:

             int[] ages = { 21,24,34,32,19,29 };
            List container = new List();

            // Capture foreach iteration variable
            foreach (int age in ages)
                container.Add(() => Console.WriteLine(age));

            foreach (Action action in container)
                action();

Bu nümunədə Bənzəri proses sadəcə dövrü olaraq yerinə yetirilir. Ekranda görünən məlumatdan məlum olduğu kimi captured variables burada aktuallığını itirir.

               Lakin həmin misalı for operatoru ilə yazsaq taam başqa ssenari ilə rastlaşırıq. Beləki aşağıdakı kod nümunəsi gözlədiyimiz nəticəni vermir!!

          for(int i=0;i-1;i++)
            {               
                container.Add(() => Console.WriteLine(ages[i]));
            }

            foreach (Action action in container)
                action();

            

   Bu kodun doğru işləməsi üçün mütləq şəkildə lokal konteksdə bir dəyişən formalaşdırmalı və həmin deyişəni istifadə etməliyik!

         for(int i=0;i-1;i++)
            {
                int temp = i;
                container.Add(() => Console.WriteLine(ages[temp]));
            }
            foreach (Action action in container)
                action();

 Adətən praktikada belə hallarla daha çox Tasklar istfadə edən zaman rastlaşırıq. Əgər bir neçə taski işə for dövründə işə salmaq lazımdırsa ozaman lambda ifadə variantı daha yaxşıdır.

            for(int i=0;i<10;i++)
            {
                new Task(() => Console.WriteLine("Task number " + i)).Start();
            }

 

Burada da problemi aradan qaldırmaq üçün əlavə kontekst daxilində dəyişənə ehtiyacımız var.

      for(int i=0;i<10;i++)
            {
                int temp = i;
                new Task(() => Console.WriteLine("Task number " + temp)).Start();
            }

Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz