Bu makalemizde developerlar tarafından type safety containerlar (örnek: List, Stack vs..) ya da fonksiyonlar tanımlamak için biçilmiş kaftan olan where keywordünü incelemeye çalışacağız.
Öyle bir liste tanımlamlamak istiyorsunuz ki sadece ICloneable arayüzünü implement eden nesneleri içinde barındırabilir ya da öyle bir generic fonksiyon tanımlamak istiyorsunuz ki içine parametre olarak geçtiğiniz nesne System.Windows.Forms.Form sınıfından türemeli. İşte bu durumlarda where keywordünü kullanabiliriz. Aşağıdaki tabloda where keywordü ile kullanılan T tipinin neler olabileceğini gösteriyoruz.
Tablo
Parametre olarak geçilen T nin tipi System.ValueType olmalı.
Parametre olarak geçilen T nin tipi System.ValueType olmamalı. Reference type olmalı.
Parametre olarak T nin default constructorı olmalı. Bu zorunluluk çoklu zorunluluk listesinde en sonda olmalı.
Parametre olarak geçilen T belirtilen sınıftan türemeli.
Parametre olarak geçilen T belirtilen interfacei implement etmeli. (Uygulamalı) Birde fazla interface virgülle ayrılarak belirtilebilir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
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( "Adı: " , Name, " Soyadı: " , Surname, " Yaşı: " , 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 adında bir sınıf ve bu sınıfa ait 4 tane property tanımladık. Bu sınıfımız IComparer arayüzünün (interface) Compare metodunu implement ediyor. Bu metodu, friend tipinde nesneleri barındıran bir listede sıralama için kullanacağız. Friend sınıfı ayrıca IComparable arayüzünün CompareTo fonksiyonunu da implement (uyguluyor) ediyor. Bu fonksiyonu Friend nesnesinin Age propertysini karşılaştırmak için kullanıyoruz.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 classında 2 tane fonksiyon tanımladık. İşte bu fonksiyonlarda where keywordunu kullandık. OrderFriends fonksiyonu parametre olarak T tipinde bir liste alıyor ve onları sort ettikten sonra listeyi tekrar geri dönüyor. Burda T tipinin nasıl olacağını where keywordünün yanında belirtiyoruz. Parametre olarak geçen T'nin Friend tipinde olması ve IComparable arayüzünü implement etmesi gerektiğini where keywordü ile belirtiyoruz. CompareAge fonksiyonu ise T tipinde 2 parametre alıyor ve fonksiyon içinde mantıksal bazı işlemler sonrasında T tipinde değişkeni dönüyor. Burda da where keywordününde belirtilen T parametresinin Friend tipinde olması gerektiği ve IComparer arayüzünü implement etmesi gerektiği, ve default constructorı olması gerektiğini belirtiyor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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 = "Kıvanç" ; friend2.Surname = "Anbarlı" ; 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 = "Kahyaoğulları" ; 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( "Yaşı büyük olan kişi: " , sonuc.AdiSoyadiYasi)); } } } |
Formun constructorunda 5 tane Friend nesnesi tanımlayıp global List tipindeki değişkenimize ekledik ve bu listeyi listboxımızın datasource'una atadık. btnSirala_Click eventinde ise Helper.OrderFriends fonksiyonunu çağırarak listeyi sıralayıp listbox nesnesinin datasource'una atıyoruz. OrderFriends fonksiyonuna geçtiğimiz parametre fonksiyonun tanımının where koşulunu sağlamaktadır. Listenin içinde Friend tipinde nesneler var ve bu bu nesnenin ait olduğu sınıf IComparable arayüzünü implement etmektedir. btnKarsilastir_Click eventinde de Helper.CompareAge fonksiyonu aracılığı ile listboxtan seçilen 2 kayıttan, hangi kaydın yaşının büyük olduğu MessageBox.Show fonksiyonu aracılığı ile gösteriliyor. Bu fonksiyonun içine parametre olarak geçilen Friend tipi IComparer arayüzünü implement ediyor ve default constructorı var.
Bu makalemizde type-safety sağlamak amacıyla kullanılan where keywordünün ne olduğunu, ne için ve nasıl kullanıldığını anlatmaya çalıştık. Bir sonraki makalemizde görüşmek üzere...