Tip Degiskenlerini Where keyword ile Kisitlama

Bu makalemizde developerlar tarafindan type safety containerlar (örnek: List, Stack vs..) ya da fonksiyonlar tanimlamak için biçilmis kaftan olan where keywordünü incelemeye çalisacagiz.

Öyle bir liste tanimlamlamak istiyorsunuz ki sadece ICloneable arayüzünü implement eden nesneleri içinde barindirabilir ya da öyle bir generic fonksiyon tanimlamak istiyorsunuz ki içine parametre olarak geçtiginiz nesne System.Windows.Forms.Form sinifindan türemeli. Iste bu durumlarda where keywordünü kullanabiliriz. Asagidaki tabloda where keywordü ile kullanilan T tipinin neler olabilecegini gösteriyoruz.

Tablo

  • where T : struct

    Parametre olarak geçilen T nin tipi System.ValueType olmali.
  • where T : class

    Parametre olarak geçilen T nin tipi System.ValueType olmamali. Reference type olmali.
  • where T : new()

    Parametre olarak T nin default constructori olmali. Bu zorunluluk çoklu zorunluluk listesinde en sonda olmali.
  • where T : BaseClassIsmi

    Parametre olarak geçilen T belirtilen siniftan türemeli.
  • where T : InterfaceIsmi

    Parametre olarak geçilen T belirtilen interfacei implement etmeli. (Uygulamali) Birde fazla interface virgülle ayrilarak belirtilebilir.

Where Keywordünde Kullanilacak Sinif

 public class Friend : IComparable, IComparer
    {
        public int Age { get; set; }

        public string Name { get; set; }

        public string Surname { get; set; }

        public string AdiSoyadiYasi
        {
            get { return string.Concat("Adi: ", Name, 
	" Soyadi: ", Surname," Yasi: ", Age.ToString()); }
        }

        public int CompareTo(object obj)
        {
            Friend friend = obj as Friend;
            if (friend != null)
            {
                return this.Age.CompareTo(friend.Age);
            }
            throw new ArgumentException("Object is 
not a type of Friend");
        }

        public int Compare(Friend x, Friend y)
        {
            return x.CompareTo(y);
        }
    }  

Burada Friend adinda bir sinif ve bu sinifa ait 4 tane property tanimladik. Bu sinifimiz IComparer arayüzünün (interface) Compare metodunu implement ediyor. Bu metodu, friend tipinde nesneleri barindiran bir listede siralama için kullanacagiz. Friend sinifi ayrica IComparable arayüzünün CompareTo fonksiyonunu da implement (uyguluyor) ediyor. Bu fonksiyonu Friend nesnesinin Age propertysini karsilastirmak için kullaniyoruz.

.

Fonksiyonlarin Tanimlandigi Sinif

public static class Helper
    {
        public static List OrderFriends(List liste) 
		where T : Friend,IComparable
        {            
             liste.Sort((x,y)=>x.Compare(x,y));
             return liste;
        }
 
        public static T CompareAge(T first, T second) 
		where T : Friend, IComparer, new()
        {
            int sonuc = first.CompareTo(second);
            if (sonuc == 1)
            {
                return first;
            }
            else if (sonuc == -1)
            {
                return second;
            }
            else
                return null;       
        }
    }

Static olan Helper classinda 2 tane fonksiyon tanimladik. Iste bu fonksiyonlarda where keywordunu kullandik. OrderFriends fonksiyonu parametre olarak T tipinde bir liste aliyor ve onlari sort ettikten sonra listeyi tekrar geri dönüyor. Burda T tipinin nasil olacagini where keywordünün yaninda belirtiyoruz. Parametre olarak geçen T’nin Friend tipinde olmasi ve IComparable arayüzünü implement etmesi gerektigini where keywordü ile belirtiyoruz. CompareAge fonksiyonu ise T tipinde 2 parametre aliyor ve fonksiyon içinde mantiksal bazi islemler sonrasinda T tipinde degiskeni dönüyor. Burda da where keywordününde belirtilen T parametresinin Friend tipinde olmasi gerektigi ve IComparer arayüzünü implement etmesi gerektigi, ve default constructori olmasi gerektigini belirtiyor.

Form ve Form’da Fonksiyonlarin Kullanimi

public partial class Form1 : Form
    {
        List liste;

        public Form1()
        {
            InitializeComponent();
            Friend friend1 = new Friend();
            friend1.Age = 28;
            friend1.Name = "Sezgin";
            friend1.Surname = "Zeka";

            Friend friend2 = new Friend();
            friend2.Age = 32;
            friend2.Name = "Kivanç";
            friend2.Surname = "Anbarli";

            Friend friend3 = new Friend();
            friend3.Age = 27;
            friend3.Name = "Koray";
            friend3.Surname = "Korkmaz";

            Friend friend4 = new Friend();
            friend4.Age = 31;
            friend4.Name = "Enis";
            friend4.Surname = "Kahyaogullari";

            Friend friend5 = new Friend();
            friend5.Age = 23;
            friend5.Name = "Emre";
            friend5.Surname = "Küçükkaya";

            liste = new List { friend1, friend2, friend3,friend4,friend5 }; 
	    listBox1.DataSource = liste;
        }

        private void btnSirala_Click(object sender, EventArgs e)
        {
            listBox1.DataSource = null;
            listBox1.DisplayMember = "AdiSoyadiYasi";
            listBox1.ValueMember = "Age";
            listBox1.DataSource = Helper.OrderFriends(liste);
        }

        private void btnKarsilastir_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItems.Count == 2)
            {
                Friend sonuc = Helper.CompareAge(listBox1.SelectedItems[0] 
                   as Friend, listBox1.SelectedItems[1] as Friend);
                MessageBox.Show(string.Concat("Yasi büyük olan kisi: ",
                                 sonuc.AdiSoyadiYasi));
            }
        }
    }

.

Formun constructorunda 5 tane Friend nesnesi tanimlayip global List tipindeki degiskenimize ekledik ve bu listeyi listboximizin datasource’una atadik. btnSirala_Click eventinde ise Helper.OrderFriends fonksiyonunu çagirarak listeyi siralayip listbox nesnesinin datasource’una atiyoruz. OrderFriends fonksiyonuna geçtigimiz parametre fonksiyonun taniminin where kosulunu saglamaktadir. Listenin içinde Friend tipinde nesneler var ve bu bu nesnenin ait oldugu sinif IComparable arayüzünü implement etmektedir. btnKarsilastir_Click eventinde de Helper.CompareAge fonksiyonu araciligi ile listboxtan seçilen 2 kayittan, hangi kaydin yasinin büyük oldugu MessageBox.Show fonksiyonu araciligi ile gösteriliyor. Bu fonksiyonun içine parametre olarak geçilen Friend tipi IComparer arayüzünü implement ediyor ve default constructori var.

Bu makalemizde type-safety saglamak amaciyla kullanilan where keywordünün ne oldugunu, ne için ve nasil kullanildigini anlatmaya çalistik. Bir sonraki makalemizde görüsmek üzere…

Örnek Projeyi buradan indirebilirsiniz

Sezgin Zeka

sezginzeka@gmail.com

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir