.NET Framework’ta nesneler, statik(static) veya statik olmayan(non-static) üyelerden oluşur. Statik olmayan üyeler, class’tan türetilmiş nesnenin üyeleridir, sınıftan kaç nesne türetilmişse bu üyelerin o kadar kopyası bulunur, bir nesneye ait üyenin değerinin değişmesi, o üyenin diğer nesnelerdeki değerini etkilemez. Statik üyeler ise, doğrudan class’ın kendi üyeleri olup class’tan üretilen nesneden bağımsız hareket ederler. Tüm nesnelerin ulaşabileceği ortak bir bellek alanında tutulur. Bu nedenle statik üyelere erişmek için class’tan bir nesne oluşturmaya gerek yoktur. Bu da statik üyelerle işlem yapmayı hızlandırır. Bütün statik üyeler, değer veya referans türü olup olmamasına bakılmaksızın hafızanın heap alanı üzerinde depolanır. Bu heap alanına 8 byte’lık bir pointer işaret eder. Kaç tane instance’in yaratıldığı önemli olmayıp her zaman tek bir hafıza slotu varlık gösterir.
Durağan üyeler veya global değişkenler olarak ta tanımlanan statik üyeler, C# tarafında static, VB.NET tarafında shared anahtar sözcüğüyle deklare edilir. Statik üyelerin ilk değeri tanımlanmamışsa, çalışma zamanında üyenin tipine göre değer verilir yani sayısal bir data türüyse “sıfır”, nesne ise “nothing” veya “null”, boolean türündeyse “false” değeri atanır. Hatırlarsanız C#’ta metodlar içindeki yerel değişkenleri kullanmak için ilk değerlerini vermek zorundaydık. Fakat bu zorunluluk sınıflara ait değişkenler için geçerli değildir.
Sadece değişkenler değil, method, event, property’leri hatta C# 2.0 ile birlikte class’ları da statik olarak deklare edebiliriz. Statik üyeler, sınıfla birlikte yüklenir ve uygulama sonlandırılana kadar yaşarlar.
Class Islem Private _sayi As Integer Public Shared Sub KareAl(ByVal Sayi As Integer) Console.WriteLine("Sayının karesi :" + Sayi * Sayi) End Sub End Class
class Islem { private int _sayi; public static void KareAl(int Sayi) { Console.WriteLine("Sayının karesi :" + Sayi * Sayi); }//KareAl } //Islem
Aşağıdaki örnekte Islem sınıfının MagazaKod, Indirim ve SiparisKod isimli üç değişkeni bulunmaktadır. MagazaKod ve Indirim, statik, SiparisKod ise statik olmayan üye olarak tanımlanmıştır. SiparisKod üyesine erişmek için sınıftan bir nesne üretmek gerekirken, MagazaKod ve Indirim üyelerine erişmek için doğrudan sınıfı kullanmak yeterlidir.
Sub Main() Console.WriteLine("Statik MagazaKod değeri : {0}", Islem.MagazaKod) 'Console.WriteLine("Statik olmayan SiparisKod değeri : {0}", Islem.SiparisKod) 'Bu satır "Reference to a non-shared member requires an object reference." hatasını verir. Dim objIslem As New Islem Console.WriteLine("Statik olmayan SiparisKod değeri : {0}", objIslem.SiparisKod) Console.WriteLine("Statik Indirim değeri : {0}", Islem.Indirim) End Sub Class Islem Public SiparisKod As Integer = 45 Public Shared MagazaKod As String = "ES2005" Public Shared Indirim As Boolean End Class
public static void Main(){ Console.WriteLine("Statik MagazaKod değeri : {0}", Islem.MagazaKod); //Console.WriteLine("Statik olmayan SiparisKod değeri : {0}", Islem.SiparisKod) //Bu satır "An object reference is required for the nonstatic field, method, or property 'Islem.SiparisKod'" hatasını verir. Islem objIslem = new Islem(); Console.WriteLine("Statik olmayan SiparisKod değeri : {0}", objIslem.SiparisKod); Console.WriteLine("Statik Indirim değeri : {0}", Islem.Indirim); }//Main public class Islem { public int SiparisKod = 45; public static string MagazaKod = "ES2005"; public static bool Indirim; }//Islem
Sonuç
Statik MagazaKod değeri : ES2005
Statik olmayan SiparisKod değeri : 45
Statik Indirim değeri : False
Durağan üyeler konusunda önemli bir nokta da şudur; bu üyelere, VB.NET tarafında bir instance yani bir nesne üzerinden erişilebilirken, C# tarafında bir nesne üzerinden erişilemez. Yukarıdaki örnek için;
Dim objIslem As New Islem objIslem.MagazaKod = "RT45" 'Uygun bir tanımlama
Islem objIslem = new Islem(); objIslem.MagazaKod="s"; //"Static member 'Islem.MagazaKod' cannot be accessed with an instance reference; qualify it with a type name instead" hatasına neden olur
Statik metodlar sadece statik metodlara erişebilir. Örnekte Statik() isimli metod, Normal() isimli metoda erişmeye çalıştığında hata oluşacaktır.
Class Islem Public Shared Sub Statik() Normal() 'Bu satır hata verir. End Sub Sub Normal() 'işlem kodları End Sub End Class
public class Islem { public static void Statik() { Normal(); //Bu satır hata verir. } public void Normal() { //işlem kodları } }//Islem
Sadece normal metodlar değil constructor’ler de statik olarak tanımlanabilir. Statik constructor’ler;
Static olarak tanımlanmış üyeler, sınıfla birlikte yüklenirler demiştik. Bunu statik olarak tanımlanmış constructor örneği yaparak görebiliriz. Aşağıdaki örnekte Islem sınıfının statik ve statik olmayan iki yapılandırıcısı bulunmaktadır.
Sub Main() Dim objIslem1 As New Islem Dim objIslem2 As New Islem Dim objIslem3 As New Islem Console.ReadLine() End Sub Class Islem Shared Sayac As Integer Shared Sub New() Console.WriteLine("Statik yapılandırıcı çalıştı.") Console.WriteLine("------------------------------") End Sub Public Sub New() Sayac += 1 Console.WriteLine("{0}. Nesnenin yapılandırıcısı çalıştı.", Sayac) End Sub End Class
public static void Main(){ Islem objIslem1 = new Islem(); Islem objIslem2 = new Islem(); Islem objIslem3 = new Islem(); Console.ReadLine(); }//Main public class Islem { public static int Sayac; static Islem() { Console.WriteLine("Statik yapılandırıcı çalıştı."); Console.WriteLine("------------------------------"); } public Islem() { Sayac += 1; Console.WriteLine("{0}. Nesnenin yapılandırıcısı çalıştı.", Sayac); } }//Islem
Sonuç
Statik yapılandırıcı çalıştı.
------------------------------
1. Nesnenin yapılandırıcısı çalıştı.
2. Nesnenin yapılandırıcısı çalıştı.
3. Nesnenin yapılandırıcısı çalıştı.
Görüldüğü gibi sınıftan bir nesne oluşturmaya çalıştığımızda öncelikle statik constructor çalıştı daha sonra nesnenin normal constructorü çalıştı. Statik üyeler, sınıfa ait olduğu için ne kadar nesne oluşturulursa oluşturulsun statik constructor bir kere yüklenir ve tüm nesneler aynı adrese erişir.
Konunun en can alıcı noktaları ve incelikleri güzel örneklerle pekiştirilerek anlatılmış, teşekkürler.
çk tşk ederim hayatım kurtuldu:)))))
Static ve shared taglarının ne gibi farkları olduğunu araştırıyordum. Baya açıklayıcı anlatmışsınız. Konuyu kavramamıza yardımcı olduğunuz için teşekkür ederim.
süper olmuş allah razı olsun:)
ÖNemli noktaları üzerine basa basa belirtmişsiniz. Klasik konu anlatımlarından uzak ama çok güzel bir yazı.