Makale Özeti

Partial sınıflar, tek bir sınıfın "partial" sözcüğü kullanılarak birden fazla dosyada (elbette ki tek bir dosya içerisinde de olabilir) ayrık şekilde tanımlanabilmesine olanak veriyor. Bu sayede sınıfımız içerisinde yer alan özellikleri, methodları, değişkenleri ve akla gelebilecek her türlü şeyi hangi ayrık parça içerisinde tanımlarsak tanımlayalım, diğer parçalarda da kullanabilme olanağımız mevcut.

Makale

.NET'i en az 1 kere kullananlar bileceklerdir, .NET Framework 1.0 ve 1.1'de yazmak istediğiniz bir class, struct ve ya interface'i tek bir dosya üzerinde yazmamız gerekirdi. Bu durum da bazı dosyalarımızın binlerce satırı bulması ve her ne kadar "region" özelliğini kullansak da, kodumuzu içinden çıkılmaz bir hale getirirdi.

Örneğin hazırladığınız bir Web formunda ve ya bir Windows formunda, designer'ın kullanması gereken tüm değişkenleri ve özellik atamalarını bizim kodumuz içerisinde yer alırdı. Bu da her ne kadar büyük bir sorun teşkil etmese de, kodda karışıklığa neden oluyordu.

Elbette ki bunun da bir çözümü vardı. Sınıfları farklı sınıf isimleriyle oluşturmak ve birbirlerinden türemelerini sağlamak, böylece en sonunda oluşacak sınıfı kullanmak fakat farklı isimlerde bir sürü sınıfa sahip olmak. Sonuç olarak bir sınıfın base sınıfının içerisindeki public method'lara ulaşabileceğini hepimiz biliyoruz.

Şimdi ise, .NET Framework ile hayatımıza giren yepyeni bir sınıf tipiyle karşı karşıyayız: "Partial" (parçalı-ayrık) sınıflar.

Partial sınıflar, tek bir sınıfın "partial" sözcüğü kullanılarak birden fazla dosyada (elbette ki tek bir dosya içerisinde de olabilir) ayrık şekilde tanımlanabilmesine olanak veriyor. Bu sayede sınıfımız içerisinde yer alan özellikleri, methodları, değişkenleri ve akla gelebilecek her türlü şeyi hangi ayrık parça içerisinde tanımlarsak tanımlayalım, diğer parçalarda da kullanabilme olanağımız mevcut.

Bu noktada ayrık sınıflar ile ilgili ilk örneğimiz aslında Visual Studio 2005 tarafından bize sunuluyor. Visual Studio içerisinde yarattığınız herhangi bir Windows formun, aslında direkt olarak "partial" sözcüğü ile tanımlandığını görüyoruz. Örneğin "Form1" isminde bir ekran yaratmak istedik. Visual Studio 2005 bizim için otomatik olarak "Form1.Designer.cs" ve ya VB.NET kullanıyor iseniz "Form1.Designer.vb" isminde bir dosya yaratıyor ve designer'ın kodumuza ekleyeceği tüm method ve özellikleri kendisi burada yazıyor. Böylece bizim ekranımızın iş kuralları ile ilgili yazacağımız tüm kodlar, designer.cs dosyasında ise Visual Studio 2005'in yazdığı tüm kodlar ayrıştırılmış şekilde bulunuyor.


Basit bir örnek ile yazım tarzını göstermek gerekirse:

Yeni bir Windows Uygulaması projesi yaratıp, myClass1.cs isminde bir dosya oluşturarak içerisine aşağıdaki kodu yazalım.

public partial class myClass
{
   public void MethodX()
   {
      MessageBox.Show ( degisken );
   }
}


Şimdi de myClass2.cs isminde bir dosya oluşturup, içerisine aşağıdaki kodu ekleyelim.

public partial class myClass
{
   public string degisken = "İlk partial class örneğimiz!";

   public void MethodY()
   {
   MethodX();
   }
}


Daha sonra da projemiz içerisinde otomatik olarak tanımlanmış olan "Form1" formunun "OnLoad" event'i içerisinde aşağıdaki kodu ekleyelim:

myClass m_Class = new myClass();
m_Class.MethodY();


Programı çalıştırdığınızda göreceksiniz ki, ekranda "İlk partial class örneğimiz!" çıktısına sahip bir uyarı belirecek.

Kodun çalışma mantığını kısaca açıklamak gerekirse;
Yeni bir kopyasını "m_Class" ismiyle yarattığımız "myClass" tipindeki sınıfımızın "MethodY" method'unu çağırdık. Bu method, içerisinde bulunduğu sınıfın ayrık bir parçası olan "MethodX" method'unu çağırdı. MethodX method'u da kendisi haricindeki ayrık parçada bulunan "degisken" ismindeki değişkeni MessageBox sınıfının Show static method'u ile ekranda gösterdi. Buradaki en önemli nokta, kodun derlenmesi sonucu oluşan MSIL (Microsoft Intermediate Language) kodunun sizin tüm ayrık parçalarınızı bir araya getirmesi. Yani derleyici tüm ayrık parçaları bulup, birleştirip, tek bir parçaymış gibi davranıyor. MSIL'in oluşturduğu kod tabi ki aşağıdakine benzemeyecek fakat gözünüzde canlanması için yapılan işin sonucunu tanımlayacak bir sınıf belirtiyorum:

public class myClass
{
   public void MethodX()
   {
      MessageBox.Show ( degisken );
   }

   public string degisken = "İlk partial class örneğimiz!";

   public void MethodY()
   {
      MethodX();
   }
}

Oluşturulan sınıfımız, artık "partial" sözcüğüne sahip değildir. Çünkü tüm sınıflar birleştirilip, tek bir sınıf oluşturulmuştur.


Şimdi dilerseniz "partial" sözcüğünün genel kullanımından bahsedelim.

Öncelikle "partial" sözcüğünün sadece sınıflar için değil "struct" ve "interface"ler içinde kullanılabileceğini fakat "enum" (enumeration)'lar için kullanılamayacağını belirtelim.

  • Tüm ayrık parçalar, kendilerine özel "using" ve "Imports" değerlerine sahip olabilirler.
  • Eğer ayrık sınıflarınızdan sadece 1 tanesi "sealed" olarak tanımlanırsa, tüm sınıf "sealed" olarak varsayılacaktır.
  • Eğer ayrık sınıflarınızdan sadece 1 tanesi "abstract" olarak tanımlanırsa, tüm sınıf "abstract" olarak varsayılacaktır.
  • Tüm sınıflar aynı erişilebilirlik düzeyinde olmalıdır. Örneğin ayrık sınıfınızın bir parçası "public" tanımlandı ise ve diğerlerinde herhangi bir erişilebilirlik tanımlaması yapılmadı ise, tüm sınıfınız "public" olarak kabul edilir. Ancak ayrık parçalardan bir tanesini "public", bir diğerini ise "private" yapma şansınız yoktur.
  • Tüm ayrık parçalara, farklı farklı attribute'ler tanımlayabilirsiniz. Fakat derlenme aşamasında oluşan tek bütün parça (yukarıda bahsetmiştim), ayrık parçalarınız üzerinde tanımlamış olduğunuz tüm attribute'lere sahip tek bir sınıf yaratacaktır. Bunu aşağıdaki şekilde örnekleyebiliriz:

    [Attribute1()]
    public partial class myClass
    {
       // kod1
    }

    [Attribute2()]
    public partial class myClass
    {
       // kod2
    }

    kodunu yazdığınızda, derlenme sonucu ortaya çıkacak sınıf aşağıdaki gibi olacaktır:

    [Attribute1(), Attribute2()]
    public class myClass
    {
       // kod1
       // kod2
    }
  • Tüm ayrık parçalar aynı sınıfı base almalıdır. Ayrık parçalardan bir tanesini "System.Windows.Forms.Form" sınıfından türetirseniz ve diğer ayrık parçalara herhangi bir base sınıf tanımlamaz iseniz, tüm parçalar "System.Windows.Forms.Form" sınıfını base alır. Ancak bir parçanızı "System.Windows.Forms.Form" sınıfından, diğer bir parçanızı "System.Windows.Forms.Button" sınıfından base alacak şekilde yazarsanız, derleme işlemi başarısızlıkla sonuçlanır.
  • Fakat yukarıdaki maddenin aksine, ayrık parçalar kendilerine özel interface'leri implement edebilirler. Normal olarak ayrık parçalardan birisinin "IMyInterface" interface'ini implement ettiğini düşünürseniz, diğer ayrık parçaların bunu implement etmesine ihtiyaç yoktur. Fakat .NET Framework 2.0 buna izin vermektedir. Ayrıca buradaki en önemli nokta, ayrık parçalardan birisinde implement edilen bir interface'in sahip olduğu method'ları, diğer ayrık parçanın implement edebilmesidir. Örnek vermek gerekirse aşağıdaki kod düzgün bir şekilde derlenebilecektir:

    public partial class myClass : IMyInterface
    {

    }

    public partial class myClass
    {
       string IMyInterface.Method1()
       {
          // kod
       }
    }
  • Ayrık parçalardan bir tanesi içerisinde tanımladığınız değişkeni bir diğer parçada kullanabilirsiniz fakat aynı isimde bir değişkeni farklı parçalar içerisinde tanımlayamazsınız. Aşağıdaki kodu derlemek istediğinizde hata alırsınız:

    public partial class myClass
    {
       string degisken = "a";
    }

    public partial class myClass
    {
       string degisken = "b";
    }
  • "partial" olarak tanımladığınız bir sınıf içerisinde tanımladığınız alt bir sınıf, yine parçalı olarak tanımlanabilir. Örneğin:

    public partial class myClass
    {
       partial class myChildClass
       {
          // kod1
       }
    }

    public partial class myClass
    {
       partial class myChildClass
       {
          // kod2
       }
    }



Coskun SUNALI
http://net.tr.gen.tr