A’ dan Z’ ye C# Öğreniyorum… (1)

Öncelikle ‘Herkese Merhaba’ diyerek bu yazıma başlamak istiyorum. Bu yazıda sıfırdan C# öğrenen biri olarak izlediğim adımları sizler ile paylaşıyor olacağım. Eğer sizde benim gibi daha yeni Sıfır'dan C#'a başlayacaksanız bu yazı tam bizlere göredir. Lafı fazla uzatmadan C#'da Kısa Kısa Notlar... (1) serimize başlayalım.

Bu arada yazımı beğenmeyi ve paylaşmayı, bi de beni takip etmeyi unutmayın :)

1. C# Nedir?

C# programlama dili Microsoft’un son zamanlarda geliştirdiği .NET platformunun bir öğesidir.

C/C++ ve Java dillerinden türetilmiş, bu dillerin dezavantajlarının elenip iyi yönlerinin alındığı .Net platformu için sıfırdan geliştirilmiş 100 nesne yönelimli bir dildir. Java dilinden farklı olarak C# dilinde işaretçiler (pointer) kullanılabilmektedir.

.NET uyumlu dillerin hepsi aynı değişkenleri ve benzer nesne yönelimli özellikleri taşır.

2. CLR ( Common Language Runtime ) - Ortak Dil Çalışma Platformu

.NET altyapısında programların çalışmasını kontrol eden ve işletim sistemi ile programımız arasında yer alan arabirimdir.

Platformdan bağımsız bir ortam istiyorsak, ihtiyaç duyulan şey CLR dir hangi platformda iseniz ( Linux,Mac, Windows ) CLR bu noktada devreye girer ve
.NET programlarının farklı platformlarda işletim sistemine göre çalıştırır.

3. CTS ( Common Type System ) - Ortak Tip Sistemi

Bütün veri tiplerinin tanımlı olduğu bir sistem olarak düşünebiliriz C# dilindeki veri türleri aslında CTS’deki veri türlerine karşılık gelen ara yüzlerdir.

CTS sayesinde .NET platformu için geliştirilen bütün diller aynı veri tiplerini kullanırlar, tek değişen türlerin tanımlama yöntemi ve söz dizimidir.

4. Assembly

.NET platformu için yazılan bütün kodların sonucunda oluşan .exe ve . dll uzantılı dosyalara genel olarak assembly denilmektedir.

Derlenmiş kodlar ve metadata olarak adlandırlan özniteleyici kodlar Assembly içerisinde bulunurlar.

Assembly’de ayrıca versiyon bilgisi de tutulur.

5. Namespaces and .NET Class Library ( İsim Alanları ve .NET Sınıf Kütüphanesi )

.NET Framework’ün programcılara sunduğu bir takım temel türler ve sınıflar mevcuttur.

Bütün bu sınıfları ve türleri iyi organize edebilmek için .NET, isim alanı
( namespace ) kavramını kullanmaktadır.

.NET ’teki sınıf kütüphaneleri bir dilden bağımsız bir yapıdadır.

C# dilinde .NET Framework sınıf kütüphanesi içerisindeki veri türleri ve sınıflar “using” anahtar sözcüğü ile kullanılır.

.NET sınıf kütüphanesinde bulunan ve en sık kullanılan sınıf kütüphaneleri şunlardır :
-
System : temel sınıfları içerir. Tüm sınıf kütüphaneleri bu isim alanı içinde kümelenmiştir.
-
System.Data : veritabanı işlemlerinin tamamı için hazır gelen sınıf kütüphanesine bu isim alanı ile erişilir.
-
System.Xml : veri biçimlendirme ve internetten veri paylaşımı için en çok kullanılan teknolojilerden biri olan XML ile çalışmak için gerekli sınırları içerir.
-
System.Net : http ve ağ protokollerini içeren isim alanıdır.
-
System.IO : dosyaları çalıştırmak (okuma - yazma) için kullanılır.
-
System.Windows.Forms : Windos uygulamalarda kullanılan görsel kontrolleri barındıran isim alanıdır.

C# dilinde her şey sınıflarla temsil edildiği için “Main()” işlevi de bizim belirlediğimiz bir sınıfın işlevi olmak zorundadır.

- Main() işlevi bizim için programımızın başlangıç noktasıdır.

- Sınıflar isim alanı ( namespace ) dediğimiz kavramla erişilmesi kolay bir hale gelmiştir.

6. Temel Veri Türleri

C#’da veri tipleri temel olarak 2 ’ye ayrılırlar. Bunlar önceden tanımlanmış veri türleri ve kullanıcı tarafından tanımlanmış veri türleridir.
- Önceden tanımlanmış olan veri türleri de kendi arasında
değer tipi ( value type ) ve
referans tipi ( reference type ) olarak 2’ye ayrılır.

Verinin bellekte tutulması 6 bölgeden biri ile olmaktadır. Bunlar :
--
Stack Bölgesi : bir tamsayı türünden nesnenin çalışma zamanında yüklendiği yer RAM’ in stack bölgesidir. Tanımlı değişkenlerin tutulduğu bellek alanıdır.
--
Heap Bölgesi : bütün C# nesneleri bu bölgede oluşturulur. Stack’ten farklı olarak bu bölgede tahsisatı yapılacak nesnenin derleyici tarafından bilinmesi zorunlu değildir. Bu bölgede bir nesneye alan ayırmak için new anahtar sözcüğü kullanılır.

new ile tahsis edilen alanlar dinamiktir. Çalışma zamanında tahsisat yapılır, derleme zamanında bir yer ayrılmaz Stack ’e göre daha yavaştır.

Değer veri türleri “Stack”, Referans veri türleri “Heap” te tutulurlar.

-- Register Bölgesi : Registerlar mikroişlemci üzerinde bulunan özel yapılardır. Diğer bölgelere göre veri transferi daha hızlıdır.
--
Static Bölge : Bellekteki herhangi bir bölgeyi temsil eder. Static alanlarda tutulan veriler programın bütün çalışma süresince saklanır.
--
Sabit Bölge : Program içerisinde, değerlerin değişmeden sürekli olarak aynı kaldığı bölümdür.
--
RAM Olayan Bölge : Bellek bölgesini temsil etmeyen disk alanlarını temsil eder.

C#’da bir değişkene herhangi bir değer atamadan onu kullanmak yasaktır. Eğer bir değişkeni kullanmak istiyorsak değişkenlere bir değer verilmesi zorunludur. Bu kural değer ve referans tipleri için de geçerlidir.

7. Değişkenlerin Faaliyet Alanları

Tanımlanan bir değişkene ancak tanımlandığı blok içerisinden ulaşılabilir. Bu blok aralığına değişkenin faaliyet alanı denir.

Bir sınıfın üye elemanı olarak tanımlanmış değişken her zaman sınıfın faaliyet alanı içerisindedir.

Yerel bir değişken, tanımlandığı blok arasında kaldığı sürece faaliyet alanındadır.

Döngü bloklarında tanımlanan değişkenler döngünün dışına çıkılmadığı sürece faaliyet alanı içersindedirler.

ŞEKİL 1 : Değişkenlerin Faaliyet Alanları ( code - Result )

Faaliyet alanı devam eden bir değişkenin tekrar tanımlanması derleme esnasında hataya yol açar.

ŞEKİL 2 : Faaliyet alanı devam eden bir değişkenin tekrar tanımlanması ( code - Result )

8. Sabitler

Program boyunca değerinin değişmeyeceği düşünülen veriler sabit olarak tanımlanırlar. Bu tanımlamayı yapmak için tanımlama satırının başında "const" anahtar sözcüğünü kullanırız.

Sabitlere ilk değer verilirken yine sabitler kullanılmalıdır. Değişken tanımlamada olduğu gibi sabitlerde de tanımlandıklarında mutlaka ilk
değerleri verilmelidir.

const double pi = 3.14;

Sabitler tanımlandıklarında değerleri atanmalıdır. İlk değer verilmeyen değişkenler sabit olamazlar.

Sabit ifadelere ancak sabit ifadelerle ilk değer atanabilir.

Sabit ifadeler kendi yapılarından dolayı static bir nesne oldukları için ayrıca static anahtar sözcüğü kullanılmaz.

9. Değer ve Referans Tipleri

Değer tipleri değişkenin değerini direkt bellek bölgesinden alırlar.

Referans tipleri ise başka bir nesneye referans olarak kullanılırlar. Diğer bir ifade ile referans tipleri, heap alanında yaratılan nesnelerin adreslerini
saklar
lar.

Değer tipleri yaratıldıklarında stack bölgesinde oluşturulurlar. Referans tipleri ise kullanımı biraz daha sınırlı olan heap bellek bölgesinde saklanırlar.

Temel veri tipleri ( int, double, float, … ) değer tipi herhangi bir sınıf türü ise referans tipidir.

-- : İki değer tipi nesnesi birbirine eşitlenirken değişkenlerde saklanan değerler kopyalanarak eşitlenir ve bu durumda iki yeni bağımsız nesne elde edilmiş olur. Birinin değerini değiştirmek diğerini etkilemez.

-- : İki referans tipi birbirine eşitlendiğinde bu nesnelerde tutulan veriler kopyalanmaz, işlem yapılan nesnelerin heap bölgesindeki adresleridir.

10. Değer Tipleri ( Value Types )

Değer tiplerinin tamamı Object denilen bir nesneden türemiştir. C#’da her nesne ya da veri tipi aslında Object tipidir.

ŞEKİL 3 : Değer ve Referans Tipleri
Değer Tipleri ( Code )
ŞEKİL 4 : Değer Tipleri ( Result )

11. Referans Tipleri ( Reference Types )

C#'ta önceden tanımlı iki referans tipi vardır Object ve String.

Object türü C#’ta bütün türlerin türediği sınıftır. Diğer bir deyişle Object türünden bir nesneye herhangi bir veri türünden nesneyi atayabiliriz.

Object’e eşleştirme (Boxing) işlemi ve tersi, Object’i dönüştürme (Unboxing).

12. String Türü

--- Özel anlamlar içeren karakterleri ifade etmek için \ ifadesini kullanırız.
--- String içinde görülen ifadenin aynısımı belirtmek için string ifadesinin önüne
@ işereti konulur.

String Türü ( Code )
ŞEKİL 5 : String Türü ( Result )

13. Object ve String Veri Türü

Object ve string değişkenler stack te oluşturulur değerleri heap te bulunur. Stack te ise heap adresleri saklanır.

Object ve String Veri Türü ( Code )
ŞEKİL 6 : Object ve String Veri Türü ( Result )
Object ve String Veri Türü ( Code )
ŞEKİL 7 : Object ve String Veri Türü ( Result )

14. var Değişken Yapısı

var, anahtar sözcüğünü kullanarak bir veri tanımladığımızda, atadığımız ilk değerin tipini derleyici tarafından kendine değer tipi olarak belirlemektedir.

var Değişken Yapısı ( code )
ŞEKİL 8 : var Değişken Yapısı ( Result )

var tipindeki değişkenimize ilk atadığımız değerin tipini kendine tip
olarak belirleyecek, sonraki atamalarda da aynı tipte değer isteyecektir.

object te ise durum farklıdır. Her gelen değer boxing olur yani gelen veri türüne göre object olarak RAM de saklanır.

15. dynamic Değişken Yapısı

dynamic , derleme zamanında ( compile time ) gerçekleştirilen tip kontrollerinin pas geçilerek, bu kontrollerin tamamen çalışma zamanında ( runtime ) gerçekleştirilmesidir.

dynamic Değişken Yapısı ( code )

dynamic , kullanılarak oluşturulan değişkenler, çalışma zamanında kendilerine atanan değişkenleri dinamik bir şekilde çözümleyerek değişkenin tipi o an ne ise, o tip için işlemleri yapmasını sağlar.

16. object ve dynamic Arasındaki Farklar

dynamic object gibi davranır ancak aralarındaki en büyük fark, object tipine var olan tüm sınıf örnekleri atanabilse de, static tip yine System.Object’dir. Uygulamada gerçek tipi kullanabilmeniz için “object” tipi cast etmeniz gerekmektedir. “dynamic”’de ise buna gerek yoktur. .NET zaten runtimeda tipi otomatik olarak belirleyerek gerekli casting işlemini yapar.

object ve dynamic Arasındaki Farklar ( code )

17. Tür Dönüşümleri

Farklı türden değişkenlerin aynı ifade içinde işlem görmeleri için tür dönüşümü kullanılır. Tür dönüşümlerini “Bilinçli” ve “Bilinçsiz” tür dönüşümü olarak ayırmak mümkündür.

--- Bilniçsiz Tür Dönüşümü : Derleyici tarafından bir değişkeni tanımladığımız türün dışında geçici olarak başka bir türe çevirmeye bilinçsiz tür dönüşümü denir

Bilniçsiz Tür Dönüşümü ( code )

---> Bilinçsiz yapılan tür dönüşümlerinde bir nesnenin türü asla kalıcı olarak değiştirilmez. Bilinçsiz yapılan tür dönüşümleri 2 şekilde gerçekleştirilebilir. Küçük türün büyük türe dönüştürülmesi ve Büyük türün küçük türe dönüştürlmesi.

-> Küçük türün büyük türe dönüştürülmesi ( Otomotik tip dönüşümü )
Küçük tür büyük türe dönüştürülürken fazla bitler sıfır ile doldurulur. Küçük türün yüksek anlamlı bitlerinin sıfırla beslenmesi değişkendeki değeri
değiştirmediği için tür dönüşümünde herhangi bir veri kaybı olmaz.

Bilniçsiz Tür Dönüşümü ( code )

---> Bazı değer türleri arasında tür dönüşümü yapmak mümkün değildir. Bunlar
-> Bool, decimal ve double türünden herhangi bir türe
-> Herhangi bir türden char türüne
-> Float ve decimal türünden herhangi bir türe float türünden double türüne
( dönüşüm hariç )

-> Büyük türün küçük türe dönüştürülmesi
Büyük türlerin küçük türlere otomatik dönüştürülmesi C#’da yasaklanmıştır. Eğer bu tür bir dönüştürme (bilinçsiz olarak) mümkün olsaydı birtakım veri
kayıpları yaşanacak
tır. Ancak “()” cast operatörü ile yapılır.

--- Bilniçli Tür Dönüşümü : genellikle derleyicinin izin vermediği dönüşümlerde kullanılır. Bu tür dönüşümlerde de yine küçük türler büyük türe ya da tersi dönüşümler yapılabilir.
-> Küçük türlerin büyük türlere çevrilmesi aynı bilinçsiz dönüşümde olduğu gibidir.
-> Bilinçli tür dönüşümü yapılırken “tür dönüştürme operatörleri” kullanılır. Tür dönüştürme operatörü parantez içinde değişken ya da sabitten önce yazılır.

Bilinçsiz yapılan tür dönüşümlerinde büyük türler, küçük türlere dönüştürülemiyordu. Eğer tür dönüştürme operatörü kullanılırsa bu işlem mümkün olur.

(dönüştürülecekTür) degişken yada sabit
Bilniçli Tür Dönüşümü ( code )
Bilniçli Tür Dönüşümü ( Result)

18. Checked ve Unchecked

Tür dönüşümlerinde veri kayıplarında programa hata uyarısı verdirebilmek için checked deyimi kullanılır. Checked anahtar sözcüğü ile çalışma zamanında oluşabilecek veri kayıplarının olabileceği durumlarda hata vermesini sağlayabiliriz.

Checked ( code )
Checked ( Result)

Normal şartlarda yapılan işlemler “unchecked ” dır. Böyle bir ifadenin konmasının nedeni uzun “checked” blokların oluşturulması istenebilir.
Bu durumlarda çok fazla blok oluşturmamak için “
unchecked” ifadesi kullanılabilir.

Checked ve Unchecked ( code )
Checked ve Unchecked ( Result )

19. Referans ve Değer Türleri Arasındaki Dönüşüm

--- Object Türü ve ToString() Metodu : Temel veri türleri de dahil olmak üzere bütün veri tipleri object denilen bir referans türünden türemiştir. Türeme, kalıtım yolu ile olduğu için var olan özellikler her zaman korunur.
-> C# herşey nesne(object) referans türünden türetilmiştir. Temelde bir sınıf vardır. Örneğin object sınıfının ToString() metodu bütün temel veri ve referans türlerinde kullanılır.
-> .ToString() metodu bütün temel türlerde ya da referans türlerde kullanılabilir. Amacı ise string’e dönüşüm işlemi yapmaktır.

Object Türü ve ToString() Metodu ( code )
Object Türü ve ToString() Metodu ( Result )

--- Boxing ( Değer - Referans Dönüşümü ) İşlemi : değer ve referans tipleri arasında bir dönüşüme ihtiyaç duyulduğunda “Boxing” yapılır. Bu yöntem değer tipindeki verileri “ object ” nesnesine çevirir.

Bir değer tipini referans tipe atadığımızda stack’teki bilgi bit olarak heap ’e kopyalanır ve stack ’teki object türünden olan değişken heap’i gösterecek şekilde ayarlanır.

-> Bilinçsiz “boxing” işlemi

int intValue = 50; // değer tipi
object onjValue = i; // boxing

-> Bilinçli “boxing” işlemi

int intValue = 50; // değer tipi
object onjValue = (object)i; // boxing

--- Unboxing ( Referans -Değer Dönüşümü ) İşlemi : Heap alanındaki nesnelerin değerlerinin bit olarak stack bölgesine kopyalanması işlemine
unboxing ” adı verilir.

Bu işlem sonucunda “referans türler değer türüne” dönüştürülmüş olur.
Unboxing işlemine tabi tutulacak nesnenin daha önceden boxing işlemine tabi tutulmuş olması gerekir.
Unboxing işlemi bilinçsiz bir biçimde yapılmaz, mutlaka tür dönüşüm operatörü kullanılmalıdır.

int i= 123;      // değer tipi
object o = i; // boxing
int j = (int)o; // unboxing

Boxing işlemi normal bir atama işleminden 20 kat daha uzun sürmektedir. Unboxing işlemi ise yine normal bir atama işleminden 4 kat daha uzun sürmektedir. Bu yüzden gerekli olmayan aşırı boxing ve unboxing kullanımı uygulamanızı gözle görülür bir biçimde yavaşlatacaktır.

22. System.Convert İle Tür Dönüşümü

.NET sınıf kütüphanesinde yer alan “Convert” sınıfı string değerleri ve temel veri türlerini birbirine çevirmek için kullanılır. Her bir veri türü için ayrı bir çevrim fonksiyonuna sahiptir.

System.Convert Metotları
System.Convert İle Tür Dönüşümü ( code )

--

--