C# Birden Çok Windows Formu Yönetme



Bir windows form uygulaması yazarken genelde tek bir form bize yeterli olmayacaktır. Bu yüzden uygulamalarımızda birden çok form kullanırız. Fakat birden çok form kullandığımızda bunları yönetme biraz sorun olacaktır. Bu tuşa basınca onu kapa bunu aç falan diye bir sürü sorun gelecektir ve gelmiştirde karşımıza. Bunun için güzel bir yöntem paylaşacağım sizinle. Öncelikle birden çok formumuz varsa herbirinin instance'ını içinde barıdıran public bir class yazın :

public class ManageForms
{
public Form Form1;
public Form Form2;
public Form Form3;

public Static HideForm(System.Windows.Forms.Form frm)
{
if(frm != null)
frm.Hide();
}
}

//ManageForm class'ı içinde tanımladığımız Form1 insatance'ına Form1 load ederken kendisini bind ediyoruz.
private void Form1_Load(Object Sender, System.EventArgs e)
{
ManageForms.Form1 = this;
}
ManageForm class'ı içinde tanımladığımız Form1 insatance'ına Form1 load ederken kendisini bind ediyoruz. Ve bu şekilde bu class üzerinden artık Form1'e kolayca ulaşabiliriz. Ayni zamanda bu formları Hide etmek içinde yazdığımız HideForm metodunu kullanabileceğimiz gibi bu class'ın içine Hide gibi form üzerinde devamlı yaptığımız işlemleri tanımlayıp kolayca ugulamanızdaki formları yönetebilirsiniz.

C# Interface(Arayüz) Kullanımı



Interface kelimesinin çevirisi "Arayüz"dür. Interface başka sınıflar için rehberdir. Bu şu anlama gelir Interface içinde hiç bir şekilde kod yazılarak işlem yapılmaz, mesela topla metodu yazıp iki sayı toplayan kod yazamayız. Peki işlem yapmıyorsak bu bizim ne işimize yarıyor? Interface'in anlamını yazarken başka sınıflar için rehberdir demiştim. C#'ta bildiğiniz gibi çoklu kalıtım söz konusu değil. Eskiden C++'ta bu olsa bile zamanla proje büyüdükçe kodun okunurluğunu yok ettiğini düşünen Microsoft dil geliştiricileri C#'ta bu özelliği kaldırmışlar. Yani C#'ta bir class sadece bir class'ı inherit edebilir. Ama bunun yanında birden çok Interface'i inherit etmesine izin verilmiştir.


Interface Tanımlama :

Interface tanımlarken nasıl class tanımlarken class anahtar sözcüğünü kullanıyorsak bunda da "interface" anahtar sözcüğünü kullanıyoruz. Arayüz isminin başında I harfi kullanıldığına dikkat edin. Bu kullanılan sınıfın bir arayüz olduğunu anlamamıza yarayan bir isim kullanma tekniğidir. Bu sayede, sınıfların kalıtımsal olarak aldığı elemanların arayüz olup olmadığını daha kolayca anlayabiliriz.


Örnek bir interface tanımı:

public inteface IDeneme
{

}
Arayüzlerin Sahip Olabileceği Üyeler :

- Özellikler (properties)
- Metodlar (methods)
- Olaylar (events)
- İndeksleyiciler (indexers)


Arayüzlerin Sahip Olamayacağı Üyeler :

- Yapıcılar (constructors)
- Yokediciler (destructors)
- Alanlar (fields)

Herşeyden önce arayüzler ile ilgili en önemli kural onun bir rehber olmasıdır. Yani arayüzler sadece, kendisini rehber alan sınıfların kullanacağı üyeleri tanımlarlar. Herhangi bir kod satırı içermezler. Sadece özelliğin, metodun, olayın veya indeksleyicinin tanımı vardır. Onların kolay okunabilir olmalarını sağlayan ve çoklu kalıtım için tercih edilmelerine neden olan sebepte budur.


Interface Kullanırken Uyulması Gereken Kurallar :

1 Bir arayüz'ün tüm üyeleri public kabul edilir. Private, Protected gibi belirtiçler kullanamayız. Bunu yaptığımız takdirde örneğin bir elemanı private tanımladığımız takdirde, derleme zamanında şu hatayı alırız. "The modifier 'private' is not valid for this item"
2 Diğer yandan bir metodu public olarakta tanımlayamayız. Çünkü zaten varsayılan olarak bütün üyeler public tanımlanmış kabul edilir. Bir metodu public tanımladığımızda yine derleme zamanında şu hatayı alırız. "The modifier 'public' is not valid for this item"
3 Bir arayüz, bir yapı(struct)'dan veya bir sınıf(class)'tan kalıtımla türetilemez. Ancak, bir arayüzü başka bir arayüzden veya arayüzlerden kalıtımsal olarak türetebiliriz.
4 Arayüz elemanlarını static olarak tanımlayamayız.
5 Arayüzlerin uygulandığı sınıflar, arayüzde tanımlanan bütün üyeleri kullanmak zorundadır.

public interface IArayuz
{
            string ParametreGetir();
            int ParametreSayısı
            {
                        get;
                        set;
            }            

            string ParametreAdi
            {
                 get;
                 set;
            }
}

Yukarda görüldüğü gibi IArayüz tanıladık. Bu arayüzümüzde ParametreGetir() metodunu ve ParametreSayısı,ParametreAdi property'lerini tanımladık. Ve interface yaratma kurallarından bahsederken söylediğim gibi tanımlama dışında hiç bir kod parçacığı bulunmamaktadır. Şimdi bir class yazdığımız IArayuz arayüzünü inherit ederse bu iki propery'i ve bir metodu kullanmak zorundadır yoksa compile ederken hata alınır. Örnek bir kullanım yaparsak :

public class Bilgiler:IArayuz

            public int _deneme;
            public string ParametreGetir()

           {
               Console.WriteLine("Parametreler Hazır...");
           }
            public int ParametreSayısı
            {
                        get;
                        set;
            }            

            public string ParametreAdi
            {
                 get;
                 set;
            }
}

şeklinde IArayuz içinde tanımlamasını yaptığımız her üye bu class içinde kullanmalıdır.


Çoklu Kalıtım :


Çoklu kalıtımın bir önceki örneğimizde yaptığımız tanımlamadan hiç bir farkı yoktur. Böyle bir tamımlama yaparken düşünelim ki IArayüz'ün yanında IParametre diye ikinci bir Interface'imiz olsun BilgiGoster sınıfı bu iki arayüzüde inherit ediyorsa tanımlama şöyle olur : 


public class BilgiGoster:IArayuz,IParametre
{
    //Tanımlamalar
}


ve bu BilgiGoster tanımlama class'ı her iki Interface içinde tanımlanan tüm üyeleri kullanmak zorundadır. Peki ya bu iki Interface içinde ayni isme sahip metod varsa ne olacak? Örneğin metodumuzun ismi Kaydet(); olsun. Bu durumda sadece bir kere kullanmak yeterli olacaktır. Ama bu iki metod ayni görevi yapmıyorsa bu durumda


IArayuz.Kaydet()
{
}


IParametre.Kaydet()
{
}


şeklinde iki tanımlamayıda yapmak sorunumuzu çözecektir. Bu metodları program içinde çağırırkende şunu kullanırız :


BilgiGoster bg = new BilgiGoster();
IArayuz a = (IArayuz)bg;
IParametre p = (IParametre)bg;


a.Kaydet();
p.Kaydet();


şeklinde hangi arayüzdeki parametreyi kullanıcaksak onu çağırmayı sağlayabiliriz.


Bu yazımında sonuna geldik umarım yardımcı olmuşumdur. Hoşçakalın..

Yararlanılan Kaynaklar : CSharpNedir

C# Polymorphism, Method Hiding and Overriding



Polymorphism Nesneye Yönelik programlamanın önemli kavramlarından biridir. Yunanca'da "bir çok şekil" anlamına gelmektedir. Nesneye yönelik programlamada ise en genel anlamda oluşturduğumuz nesnelerin gerektiğinde başka bir nesneymiş gibi davranabilmesine polimorfizm denilmektedir.

Inherited Metod

Foo() diye bir metod A base clasında yaratılsın ve B class'ı A class'ından türetilsin bu durumda B class'ı Foo() metodunu tanımlamadığı halde base class'ında bulunduğu için bunu kullanabilir.

    using System;
    namespace Polymorphism
    {
        class A
        {
            public void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A {}

        class Test
        {
            static void Main(string[] args)
            {
                A a = new A();
                a.Foo();  // çıktı --> "A::Foo()"

                B b = new B();
                b.Foo();  // çıktı--> "A::Foo()"
            }
        }
    }
     
Virtual and Overridden Metodlar

B class'ımız için bu sefer A clasında tanımlanan Foo() metodu yetersiz gelsin. Bu durumda B class'ımız içinde bu Foo() metodunu override etmemiz gerekmektedir. Bunun için A (base class) içinde Foo() metodu tanımlanırken "virtual" keyword'ünün kullanılması gerekmektedir. B class'ı(derivered class) içinde Foo() metodu override edebilmemiz içinse "override" keywor'ünü kullanmamız gerekmektedir. Bu kodu yazarsak:

    using System;
    namespace Polymorphism
    {
        class A
        {
            public virtual void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A
        {
            public override void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // çıktı--> "A::Foo()"
                b.Foo();  // çıktı--> "B::Foo()"

                a = new B();
                a.Foo();  // çıktı--> "B::Foo()"
            }
        }
     }
Metod Hiding

Eğer A a = new B(); şeklinde bir instance oluşturup a.Foo(); dediğimizde A(base class) içindeki Foo() metodunun çalışmasını, B(derivered class) içerisindeki Foo() metodunu saklanmasını istiyorsak B(derivered class) içerisine Foo(); metodu tanımlanırken new keywors'ü kullanılır. Örnek kodu yazarsak:

    using System;
    namespace Polymorphism
    {
        class A
        {
            public void Foo() { Console.WriteLine("A::Foo()"); }
        }

        class B : A
        {
            public new void Foo() { Console.WriteLine("B::Foo()"); }
        }

        class Test
        {
            static void Main(string[] args)
            {
                A a;
                B b;

                a = new A();
                b = new B();
                a.Foo();  // çıktı -->; "A::Foo()"
                b.Foo();  // çıktı-->; "B::Foo()"

                a = new B();
                a.Foo();  // çıktı--> "A::Foo()" base class içindeki Foo() çalıştı
            }
        }
    }  


Polimorfizm

Polimorfizm kavramının kullanımına bir örnek vericek olursak yukarıda A(base class) ve B(derivered class) tanımlamaları yaptık. B class'ı A class'ından türetildiği için B'nin bir instance'ını şu şekilde tanımlayabiliriz :

A a = new B();

bunu yapabilmemizin nedeni C# taki polimorfizm'dir. Polimorzime başka bir örnek verecek olursak:

diyelimki A class'ı türünden değer alan Foo(A a); fonksiyonumuz olsun. Bu durumda bir bu Foo() fonksiyonuna upcasting yaparak Foo(b) şeklinde compile hatası almadan b nin bir instance'ını yollayabiliriz. İşte bu şekilde nesnelerin gerektiğinde başka bir nesneymiş gibi davranabilmesine polimorfizm denilmektedir. En genel anlamıyla Polimorphism budur.

Yararlanılan Kaynaklar : akadia



C# Class Diagram Oluşturmak



C# uygulamaları yazarken nesneye yönelik bir yapı kullanırız. Bu yapı içerisinde birbirlerinden türetilen class'lar, bu class'ların Field,Metot ve Propery'leri vardır. Class Diagram bu class'lar araşındaki ilişkiyi görsel olarak gösteren bir diyagram oluşturmamıza olanak sağlar. Bu bize bir çok konuda yardımcı olsada en basit anlamda program içinde yarattığımız class'lar arası ilişkiyi görsel olarak görerek yeni ilişkileri daha rahat kurabilmemizi sağlar.

Bu diagramın en önemli özelliği örneğin bir diyagram oluşturup bu diagrama bi class eklediyseniz o class'ın koduna Field,Property veya metod eklersek diyagram otomatik olarak değişmektedir. Bu durumun terside söz konusudur yani eğer diagram üzerindeki bir class'a diagram üzerinden Field,Property veya Metod eklersek kodunu class'ın içine otomatik olarak eklemektedir.

Class Diagram Ekleme :

Projenin üstüne gelip Add -> New Item 'a tıklanıp Class Diagram seçilirse projemize Class Diagram eklemiş oluruz.

visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

Class Diagramımızı eklememizin ardından diagramın üstüne sağ tıklayıp Add -> Class dersek projemizde bulunan bir class'ı veya yeni bir class oluşturup o class'ı diagrama ekleyebiliriz.

visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

Artık diyagramımıza eklediğimiz class'ın kod kısmında class'a Property,Field veya Metod eklediğimizde bu yaptığımız değişiklikler diyagramımıza otomatik olarak yansıyacaktır. Daha önce bahsettiğim gibi tam terside geçerlidir. Diyagramımıza eklediğimiz class'a diyagram üzerinde Property,Field veya Metod eklersek bunların tanımlamaları kod kısmında otomatik olarak yazılmaktadır. Yani class'larımızı dizayn ederken hem kod hemde diyagramları kullanabiliriz.

visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

Class'larımız arasında kalıtım(inheritance) varsa veya şemadan bakarak inheritance yapıyı oluşturmak istersek toolbox içirisindeki Inheritance özelliğini kullanarak bu class'lar birbirinden türetebiliriz.


visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

Class Diagram'ı ile bir class'ın Interface'ini üretmek istiyorsak yapmamız gereken işlem ise diyagram üzerinde class'a sağ tıklayıp Refactor-> Exract Interface... denemmiz yeterli olacaktır.

visual studio class diagram,c# class diagram, class diagram oluşturmak, how to create class diagram

Son olarakta bu oluşturduğumuz diyagramı başka yerlerde örneğin proje dökümantasyonunda kullanmak isteyebiliriz böyle bir durumda Visual Studio bize bu diyagramı resim olarak export etmemizi sağlar. Bunun için yapılması gereken tek şey diyagramın üstüne sağ tıklayıp "Export Diagram As Image.." demektir.



Bu yazımda Visual Studio 2008 kullanarak Class Diagram'ları nasıl oluşturulur ve kullanılır sorusuna cevap vermeye çalıştım umarım size yararlı olmuştur. Bir sonraki yazımda görüşmek üzere.



C# Struct(Yapı) ile Class(Sınıf) Kavramları Arasındaki Farklar



Bir çok kez bu kavramlarla karşılaştım fakat tam olarak farkları nedir? bu sorunun cevabını tam olarak bulamamıştım. Sonuçta ikiside ayni şekilde tanımlanıyor, ikisininde efendim propery'leri, değişkeleri, constructor'ları var falan filan.. Bu yüzden bu konuyla ilgili bir araştırma yaptım öğrendiklerimi sizle paylaşıyorum bu konuda benim gibi düşünenler varsa onları aydınlatırsam ne mutlu bana..

Herşeyden önce en önemli fark, yapıların değer türü olması yani belleğin stack bölümünde ve sınıfların referans türü olması yani belleğin heap bölümünde depolanmasıdır. Sınıflar referans type olduğu için adresleri tutarlar, yapılar ise değer türü olduğu için verinin kendisini tutarlar. Bu yüzden büyük boyutlu yapılar için sınıf tanımlamasını seçmek daha mantıklıdır.

Diğer bir fark ise Struct yapısı için default constructor yazamayız. Ancak çok parametreli constructor yazmaya izin verir. Çok parametreli constructor yazarkende dikkat edilmesi gereken nokta tanımlanan değerlere eğer çok paramtereli contructor yazdıysak ilk değerini otomatik atamaz yani her değere ilk değerini atamak zorunda oluruz. Buna default constructor kullanıyorsak gerek yoktur.

using System; 

namespace StructSample1
{           
      struct Zaman
      {
           private int saat,dakika,saniye;
           private string kosucuAdi;                       

          /* Yapı için parametreli bir constructor metod tanımladık. Yapı içinde yer alan kosucuAdi,saat,dakika,saniye alanlarına ilk değerlerin atandığına dikkat edelim. Bunları atamassak derleyici hatası alırız. */

           public Zaman(string k,int s,int d,int sn)
           {
                kosucuAdi =k;
                saat =s;
                dakika =d;
                saniye =sn;
           } 

          /* Bir dizi özellik tanımlayarak private olarak tanımladığımız asıl alanların kullanımını kolaylaştırıyoruz. */
           public string Kosucu
           {
                get
                {
                     return kosucuAdi;
                }
                set
                {
                     kosucuAdi =value;
                }
           }

           public string Saat
           {
                get
                {
                     return saat;
                }
                set
                {
                     saat =value;
                }
           }

           public string Dakika
           {
                get
                {
                     return dakika;
                }
                set
                {
                     dakika =value;
                }
           }


           public string Saniye
           {
                get
                {
                     return saniye;
                }
                set
                {
                     saniye =value;
                }
           }
      } 
code: csharpnedir.com

C# Destructor Kullanımı



Constructor'un tam tersidir. Yani Constructor nasıl nesne oluştururken atanan özellikleri içeriyorsa Destructor'da nesne yok edilince harekete gecen prosedür'dür. Her class sadece bir Destructor'a sahip olabilir.

Destructor Tanımı:

class Car
{
    ~Car()  // destructor
    {
        // temizleme işlemi
    }
}


C# Property Kavramı



Daha önceki Encapsulation yazımda bir class içerisindeki bazı field'ları kullanıcıdan saklamak olduğunu telefon örneği vererek açıklamıştım. Kısaca hatırlarsak Encapsulation telefonun düğmeleri ortada (public) dururuken bir çok parça telefonun içerisinde gizildir (private). Zaten kullanıcının bunları kullanması gerekmez hatta dokunmaması gerekir. Aynı şekilde bir nesnenin kendinde bulunan bileşenleri kötü niyetli veya bilinçsiz kullanımlardan gizlemesi gerekir. İşte bu bileşenlerden bazılarına değiştirme, ulaşma veya her ikisinide vermek isteyebilirsiniz bu durumda property kullanırız. VS'de kısaca property tanımlamak için "prop" yazılıp iki kere "Tab" tuşuna basmak yeterlidir.

    class Class1
    {

        //Hem getter hemde setter'ı bulunan propery
        public string Name { get; set; }

        //Write Only Property : sadece setter'ı bulunan property
        public string Surname { set; }

        //Read Only Propery : sadece getter'ı bulunan property
        public string Fullname { get; }
    }

C# Field Tanımlama İpucu



C#'ta class tanımlarken Field tanımlarız yani bunlar bizim değişkenlerimizdir. Bunları tanımlarken değişken adlarının başına alttan tire "_" koymak iyi programlama ipuclarından biridir. Bu kodumuzu daha okunur hale getirir. Örnek bir class yazacak olursak :

public class FieldExample
{
    private string _name;
    private string _surname;

    public void makeFullName(string fullName)
   {
       fullName = _name + _surname;
    }
}

C# Encapsulation Nedir?



Bir nesnenin bazı özellik ve işlevlerini diğerlerinden saklanabilmesi, erişimin sınırlandırılabilmesidir. Yani private tanımladığımız field'ları kullanıcıdan saklamamız anlamına gelir ki zaten kullanıcının bunu kullanmasına gerek yoktur ve hatta kullanmaması gerekmektedir. Encapsulation'u bir telefona benzetebiriz.  Telefonun düğmeleri ortada ('public') dururuken bir çok parça telefonun içerisinde gizildir (private). Zaten kullanıcının bunları kullanması gerekmez hatta dokunmaması gerekir. Aynı şekilde bir nesnenin kendinde bulunan bileşenleri kötü niyetli veya bilinçsiz kullanımlardan gizlemesi gerekir. Encapsulation programcıya nesneleri koruma gücünü verir.

C# Boxing & Unboxing

  • Boxing
Değer tipinden bir degiskenin, object türüne bilinçsiz dönüstürülmesidir.

Örnek :
int i = 12;
object o = (object);

  • Unboxing
Boxing işleminin tam tersidir. Obje türünden bir degiskenin, değer tipine bilinçli dönüstürülme işlemidir.

Örnek :
object o = 12;
int i = (int)o;

Buradaki bilinçli - bilinçsiz dönüştürme işlemini şu anlama gelmektedir:

Mesela Boxing yaparken bilinçsiz bir dönüşüm söz konusudur çünkü istediğimiz değeri hata almadan obje türüne çevirebiliriz. Fakat Unboxing'te bilinçli bir dönüşüm söz konusudur çünkü Unboxing yaparken mesela örneğimize bakarsak 12 objesini int'e çevirmişiz yani böyle bir dönüşüm yapabiliriz fakat o objesi 12 değilde "abc" gibi bir string olsaydı bunu int e çevirmeye kalksaydık : "System.InvalidCastException: Specified cast is not valid." hatası alırdık. Yani Boxing yaparken her türlü nesneyi objeye çevirebileceğimiz için hata almayız ama Unboxing yaparken neye çevireceğimizi düşünmemiz gerekir bu yüzden bilinçli dönüştürme söz konusudur.