Serdar YILMAZ / Software Developer
Bizimkisi Bir “Bug” Hikayesi...
Kocaeli/Körfez

Arşiv 'Programlama' Kategori

C# – Temel ve Türetilmiş Sınıf Referansları

dotnetC#’da farklı türden referansların birbirine aktarılması yasaklanmıştır. Örneğin, A ve B isminde iki sınıfımız olsun. A sınıfından oluşturulan bir nesnenin adresini B sınıfından oluşturulan bir referansta tutamayız, aynı şekilde B sınıfından oluşturulan bir nesnenin adresini de A sınıfından oluşturulan bir referansta tutamayız.

Kalıtım ile Türetilmiş sınıftan oluşturulan bir nesnenin adresini, Temel sınıftan oluşturulan bir referansta tutabiliriz.

Kedi ve Insan sınıfı Memeli sınıfından Türetilmiştir. Bu durum da Memeli sınıfı Temel sınıf, Insan ve Kedi sınıfı da Türetilmiş sınıftır.

Açıklama satırlarında da belirtildiği üzere; Insan ve Kedi sınıfları Memeli sınıfından türetildiği için bu sınıflardan oluşturulan nesnelerin adresleri Memeli sınıfından oluşturulan referanslarda tutulabilir. Yalnız burada dikkat edilmesi gereken çok önemli bir husus bulunmakta. Memeli sınıfını inceleyecek olursak içerisinde “TurBilgisi()” adında bir metodun olmadığını görürüz. Bu yüzden Insan veya Kedi sınıfından oluşturulan bir nesnenin adresini Memeli sınıfından oluşturulan bir referansa aktardığımız taktirde “TurBilgisi()” metoduna erişemeyiz. Çünkü Memeli sınıfı içerisinde böyle bir metot bulunmamaktadır.

C# Kalıtım

Türetilmiş sınıf, temel sınıf içerisindeki değişkenleri ve metotları kendi içerisinde tanımlanmış gibi kullanabilir. Ancak temel sınıf, türetilmiş sınıftaki değişkenleri ve metotları kullanamaz.

Insan ve Kedi sınıfları, Memeli sınıfından türetildiği için “Bilgi()” metoduna Insan ve Kedi sınıfından oluşturulan nesnelerin referanslarını parametre olarak gönderebiliriz.

Serdar YILMAZ

C# – Üye Gizleme

dotnetTemel sınıf içerisinde bulunan elemanlardan public ve protected erişim belirteçli olanların kalıtım yoluyla Türetilmiş sınıfa aktarıldığından bahsetmiştik (Bkz: C# – Kalıtım). Peki Temel sınıfta ve Türetilmiş sınıfta aynı isme sahip elemanlar tanımlarsak ne olur?

A Temel sınıf, B ise Türetilmiş sınıftır. Temel sınıfta ve Türetilmiş sınıfta aynı isme sahip elemanlar tanımladığımız için Visual Studio uyarı verecektir. Bu uyarının sebebi; Türetilmiş sınıf içerisindeki elemanların, aynı isimli Temel sınıf elemanlarını gizlemesinden kaynaklanmaktadır.

Türetilmiş sınıfın elemanları Temel sınıfın elemanlarını gizlediği için B sınıfından bir nesne oluşturup “Uye_1” ve “Uye_2” elemanlarına erişmek istediğimiz de B sınıfı içerisinde tanımlanmış olan “Uye_1” ve “Uye_2” elemanlarına erişebiliriz. Ekran çıktısı;

Üye gizleme olayının gerçekleştiği durumlar da Visual Studio bu işlemi yanlışlıkla yaptığımızı düşünerek bize bir uyarı verecektir. Bu işlemi kontrollü bir şekilde yaptığımızı belirtmek için new anahtar sözcüğünü kullanırız.

Yapmış olduğumuz düzenlemeden sonra Visual Studio artık uyarı vermeyecektir. Peki Temel sınıf içerisinde ki “Uye_1” ve “Uye_2” elemanlarına nasıl erişebiliriz ?

Temel sınıf içerisindeki “Uye_1” ve “Uye_2” elemanlarına Türetilmiş sınıf içerisinden erişebilmek için base anahtar sözcüğünü kullanırız. Base anahtar sözcüğü türetmenin yapıldığı temel sınıfı temsil eder. Base anahtar sözcüğünün kullanımına Yapıcı Metotlar ve Kalıtım konusunda da değinmiştik.

Serdar YILMAZ

C# – Yapıcı Metotlar ve Kalıtım

dotnetTüretilmiş sınıftan bir nesne oluşturduğumuz da önce temel sınıfın yapıcı metodu sonra da türetilmiş sınıfın yapıcı metodu çalışacaktır.

A temel sınıf, B ise türetilmiş sınıftır. Bu yüzden B sınıfından bir nesne oluşturduğumuz da (B nesne=new B();) önce A sınıfının yapıcı metodu sonra da B sınıfının yapıcı metodu çalışacaktır.  Ekran çıktısı;

Her yapıcı metodun kendi tanımlandığı sınıfın üye elemanları ile ilgili iş yapması gerekir.

base Anahtar Sözcüğü

Türetilmiş sınıf içerisinden temel sınıfın elemanlarına erişmek için base anahtar sözcüğünü kullanırız.

A temel sınıf, B ise türetilmiş sınıftır. Temel sınıfın yapıcı metoduna türetilmiş sınıf üzerinden parametre gönderebilmek için base anahtar sözcüğünü kullanırız.

B sınıfından nesne oluştururken girdiğimiz birinci(10) ve ikinci(15) parametreler A sınıfının yapıcı metoduna gönderilecektir. Üçüncü(20) ve dördünce(25) parametreler ise B sınıfının yapıcı metodu içerisinde kullanılacaktır. Ekran çıktısı;

Türetme ile sınıflar arasında hiyerarşik bir yapı sağlanır.

base anahtar sözcüğü C sınıfında B sınıfını; B sınıfında da A sınıfını temsil eder. C sınıfından bir nesne oluşturduğumuz da önce A sınıfının yapıcı metodu, sonra B sınıfının yapıcı metodu en son da C sınıfının yapıcı metodu çalışacaktır.

C sınıfından nesne oluştururken girdiğimiz birinci(10) ve ikinci(15) parametreler B sınıfının yapıcı metoduna gönderilecektir. Üçüncü(20) parametre ise C sınıfının yapıcı metodu içerisinde kullanılacaktır. B sınıfına gönderilen birinci(10) ve ikinci(15) parametrelerden ilki(10) A sınıfının yapıcı metoduna gönderilecektir ve ikinci(15) parametre de B sınıfı içerisinde kullanılacaktır.

Serdar YILMAZ

C# – Kalıtım

dotnetKalıtım, nesneye dayalı programlamanın en önemli özelliklerinden biridir. Kalıtım yolu ile sınıflar birbirinden türetilebilir. Bir sınıf diğer bir sınıftan türediği zaman, türediği sınıfın bütün özelliklerini içerir. Bunun yanında kendine has özellikler de barındırabilir.

Yukarıdaki örnekte; A temel sınıf, B ise türetilmiş sınıftır. Türetme işlemi “class B : A” kodu ile 11. satırda yapılmıştır. B sınıfı A sınıfından türetildiği için A sınıfı içerisindeki değişken ve metodu kalıtım yolu ile almaktadır.

Türetme işleminden dolayı B sınıfı, A sınıfı içerisindeki “degisken_1” ve “Metot_1()” elemanlarını kendi içerisinde tanımlanmış gibi kullanabilmektedir.

Türetilmiş sınıf, temel sınıf içerisindeki değişkenleri ve metotları kendi içerisinde tanımlanmış gibi kullanabilir. Ancak temel sınıf, türetilmiş sınıftaki değişkenleri ve metotları kullanamaz.

Erişim Belirteçleri

Türetilmiş bir sınıfa, temel sınıftaki elemanlardan sadece public ve protected olarak tanımlananlar aktarılır. Erişim belirteci private olan elemanlar kalıtım ile aktarılmaz.

Erişim Belirleyicisi: Metot ve özelliklere olan erişimin sınırlarını belirtmektedir. (Bknz: C# – Sınıflar)

  1. Private: Sadece tanımlandığı sınıf içerisinden erişilebilir. (Kalıtım ile aktarılmaz.)
  2. Public: Her yerden erişilebilir. (Kalıtım ile aktarılır.)
  3. Internal: Sadece bulunduğu projede erişilebilir. (Kalıtım ile aktarılır.)
  4. Protected: Tanımlandığı sınıfta ve o sınıfı miras (kalıtım) alan sınıflardan erişilebilir. (Kalıtım ile aktarılır.)

TemelSinif içerisindeki degisken_3‘ün erişim belirteci private olduğu için TuretilmisSinif‘a aktarılmaz. Sadece TemelSinif içerisinde kullanılabilir.

TemelSinif içerisindeki degisken_2‘nin erişim belirteci public olduğu için TuretilmisSinif‘a aktarılır. Yukarıdaki örnekte TuretilmisSinif içerisinde degisken_2 adında bir değişken tanımlanmamış olmasına rağmen TemelSinif‘tan kalıtım aldığı için Metot_2() içerisinde kullanılabilmiştir.

TemelSinif içerisindeki degisken_1‘in erişim belirteci protected olduğu için TuretilmisSinif‘a aktarılır. Yukarıdaki örnekte TuretilmisSinif içerisinde degisken_1 adında bir değişken tanımlanmamış olmasına rağmen TemelSinif‘tan kalıtım aldığı için Metot_1() içerisinde kullanılabilmiştir.

Peki bu durum da public ile protected belirteçleri arasındaki fark nedir? 

Kalıtım

TemelSinif‘dan TuretilmisSinif‘a kalıtım yoluyla aktardığımız “degisken_1 (protected)” ve “degisken_2 (public)” elemanlarını TuretilmisSinif içerisinde kullanabiliriz. Ancak TuretilmisSinif‘dan oluşturduğumuz bir nesne üzerinden sadece “degisken_2” elemanına erişebiliriz. Erişim belirteci protected olan degisken_1 elemanına başka bir sınıftan erişemeyiz. Bunun nedeni; Erişim belirteci protected olan elemanlar tanımlandıkları sınıfta ve  kalıtım yolu ile aktarıldıkları sınıflar da private elemanların özelliklerini gösterirler.

Erişim belirteci protected olan elemanların private elemanlardan tek farkı kalıtım yolu ile aktarılabiliyor olmalarıdır. Eğer türeme söz konusu değilse protected olarak bildirilen elemanlarla private olarak bildirilen elemanlar arasında bir fark kalmaz. Erişim belirteci protected olan elemanları, kalıtım yolu ile aktarılabilen private elemanlar olarak düşünebiliriz.

Serdar YILMAZ

Razor View Engine

dotnetRazor View Engine; View’lar da HTML, CSS, JavaScript ile beraber C#’ın da kullanılabilmesini sağlamaktadır. View’lara yazılan HTML, CSS ve JavaScript kodları istemci tarafında çalışmaktadır. C# kodları ise sunucu tarafında çalışır ve sonuç istemciye gönderilir.

Razor Açıklama Satırı

HTML açıklama satırları tarayıcı tarafından yorumlanmaz ancak sayfanın kaynak kodlarını görüntüleyen kullanıcılar tarafından görülebilir. Razor açıklama satırları ise tarayıcı tarafından yorumlanmadığı gibi sayfanın kaynak kodlarında da gözükmez. Sadece uygulamayı geliştiren yazılımcılar tarafından görülebilir.

Razor Kod Blogu

View’de C# kodları yazabilmek için “@{ }” ile Razor kod blogu oluşturmamız gerekmektedir. Örneğimiz de Razor kod blogu içerisinde 3 adet değişken tanımladık. Razor kod blogu içerisinde tanımladığımız değişkenlere, kod blogu dışında erişebilmek için başlarına “@” işareti koymamız gerekmektedir.

Razor Kod Satırı

Tek satırlık C# kodlarını “@( )” içerisine yazabiliriz.

Kontrol Yapıları ve Döngülerin Kullanımı

Razor sayesinde C# diline ait döngü ve kontrol yapılarını (For, Foreach, While, Switch-Case, If-Else…) sayfamızın içerisinde dilediğimiz yerde kullanabiliriz.

Yazar: Serdar YILMAZ

C# – Static Elemanlar ve Sınıflar

dotnetBir sınıf içerisindeki static olmayan metotlara ve özelliklere o sınıftan oluşturduğumuz nesneler üzerinden erişiriz. Static olan metotlara ve özelliklere ise nesne oluşturmadan sınıf adı ile erişiriz.

Static olmayan elemanlar nesneye özgü bilgileri tutarken static olan elemanlar uygulama çalıştığı sürece kendilerine en son atanan değeri tutarlar. AdiSoyadi ve Numara değişkenleri static olmadığı için Ogrenci sınıfından oluşturulan her bir nesne için farklı değerler tutabilirler. OgrenciSayisi değişkeni ise static olduğu için kendisine en son atanan değeri tutacaktır.

Bir özelliği veya metodu static yapmak için erişim belirleyicisinden sonra “static” anahtar kelimesini getirmemiz gerekir.

Static bir metodun içerisinden static olmayan metotlar ve değişkenler çağrılamaz. Sadece diğer static metotlar ve değişkenler çağrılabilir.

Static Yapıcı Metotlar

Yapıcı metotları da normal metotlar gibi static olarak tanımlayabiliriz. Sınıfın static değişkenleri ile ilgili işlemler static yapıcı metodun içerisinde yapılabilir. Static yapıcı metotlar parametre almazlar ve erişim belirteçleri yoktur.

Kullanici sınıfının iki adet yapıcı metodu bulunmaktadır. Bunlardan static olanı kullanicisayisi isimli static değişkenin başlangıç değerini atarken, static olmayanı Nick ve EMail değişkenlerinin atama işlemlerini gerçekleştirmektedir.

Kullanici sınıfından ilk nesne oluşturulduğunda hem static yapıcı metot hemde static olmayan yapıcı metot çalışacaktır(İlk static yapıcı metot çalışır). İlk nesneden sonra oluşturulacak diğer tüm nesnelerde sadece static olmayan yapıcı metot çağrılacaktır. Yani static yapıcı metot sadece ilk nesne oluşturulduğunda çalışır.

Static Sınıflar

Oluşturduğumuz sınıf içerisinde sadece static metotlar ve değişkenler bulunuyorsa sınıfı static olarak tanımlayabiliriz. Sınıfların static olarak tanımlanması bir zorunluluk değildir sadece okunabilirliği arttıran bir yaklaşımdır.

Matematik sınıfının üye elemanları(Topla ve Carp metotları) static olduğu için sınıfı da static olarak bildirdik. Matematik sınıfının static olduğunu gören bir programcı, sınıf içerisinde sadece static elemanların bulunduğunu anlayacaktır.

Static sınıflarla alakalı bilinmesi gerekenler;

  1. Static sınıflardan nesne oluşturulamaz. (new Matematik; YANLIŞ)
  2. Static sınıf türünden referanslar oluşturulamaz. (Matematik m; YANLIŞ)
  3. Static sınıfların içinde static olmayan metot yada değişken tanımlanamaz.
  4. Static sınıflarda kalıtım yoktur.

Serdar YILMAZ

C# – Garbage Collection ve Yıkıcı Metotlar

dotnetYıkıcı metotlara geçmeden önce Garbage Collection mekanizması hakkında bilgi vermekte fayda var.

Garbage Collection

Garbage Collection erişilemeyen nesneleri silerek belleğin verimli bir şekilde kullanılmasını sağlamaktadır. Konuyu örnekler üzerinden açıklamaya devam edelim;

Yukarıdaki kod satırında “new Ogrenci()” komutu ile Heap bellek bölgesinde Ogrenci sınıfından bir nesne oluşturduk. Bu nesneye erişebilmek için adresini, belleğin Stack bölgesinde tutulan “ogr” ismindeki işaretçiye aktardık. Herhangi bir şekilde “ogr” isimli işaretçiyi kaybedersek, Heap bellek bölgesinde oluşturduğumuz nesneye erişmemiz mümkün olmayacaktır. Erişilemeyen nesnelerde Garbage Collection tarafından silinerek bellekte gereksiz yer kaplaması önlenecektir.

Bu örneğimizde Ogrenci sınıfından iki adet nesne oluşturduk. 1. ve 2. satırlarda ilk oluşturduğumuz nesnenin adresini “ogr1” işaretçisine, ikinci oluşturduğumuz nesnenin adresini “ogr2 işaretçisine aktardık. 3. satırda ise ikinci nesnenin adresini, ilk nesnenin adresini tutan “ogr1” işaretçisine aktardık. Yani artık ogr1 işaretçisi, ilk nesnenin adresini değil ikinci nesnenin adresini tutmaktadır. İlk oluşturulan nesnenin adresi kaybedildiği için artık o nesneye ulaşmak mümkün olmayacaktır. Nesneye erişimin mümkün olmadığı durumlarda nesnenin bellekte kalmasının bir anlamı yoktur. Bu yüzden Garbage Collection tarafından silinecektir.

Garbage Collection, Stack, Heap

Garbage Collection mekanizmasının ne zaman devreye gireceği kesin olarak bilinemez. Arkaplanda programcıdan bağımsız bir şekilde çalışmaktadır.

Yıkıcı Metotlar

Erişilemeyen bir nesnenin Garbage Collection tarafından silinmeden hemen önce çalışan metoduna Yıkıcı Metot denilmektedir. Bir nesnenin silinmeden önce yapmasını istediğimiz şeyleri o nesnenin yıkıcı metodu içerisine yazarız.

Yıkıcı Metot Nasıl Tanımlanır ?

  1. Yıkıcı metodun adı sınıf adıyla aynı olmalıdır ve başında “~” işareti olmalıdır.
  2. Parametresi, geri dönüş değeri ve erişim belirteci olmamalıdır.

Oyuncu sınıfından her nesne oluşturulduğunda “OyuncuSayisi” isimli static değişkenin değeri bir arttırılacak ve nesne silinmeden önce değeri bir azaltılacaktır.

Serdar YILMAZ

C# – Byte Birimindeki Sayısal Büyüklüğü Byte’ın Katlarına Çevirme

dotnet

Açıklama

BytesToString() metodu; parametre olarak girilen sayısal büyüklüğü Byte’ın ilgili katına çevirmektedir.

Kod

Önizleme

Serdar YILMAZ

C# – GET ve SET Metotları

dotnet

Set ve Get metotlarını birer kontrol mekanizması olarak düşünebiliriz. Olası problemleri önlemek, işlemleri güvenilir ve kontrollü bir şekilde gerçekleştirmek için Set ve Get metotlarını kullanırız.

Basit bir senaryo üzerinden konumuzu açıklamaya devam edelim. Otel otomasyonu için müşteri bilgilerini tutan bir sınıf tasarladığımızı düşünelim. Müşterinin ad-soyad, TC kimlik numarası ve oda numarası bilgilerini tutmak istiyorsak aşağıdaki gibi bir tasarım yapabiliriz.

Musteri sınıfının üyeleri public olarak bildirildiği için bu üyelere doğrudan erişilip değerler atanabilir. İşte bu noktada kontrolü elimize almamız lazım aksi taktirde TC kimlik numarası eksik/fazla girilebilir veya 120 odalı bir otelde oda numarası negatif veya 120’den büyük girilebilir. Amacımız dikkatsizlik sonucu yaşanabilecek olası sorunların önüne geçmek. Bu yüzden üyelere doğrudan erişimi engelleyip (Private), Get ve Set metotları ile kontrollü bir erişim sağlayacağız.

Sınıfın AdSoyad, TCNo, OdaNo üyelerini diğer sınıfların erişimine kapattık (private) ve bu üyelere olan erişimi adsoyad, tcno, odano özellikleri üzerinden kontrollü bir şekilde sağladık. (else bloklarında exception fırlatabilirdik ancak istisnai durum yönetimini anlatmadığımız için şimdilik es geçiyoruz.)

GET Metodu

Bir özelliğin değeri okunmak istenildiğinde o özelliğe ait GET metodu çalışır.

Console.WriteLine(m1.adsoyad);

m1 nesnesinin içerisindeki adsoyad özelliğinin Get metodu çalışacaktır.

SET Metodu

Bir özelliğe atama yapılmak istenildiğinde o özelliğe ait SET metodu çalışır. Atanan değere SET metodu içerisinde value anahtar sözcüğü ile erişilir. value anahtar sözcüğünün önceden belirlenmiş herhangi bir türü yoktur. Özelliğe atanacak değer hangi türden ise value da o türden olur.

m1.adsoyad=”Serdar Yılmaz”;

m1 nesnesinin içerisindeki adsoyad özelliğinin SET metodu çalışacaktır ve value ifadesi “Serdar Yılmaz” değerini alacaktır.

Bir özelliğin sadece GET metodunu tanımlayarak özelliği sadece okunabilir hale getirebiliriz.

Erişim Belirleyicisi Kullanımı

GET ve SET metotlarında erişim belirleyicilerini kullanarak erişimin sınırlarını belirtebiliriz.

Yukarıdaki örneğimizde SET metodu private olarak bildirildi. Bu yüzden diğer sınıflardan adsoyad özelliğinin değeri okunabilir ancak herhangi bir atama yapılamaz (set metoduna sadece sınıfın içinden erişilebilir). Eğer SET metodunu private olarak bildirmeseydik; adsoyad özelliği public olduğu için SET metodu da otomatikmen public olacaktı.

GET ve SET metotları için herhangi bir erişim belirteci bildirilmezse, varsayılan olarak özelliğin erişim belirtecini alırlar.

Serdar YILMAZ

C# – This Anahtar Sözcüğü

dotnet

this anahtar sözcüğü ilgili nesnenin referansını belirtmektedir. Konuyu daha anlaşılır kılmak için örnek uygulamalar üzerinden gideceğiz.

Yukarıdaki veri modelinde sınıfın üye elemanları ile yapıcı metodun parametrelerinin aynı isimlere sahip olduğu görülmektedir. Peki yapıcı metot içerisinde AdSoyad değişkenine erişmek istediğimizde; sınıfın üye elemanı olan AdSoyad değişkenine mi erişiriz yoksa yapıcı metodun parametresi olan AdSoyad değişkenine mi ? İşte bu noktada this anahtar sözcüğü sorunun cevabını netleştirip, kaynak kodlarımızın okunabilirliğini arttırmaktadır.

this anahtar sözcüğü ile nitelenen değişkenler sınıfın üye elemanlarıdır. Yukarıdaki veri modelinde yapıcı metoda parametre olarak gönderilen değerler, sınıfın üye elemanlarına aktarılacaktır.

Yukarıdaki programımızı inceleyecek olursak; Silindir sınıfının iki adet yapıcı metodu bulunmaktadır. Silindir sınıfından nesne oluşturulurken 3 adet parametre girildiğinde; 1. parametre silindirin yarıçapını, 2. parametre yüksekliğini, 3. parametrede PI sayısının kaç alınacağını belirtecektir.

Eğer Silindir sınıfından nesne oluşturulurken 2 parametre girilirse; 1. parametre silindirin yarıçapını, 2. parametre yüksekliğini belirtecektir ve PI sayısı da “3.1415” olarak alınacaktır. Peki bunu nasıl yaptık ?

İçeriğimizin başında this anahtar sözcüğünün ilgili nesnenin referansını belirttiğini söylemiştik.

public Silindir(double yaricap, double yukseklik) : this(yaricap, yukseklik, 3.1415) { }

this anahtar sözcüğü ile; girilen 2 parametreyle beraber, PI girilmediği taktirde varsayılan olarak kabul edilmesini istediğimiz değerini, double tipinde 3 parametre alan yapıcı metoda gönderdik. Böylece 2 parametre alan yapıcı metodu, 3 parametre alan yapıcı metottan faydalanarak kullandık.

Yapıcı metotların aşırı yüklenmesini anlatırken yukarıdaki programı this anahtar sözcüğünü kullanmadan yazmıştık (Bkz:C# – Yapıcı Metotlar). Kaynak kodlarını karşılaştırıp aradaki farkı daha iyi anlayabilirsiniz.

Yukarıdaki program Opsiyonel(Optional) Parametreler kullanılarak tek bir yapıcı metot ile yazılabilir.

Serdar YILMAZ