C# Static Kullanımı



Static'in kullanıldığı yerler:

• Bir sınıf(class) içerisinde bulunan metodlar(methods).
• Bir sınıf(class) içerisinde bulunan alanlar (fields)
• Bir sınıfa ait static bir yapıcı metod (constructors)
• Değişmezler (constants) implicit olarak static tanımlama.
• Readonly referanslar.

  • Bir sınıf(class) içerisinde bulunan metodlar(methods).

    Static olarak tanımlanan bir metodun kullanılabilmesi için tanımlanmış olduğu tipin nesne örneğini oluşturmaya gerek yoktur. Bu durum çoğunlukla bir tipin asıl iş yapan fonksiyonelliklerin kullanılabilmesi için, tüm nesneyi örneklemenin gereksiz olduğu durumlarda ele alınır. Instance oluşturup bir statik metodu çağaramayız.

     
        public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }
        }


        class Program
        {
            static void Main(string[] args)
            {
                int alan = Dikdortgen.AlanHesapla(3,5);
            }
        }

    Görüldüğü gibi Dikdörtgen sınıfı içerisinde static olarak tanımalanan AlanHesapla metdodu Dikdörtgen sınıfının instance'ı oluşturulmadan sadece sınıf ismi ardından nokta denerek kullanılmıştır. Bu buze yuraıda yazdığımız gibi nesneyi boşuna yaratmadan Dikdörgen sınıfı içerisindeki metodu çağırmamızı sağlamıştır. Örneğin Console uygulamalarını geliştirirken çok sık kullandığımız Console sınıfına ait WriteLine, ReadLine vb metodlar static olarak tanımlanmışlardır. Hatta bir console uygulaması geliştirdiğimizde, programın giriş noktası olan Main metodunun static olarak tanımlandığını farketmişizdir.

    Static metodların kullanılması sırasında dikkat edilmesi gereken bazı durumlar vardır. Öncelikli olarak, static olarak tanımlanmış sınıf metodlarına static olmayan sınıf üyeleride erişebilir. Örneğin:


        public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }

    Bu kod parçasında görüldüğü gibi static olarak tanımlanan AlanHesapla metodu static olmayan AlanKontrolu metodu içerisinde çağırılabilmiştir. Fakat bu durumun tam tersi mümkün değildir yani static üyeler sadece static üyelere erişebilir.

    • Bir sınıf(class) içerisinde bulunan alanlar (fields) 

    Static metodlar gibi, bir sınıf içerisinde kullanılabilecek static alanlarda tanımlayabiliriz. Bir örnekle bunu inceleyecek olursak :


        public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int kontrolAlani = 20;
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Dikdortgen dikdortgen1 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen2 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen3 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Console.ReadLine();
            }
        }

    Bu kod parçacığında görüldüğü gibi int tipinde static kontrolAlani adında bir değişken tanımlanmıştır ve Dikdörtgen nesnesinin 3 defa instance'ı oluşturulup bu değişkenin değerlerine bakılmıştır. Bu program parçacığının çalışması sonucunda şu şekilde olacaktır:


    c# static

    Burada görüldüğü gibi Dikdörtgen sınıfına ait 3 nesne örneğinin oluşturulmasına ve kullanılmasına rağmen kontrolAlani değerinin hiç bir şekilde değişmediğidir. İşte bu etkinin nedeni kontrolAlani değerinin static olarak tanımlanmış oluşudur. Dolayısıyla Dikdörtgen nesnelerinden kaç tane oluşturulursa oluşturulsun hepsi aynı kontrolAlani değerine işaret etmektedir. Fakat bir static alanın değeri çalışma zamanında değiştirilebilir. Bu duruma şöyle bir örnek verilebilir :


    public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int kontrolAlani = 20;
            public void KontrolAlaniDegistir(int yeniKontrolAlani)
            {
                kontrolAlani = yeniKontrolAlani;
            }
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Dikdortgen dikdortgen1 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                dikdortgen1.KontrolAlaniDegistir(30);

                Dikdortgen dikdortgen2 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen3 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Console.ReadLine();
            }
        }
    Görüldüğü gibi Dikdortgen sınıfının içerisine kontrolAlaniDegistir adında bir metod tanımlanarak static bir değişken olan kontrolAlani'ni çalışma anında değiştirme amaçlanmıştır. Bu programın çıktısı şu şekilde olacaktır:



    Fakat burada contructer işin içene girince durum farklı bir boyut alacaktır. Bu örneğin bir farklı versiyonunun contructer'lı yazılmış hanina bakarsak :

    public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int kontrolAlani = 20;

            public Dikdortgen()
            {
                kontrolAlani = 25;
            }
            public void KontrolAlaniDegistir()
            {
                kontrolAlani = 40;
            }
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }

        class Program
        {
            static void Main(string[] args)
            {
                Dikdortgen dikdortgen1 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                dikdortgen1.KontrolAlaniDegistir();

                Dikdortgen dikdortgen2 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen3 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Console.ReadLine();
            }
        }

    Bu örneğin çıktısı şu şekilde olacaktır:


    Görüldüğü gibi bu durumda KontrolAlaniDegistir  metodu işe yaramamıştır. Çünkü her yeni nesne örneği oluşturulduğunda kontrolAlani değişkenine 25 değeri atanmıştır. Bu durumdan kurtulmanın yolu bir sonraki başlıkta açıklanacaktır.


    • Bir sınıfa ait static bir yapıcı metod (constructors)
    Static yapıcı metodu çoğunlukla bir sınıfın static değişkenlerine ilk nesne örneği oluşturulduğunda bir kereliğine değer atmak için kullanabiliriz. Bu bilgiler ışığında Dikdortegen sınıfımızı aşağıdaki gibi değiştirelim ve static yapıcı metodumuz içerisinde static kontrolAlani değişkeninin değerini belirleyelim.


    public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int kontrolAlani = 20;
            //public Dikdortgen()
            //{
            //    kontrolAlani = 25;
            //}
            //Bu sefer statik constructer kullandık.
            static Dikdortgen()
            {
                kontrolAlani = 35;
            }
            static void KontrolAlaniDegistir()
            {
                kontrolAlani = 40;
            }
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }
     


    Bu durumda program çıktısı :


    bu şekilde farklı bir sonuç elde etmemizin nedeni static yapıcılar(constructor)sadece ilk nesne örneği oluşturulduğunda çalışır. Aynı tipe ait sonraki nesne örneklemelerinde çalışmazlar.

    • Değişmezler (constants) implicit olarak static tanımlama. 
     Constant’ lar uygulamanın çalışması boyunca değişmeyecek değerleri saklamak için kullandığımız bir değişken çeşididir. Basit olarak değer türünden (value types) sabit bir değişkeni aşağıdaki gibi tanımlayabiliriz.


    public const double PI = 3.14;;

    Çağırırkende şu şekile çağırılabilir :


    double pi = Derived.PI;

    yani yazılmamış olsa bile cons değişkenler static değişkenlerdir bu yüzden bir const değişken tanımlarken static kelimesini eklersek tanımlamaya hata alırız.

    • Readonly referanslar.

    Constant’ lar derleme zamanında (compile time) tanımlanan değişkenler için geçerlidir. Bu nedenlede sadece değer türlerine (value types) uygulanabilirler. Oysaki bazı durumlarda sabit olarak tanımladığımız değişkenlerin değerleri çalışma zamanında belirlenebilir. Bu nedenle referans tiplerini sabit olarak kullanılabilmek için readonly tanımlarız. Bununla ilgilide örneğimizi şu şekilde genişletebiliriz :


         public class Dikdortgen
        {
             //Dikdortgen sınıfı ile ilgili diğer kodlar.
            public static int kontrolAlani = 20;
            //public Dikdortgen()
            //{
            //    kontrolAlani = 25;
            //}
            //Bu sefer statik constructer kullandık.
            static Dikdortgen()
            {
                kontrolAlani = 35;
            }
            public void KontrolAlaniDegistir()
            {
                kontrolAlani = 30;
            }
            public static int AlanHesapla(int aKenari, int bKenari)
            {
                return aKenari * bKenari;
            }

            public bool AlanKontorlu(int aKenari, int bKenari,int kontrolAlani)
            {
                if (kontrolAlani > AlanHesapla(aKenari, bKenari))
                    return true;
                else
                    return false;
            }
        }
        public class Sekiller
        {
            public static readonly Dikdortgen dikdortgen;

            static Sekiller()
            {
                dikdortgen = new Dikdortgen();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Dikdortgen dikdortgen1 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                dikdortgen1.KontrolAlaniDegistir();

                Dikdortgen dikdortgen2 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen3 = new Dikdortgen();
                Console.WriteLine(Dikdortgen.kontrolAlani);

                Dikdortgen dikdortgen4 = Sekiller.dikdortgen;

                Console.ReadLine();
            }
        }

    7 yorum :

    1. Teşekkürler gayet açıklayıcı olmuş

      YanıtlaSil
    2. Teşekkürler. Emeğinize sağlık.

      YanıtlaSil
    3. Çok güzel anlatmışsınız teşekkürler.

      YanıtlaSil
    4. web serviste neden Static olarak tanımlanan bir metodu kullanamıyoruz?

      YanıtlaSil
    5. Sitede this anahtar sözcüğünün kullanımına dair bir makale bulamadım ? yardımcı olmanızı istiyorum !

      YanıtlaSil
    6. Teşekkürler.

      YanıtlaSil
    7. Geniş kapsamlı güzel bir anlatım yapmışsınız teşekkürler.

      YanıtlaSil