Herkese merhaba. Kapsülleme yazımdan sonra property ve access modifier (erişim belirleyiciler) konusunun daha iyi anlaşılması için bir örnek yazısı hazırladım. Yazının sonlarına doğru Type Initializer, Anonim Tipler (Anonymous Types) ve Index Property (Indexer) konularına da değineceğim. İlk konu kapsamda bir matematik kütüphanesi hazırlayacağım. Bu matematik kütüphanesinin içerisinde üs alma metodunun farklı erişim belirleyici versiyonları yer alacak. Bu projeyi github repomda bulabilirsiniz. Dilerseniz siz de kendi projenize entegre ederek bu kütüphaneyi kullanabilirsiniz. Property ve Access Modifiers (erişim belirleyiciler) yapılarının ne olduğunu hatırlamak için C# Notlarım 16: Kapsülleme (Encapsulation) yazımı okuyabilirsiniz.
Property ve Access Modifier – Hesaplama Uygulaması
Projemizi dll olarak kullanacağımız için .Net Framework kullanan bir class library oluşturuyorum. Taban, üs ve sonuç için uygun propları oluşturarak kapsüllemeyi tamamlıyorum. Farklı erişim belirleyiciler ile işaretlenmiş olan metotlar üzerinden testimi yapacağım.
private int _base; private int _pow; private int _result; public int Base { set { _base = value; } get { return _base; } } public int Pow { set { _pow = value; } get { return _pow; } } public int Result { get { return _result; } private set { _result = value; } } private void CalculatePrivateMethod() { int result = 1; for (int i = 1; i <= _pow; i++) { result = result * _base; } Result = result; } protected void CalculateProtectedMethod() { int result = 1; for (int i = 1; i <= _pow; i++) { result = result * _base; } Result = result; } internal void CalculateInternalMethod() { int result = 1; for (int i = 1; i <= _pow; i++) { result = result * _base; } Result = result; } protected internal void CalculateProtectedInternalMethod() { int result = 1; for (int i = 1; i <= _pow; i++) { result = result * _base; } Result = result; } public void CalculatePublicMethod() { int result = 1; for (int i = 1; i <= _pow; i++) { result = result * _base; } Result = result; }
Bu kütüphaneyi test edebilmemiz için asıl kullanacağımız projeye dll olarak eklememiz gerekiyor. Ekleme yapmak için; projeye sağ tık > Add > Reference yaparak o projeye ekleme yapabiliriz.
Projeyi bu şekilde ekledikten sonra artık ana proje üzerinden test edebiliriz. Main metot içerisinde yeni bir PowMethod nesnesi oluşturuyorum. Taban ve üs bilgilerini verdiğimizde hesaplama metodunu çağırarak işlem yapmasını sağlamalıyız. Bu metotlardan birini kullanmak istediğimizde aşağıdaki gibi sadece public metodu çağırabiliyoruz.
PowMethod pow = new PowMethod(); pow.Base = 5; pow.Pow = 3; Console.WriteLine("Taban: " + pow.Base + "\nÜs: " + pow.Pow); //Hesaplama Metotları pow.CalculatePublicMethod(); //SADECE PUBLIC ERISIM BELIRLEYICISINI KULLANABILIYORUM Console.WriteLine("Sonuç: " + pow.Result);
Program classınının altında yeni bir class oluşturup, ona kalıtım olarak PowMethod classını verdiğimizde constructor metodu içerisinde internal ve protected internal seviyesindeki metotlara erişebiliyorum. Kalıtım ve constructor metodu daha sonraki yazımda anlatacağım.
class Deneme : PowMethod { public Deneme() { CalculatePublicMethod(); CalculateProtectedMethod(); CalculateProtectedInternalMethod(); } }
Şimdi Type Initializer, Anonim Tipler (Anonymous Types) ve Index Property konularına giriş yapalım.
Type Initializer, Anonim Tipler (Anonymus Types) ve Index Property (Indexer)
Type Initializer
Bize C# 3.0 ile gelen bu özellik sayesinde nesne tanımlamaları oldukça pratikleşiyor. Yeni bir sınıf nesnesi oluşturmak için constructor metodu tanımlamasını yaptıktan sonra, o nesnenin ilgili propetylerini doldurabiliriz. Örneğin;
//PowMethod pow = new PowMethod(); //pow.Base = 5; //pow.Pow = 3; PowMethod pow = new PowMethod() { Base = 5, Pow = 3 }; Console.WriteLine("Taban: " + pow.Base + "\nÜs: " + pow.Pow); //Hesaplama Metotları pow.CalculatePublicMethod(); //SADECE PUBLIC ERISIM BELIRLEYICISINI KULLANABILIYORUM Console.WriteLine("Sonuç: " + pow.Result); Console.ReadKey();
Anonim Tipler (Anonymous Types)
C# içerisinde nesne belirtmeksizin tip oluşturabiliriz. Örneğin bir kişi nesnesine ihtiyacımız var ancak bunu projenin her yerinde kullanmayacağız. O zaman var özel kelimesini kullanarak kendi tipimizde bir nesne oluşturabiliriz. Bu yapı genellikle LINQ sorgularında dönen sonuç özel bir data tipi gerektiriyorsa kullanılır. Type safety yapısında olduğu için JavaScript içerisindeki gibi değişkene ilk önce string değer verip daha sonrasında integer bir değer ataması yapamazsınız. Derleme zamanında ilk atanan tip gibi bir class oluşturup onun gibi davranmaya başlar. Dynamicten farkı compile yani derleme zamanında eklenir. Dynamic runtimeda oluşur.
var person = new { Name = "Marty", Surname = "McFly" }; Console.WriteLine("Anonim tip nesne:"); Console.WriteLine("Ad:" + person.Name + "\nSoyad" + person.Surname); Console.ReadKey();
Index Property (Indexer)
Indexer sadece class içerisinde kullanılabilen özel tanımlı bir propertydir. Tanımlandığı classın dizi gibi davranmasını sağlar. Bir collection içerisindeki hangi dataları görmek istiyorsak ona göre indeksleme yapmamıza yardımcı olur. Indexer kod dizilimi;
public T this[int index] //T sizin geriye döndürdüğünüz değerin tipidir. { get { return this._items[index]; } set { this._items[index] = value; } }
Örneğin bir sınıf nesnesi oluşturarak içerisindeki öğrenci listesini farklı şekillerde indekslemeye çalışalım.
class Student { public string Name { get; set; } public string Surname { get; set; } public char Gender { get; set; } } class Classroom { private List _students; public string LabName { get; set; } public int Capacity { get; set; } public Classroom(string lab, int capacity) { LabName = lab; Capacity = capacity; _students = new List(capacity); } public List Students { get { return _students; } set { _students = value; } } public Student this[int index] { get { if (index < 0 || index > Capacity - 1) { return null; } return _students[index]; } set { _students[index] = value; } } public List this[char gender] { get { List list = new List(); foreach (Student item in this.Students) { if (item.Gender == gender) { list.Add(item); } } return list; } } }
İlk tanımlanan indexer propertysi sayesinde nesnenin kendisine bir diziymiş gibi davranıp belli bir indeksteki elemanını alabilirim. Normalde bunu yapmak için nesneninin içerisindeki dizi elemanına ihtiyaç duyarız. Burada kullanıcıdan gelen indeksin kontrollerini yapıp uygun indeksteki sonucu döndürüyorum. Bir altındaki metot ise öğrenci listesinin içindeki gender propertysine göre indeksleme yapabilmeyi sağlıyor. Yani sınıftaki kız öğrencileri indekslemek istediğimde bu propertyi kullanabilirim.
Classroom pisagor = new Classroom("202", 4); pisagor.Students.Add(new Student() { Name = "Derya", Surname = "Dok", Gender = 'K' }); pisagor.Students.Add(new Student() { Name = "Mert", Surname = "Altıntaş", Gender = 'E' }); pisagor.Students.Add(new Student() { Name = "Mustafa Mert", Surname = "Oğuz", Gender = 'E' }); pisagor.Students.Add(new Student() { Name = "Miray", Surname = "Dopdoğru", Gender = 'K' }); Console.WriteLine(); Console.WriteLine("Bütün Öğrenciler"); //Bütün öğrencileri yazdır foreach (Student item in pisagor.Students) { Console.WriteLine("Ad: " + item.Name + " Soyad: " + item.Surname ); } Console.WriteLine(); //Sadece kız öğrencileri yazdır Console.WriteLine("Kız Öğrenciler"); List list = pisagor['K']; foreach (Student item in list) { Console.WriteLine("Ad: " + item.Name + " Soyad: " + item.Surname); } Console.WriteLine(); //İndexteki öğrenciyi yazdır normal yöntem Console.WriteLine("2. İndeksteki Öğrenci (Normal Yöntem)"); Student mmo = pisagor.Students[2]; Console.WriteLine("Ad: " + mmo.Name + " Soyad: " + mmo.Surname); //İndexteki öğrenciyi yazdır Console.WriteLine("1. İndeksteki Öğrenci"); Student ma = pisagor[1]; Console.WriteLine("Ad: " + ma.Name + " Soyad: " + ma.Surname); Console.ReadKey();
Bir sonraki yazıya kadar kendinize iyi bakın. 😊
mert
harika paylaşım teşekkürler