You are on page 1of 217

BU DKMAN KAAN ASLAN TARAFINDAN C VE SSTEM PROGRAMCILARI DERNENDE VERLEN C# LE NESNE YNELML PROGRAMLAMA KURSUNDAK DERS ERSNDE TUTULAN

NOTLARDAN OLUMAKTADIR. NOTLAR ZERNDE HBR DZELTME YAPILMAMITIR

.NET ORTAMININ TEMEL ZELLKLER ARAKOD SSTEM Diller Aras Entegrasyon


(07.06.2007 Perembe)

.Net ortamnda, bu ortam iin yazlm derleyiciler ayn ortak arakodu retmektedir. rnein C# derleyicisi de, Visual Basic.Net derleyicisi de ayn arakodu retmektedir.Bu durumda C# da yazlm plan kodun Visual Basic.Nette ya da Visual Basic.Nette yazlm olan bir kodun C# ta kullanlmas tamamen doal yntemlerle salanm olur. Bir dilde yazlm olan kodlarn baka bir dilde kullanlmas nemli bir sorundur. Microsoft, .Net ncesinde COM denilen bir ara yzle bu sorunu zmeye almtr. Fakat bu COM sisteminin nemli dezavantajlar sz konusudur. Fakat .Nette diller aras entegrasyon zaten doal olarak arakod dzeyinde zlmtr. Microsoft, .Net ortam iin 4 programlama diline ait derleyiciyi kendi yazmtr. Bunlar C#, Visual Basic.Net, C++.Net, J# derleyicileridir. Ancak C# dnda dier diller bir takm syntax deiiklikleri ile bu ortama zorla adapte edilmitir. Bu nedenle C# bu ortamn birincil dilidir. Bir programlama dilinin .Net uyumlu olmas iin baz zellikleri barndrmas gerekir. Bu zelliklerin neler olduu ECMA 335 CLI standartlarnda belirtilmitir. Hzl Uygulama Gelitirme .Net ortam ve C# programlama dili hzl uygulama gelitirme srecini destekleyecek nitelikte tasarlanmtr. Uzun olmayan bir eitim srecinden sonra pek ou hazr olan bileenleri kullanarak uzman olmayanlarnda program yazabilmesi mmkn hale getirilmektedir. Hzl uygulama gelitirme de grsel elerin kullanlmas gerekmektedir. Ortak Snf Ktphanesi .Net ortamnda tm dillerde kullanlabilen ortak ve geni bir snf ktphanesi vardr. Pek ok ilem bu ktphaneler sayesinde kolayca yaplr. Bu ktphaneleri kullanma becerisi .Net programclnda nemli bir yer tutar. .Net ktphanesi, framework ktphanesine yeni snflar eklenerek geniletilmektedir. Bu ortak snf ktphanesinin baz blmleri zel isimlerle anlr. rnein veritaban iini yapan ksmna ADO.Net, ekranlar oluturmak iin kullanlan ksmna Forms, web sayfas oluturmak iin kullanlan ksmna ASP.Net denir. Web Tabanl alma .Net ortam Microsoftun web sunucular ile de btnletirilmitir. ASP.Net denilen sistemle etkileimli web sayfalar .Net ortam ierisinde oluturulabilmektedir. 1

Gvenlik .Net ortamnda arakod almas sayesinde gvenlik ihlalleri CLR tarafndan engellenebilmektedir. .Net ortam pek ok bakmdan daha gvenli bir alma ortam sunmaktadr. Visual Studio IDEsi .Net altnda yazlm gelitirme faaliyetlerini kolaylatrmak iin kendi ierisinde editr olan, eitli gelitirme aralar bulunan IDEler bulunmaktadr. Microsoftun .Net IDEsi Visual Studio isimli IDEdir. u anda kullanlan son srm Visual Studio 2005tir. Bu IDE eitli paketler halinde para ile satlmaktadr. En kapsaml versiyonu Team Editiondur.

.NET ORTAMI NASIL KURULUR? .Net ortamn kurmann birka deiik yolu vardr. 1- Windows Xpnin son srmleri, Windows Vistann son srmleri zaten .Net ortamn iletim sisteminin bir paras olarak iermektedir. Bu sistemlerde ayrca .Net ortamn kurmaya gerek yoktur. Microsoft bundan sonraki Windows srmlerinde .Net ortamnn tpk Internet Explorer gibi bulunacan sylemitir. 2- Visual Studio Express Edition IDEleri yklenirken .Net ortam da zaten yklenmi olur. 3- www.microsoft.com/downloads internet adresine girilerek .Net Framework 2.0 SDK indirilerek kurulur. Bu paket yaklak olarak 300mb civarndadr. .Net ortamnn yan sra komut satrndan alan eitli aralar da iermektedir. 4- Bir .Net programnn alabilmesi iin minimum kurulum .NET Framework Version 2.0 Redistributable Package isimli paketle yaplabilir.

DERLEYC VE IDE KAVRAMLARI Derleyiciler genellikle komut satrndan altrlan basit bir arayze sahip programlardr. Yaptklar i karmak olmasna karn altrlmalar ok basittir. Microsoftun C# derleyicisi csc.exe programdr. Hlbuki IDE derleme dndaki gelitirme faaliyetlerine yardmc olan programlardr. IDElerin kendi editrleri, menleri ve eitli yardmc aralar vardr. Program IDEde yazdktan sonra derleme aamasna gelindiinde IDE, komut satr derleyicisini ararak ilevini yapar(csc.exe). Aslnda en kark programlar bile Notepad gibi bir editrle yazlarak komut satrndan derlenebilir. 2

MERHABA DNYA PROGRAMI


(12.06.2007 Sal)

Ekrana Merhaba Dnya yazsn kartan iskelet C# program aadaki gibi yazlabilir: namespace CSD { class App { public static void Main() { System.Console.WriteLine(Merhaba Dnya); } } } Bir snflarda ki ssl snflarn, C# program kabaca isim alanlarndan, isim alanlar snflardan, fonksiyonlardan olumaktadr. C#ta fonksiyonlara method da denir. parantez arasndaki blme blok denilmektedir. sim alanlarnn, fonksiyonlarn bloklar vardr.

Programlama dilleri ile doal diller yap olarak birbirine benzemektedir. Programlama dillerine dilbiliminde biimsel diller(Formal Languages) denir. Biimsel diller matematiksel olarak aklanabilir dillerdir. Doal diller matematiksel olarak aklamanaz. Bir dilde 3 eit kural topluluu vardr. 1-) Syntax Kurallar 2-) Semantik Kurallar 3-)Dier Kurallar Dilin tm bu kurallarna gramer denilmektedir. Syntax doru yazm kurallardr. Yani hangi yazmn doru hangi yazmn yanl olduunu gsteren kurallardr. Semantik kurallar ise yazlan eylerin ne anlama geldiine dair kurallar ierir. Ancak syntax olarak doru olan ifadeler semantik olarak yorumlanrlar. Kursumuzda syntax anlatmnda asal parantezler <..> olmas gereken zorunlu eleri, keli parantezler [.] olup olmamas istee bal eleri ifade eder. Bir isim alan aadaki gibi bildirilir: namespace < isim > { } Snf alann genel bildirimi aadaki gibidir: class < isim > { . } 3

ATOM KAVRAMI Bir programlama dilinde yazlm kendi anlaml olan en kk blme atom(token) denilmektedir. Gerekten derleyiciler de ilk aamada kaynak kodu atomlarna ayrmaktadr. Bu ileme Lexical Analys denir. Daha sonra derleyiciler 2. aamada atomlarn dizili srasnn geerli bir program oluturup oluturmadna bakar. Buna Syntax Analys denir. 3. aamada programn ne yapmak istedii tespit edilir. Buna Semantic Analys denir. En son aamada programcnn istedii eyleri yapacak kod retilir. Buna Code Generation denir. 123456Atomlar 6 gruba ayrlr: Anahtar Szckler(Keywords): Deiken olarak isimlendirilmesi yasaklanm, dil iin zel anlam olan szcklere anahtar szck denir. Deikenler(Identifier/Variables): smini programcnn istedii gibi verebildii atomlara deiken diyoruz. Sabitler(Constants/Literals): Dorudan yazlm olan saylara sabit denir. Operatrler(Operators): Bir ileme yol aan, ilem sonrasnda bir deer retilmesini salayan atomlara operatr denir. Stringler(Strings): ki trnak iindeki yazlar trnaklar ile birlikte tek bir atomdur. Bu atomlara string denir. Ayralar(Delineters): Yukardaki gruplarn dnda kalan atomlara ({, ;) ayra denir. DERLEYCLERN HATA MESAJLARI Derleyici, atomlara ayrma ilemini yaptktan sonra programn doru yazlp yazlmadn denetlerken geersiz bir durumla karlarsa hatann kaynan aklayan bir hata mesaj verir. Sonuta derleme ilemi baarsz olur. Derleyiciler genellikle tm error mesajlarn tespit edip bir hamlede listelemektedir. Milyon satr programda bir error olsa bile program derlenemez. Error mesajlar genellikle syntax aamasnda ortaya kt iin bunlara Syntax Error denmektedir. Baz kodlamalar syntax olarak tamamen geerli olduu halde mantksal bir yanl ierebilirler. Bu tr durumlar derleyici fark ederse Warning (Uyar) mesajlar verir. Derleyicinin uyar mesaj vermesi kodun derlenmesini engellemez. Fakat eer gerekten derleyicinin szne ettii gibi bir mantk hatas varsa kod alrken istenileni yapamayacaktr. C# PROGRAMININ DERLENEREK ALITIRILMASI Komut satrndan C# derleyicisinin altrlabilmesi iin PATH evre deikeninin set edilmi olmas gerekmektedir. Komut satr iin Donatlarda deil Visual Studio 2005 Command Prompttan gemek gerekmektedir. Programlar herhangi bir text editrle (rnein Notepad) yazlabilir. Derleme ilemi yle yaplmaldr: 4

csc < proramn ismi > BOLUK KARAKTERLER (WHITE SPACE) Klavyeden boluk oluturmak iin kullanlan Space, Tab ve Enter karakterlerine boluk karakterleri denir. C#IN YAZIM KURALI C#n yazm kural 2 madde de zetlenebilir. 1- Atomlar arasnda istenildii kadar boluk karakteri kullanlabilir. 2- Atomlar istenildii kadar bitiik yazlabilir. Fakat deikenler ile anahtar szckler arasnda en az bir boluk karakteri eklemek gerekir. C# PROGRAMININ ALIMASI Bir isim alannda pek ok snf, bir snf alannda da pek ok fonksiyon bulunabilir. Fakat Main ismindeki fonksiyonun zel bir anlam vardr. C# program Main isimli fonksiyonla almaya balar Main fonksiyonu bitince programda biter. Main fonksiyonu herhangi bir snfn iinde olabilir. Fakat toplam da bir Main fonksiyonu olmaldr. Bir fonksiyonun bizim tarafmzdan yazlmasna fonksiyonun tanmlanmas (function definetion) denir. Fonksiyonun altrlmasna ise fonksiyon arma (function call) denir. Fonksiyon tanmlamann genel ekli aadaki gibidir:

[Eriim Belirleyicisi] [Static] <Geri Dntrc> <sim> ([Parametre Bildirimi]) { } Daha nce tanmlanm bir fonksiyonun arlma ilemi de aadaki gibi yaplr: [sim Alan smi] [.] [Snf smi] [.] <Fonksiyon smi> ([Parametre Listesi]) ;

Anahtar Not Program terimi ok eskiden sylenmitir ve gnmzn gereksinimini tam karlamamaktadr. Program genellikle tek bir exeyi tanmlamak iin kullanlr. Halbuki uygulama (application) bir yada birden fazla program ieren bir projedir. Yani uygulama terimi daha geni bir anlam ifade eder. Windows uygulamalar GUI ve Konsol uygulamalar olarak ikiye ayrlr. Pencereli tip Windows uygulamalarna GUI uygulamalar diyoruz. Siyah ekranla alan uygulamalar da konsol uygulamalar diyoruz. Konsol uygulamalarnda bir imle vardr. Her zaman imleci bulunduu yere yaz yazlr, imlete yazlan miktar kadar ilerletilir. Consol snfnn Write fonksiyonu imleci sonda brakrken WriteLine fonksiyonu ekrana yazdrma ileminden sonra imleci aa satrn bana geirir.

C#TA TEMEL VER TRLER Tr(Type) bir deikenin bellekte ka byte yer kapladn ve onun ierisindeki bilgilerin hangi formatta bulunduunu anlatan bir kavramdr. Temel trler bir tablo halinde aadaki gibi ifade edilebilirler:
Tr Belirten Anahtar Szckler int TAMSAYI TRLER Uint Long Ulong Short Ushort Byte sbyte
GEREK SAYI TRLER

Uzunluk (Byte) 4 4 8 8 2 2 1 1 4 8 16 2 1

Yap Karl System.Int32 System.UInt32 System.Int64 System.UInt64 System.Int16 System.UInt16 System.Byte System.SByte System.Single System.Double System.Decimal System.Char System.Bool

Snr Deerler -2 31 , +2 31 0 , +4 294 967 295 -2 63 , +2 63 -32768 , +32767 0 , +65535 0 , +255 -128 , +127 Az Duyarlkl Gerek Say Duyarllk Yksek Say 28 Digit Yuvarlama Hatasz Gerek Say 0 , 65536 True , False

float double decimal char bool

int tr bir iaretli tamsay trdr. int tr her sistemde 4 byte uzunluktadr. (Cde olduu gibi derleyiciye bal deildir.) uint tr int trnn iaretsiz biimidir. Her tamsay trnn iaretsiz bir versiyonu da vardr. aretsiz trlere pozitif saylar yerletirilir. aretli versiyona gre 2 kat daha byk pozitif saylar yerletirilebilir. long tr 8 byte uzunluunda iaretli bir tamsay trdr.

short tr int trnn yar uzunluunda iaretli bir tamsay trdr. ushort short trnn iaretsiz trdr. byte ve sbyte trleri iaretsiz ve iaretli 1 byte uzunluunda tamsay trleridir. float tr 4 byte uzunluunda noktal bir say trdr. float trnn yuvarlama hatalarna direnci zayftr. double tr float trnden 2 kat daha fazla duyarllktadr. Dolays ile yuvarlama hatalarna direnci daha yksektir. decimal tr 28 digitli, noktal bir sayy yuvarlama hatas olmadan tam olarak tutar. Yapay bir trdr. zellikle finansal hesaplamalarda tercih edilir. Gerek say trlerinin iaretli ve iaretsiz trleri yoktur. Bu trler her zaman iaretlidir. char tr bir karakterin, karakter tablosundaki saysal karln tutmaktadr. Her sistemde 2 byte yer kaplar. Karakter tablosu Unicode tablosudur. (ASCII deil) bool tr yalnzca doru yanl bilgisini tutar. C#ta en fazla kullanlan tamsay tr int trdr. Programc ancak baka bir gereke varsa bu trn dnda bir tr denemelidir. En fazla kullanlan gerek say tr double trdr. nk yuvarlama hatalarna direnci yksektir. BLDRM LEM Kullanlmadan nce bir deikenin derleyiciye tantlmas ilemine bildirim diyoruz. Bildirim yaplmadan bir deiken kullanlamaz. Bildirim ileminin genel biimi aadaki gibidir:

< Tr Belirten Szck >

< Deiken Listesi > ;

rnein: int a; int a, b, c; double x, y, z; int a; double b;

C#ta bildirimler 2 yerde yaplr: 1- Fonksiyonlarn iinde 2- Fonksiyonlarn dnda fakat snf iinde Fonksiyonlarn iinde yaplan bildirimlere yerel bildirimler, snf bildirimi ierisindeki bildirimlere veri eleman bildirimi denir. Benzer biimde fonksiyon ierisindeki deikenlere yerel deikenler, snf ierisindeki deikenlere veri eleman diyoruz. Bir fonksiyonun ana blou olmak zorundadr. Fakat i ie veya ayrk blok alabilir. Yerel deikenler bloun herhangi bir yerinden bildirilebilir. Ancak bildirilme noktasndan sonra kullanlabilir. Bildirilen bir deiken tm programda kullanlmaz. Yalnzca belirli bir program aralnda kullanlabilir. Bir deikenin kullanlabildii program aralna faaliyet alan(scop) denir. Bir yerel deiken hangi blokta bildirilmise bildirim noktasndan sonra, bildirimin yapld blokta ve o bloun kapsad bloklarda kullanlabilir. Ama o blok dnda kullanlamaz. C#ta bir yerel deikenin bildirildii blokta ve o bloun kapsad bloklarda ayn isimde baka bir deiken bildirilmez. rnein: public static void Main() { int a; { long a; --> error } } Fakat ayrk bloklarda ayn isimli deikenler bildirilebilir. rnein: public static void Main() { { int a; --> Geerli } { int a; } } ie bloklarda ayn isimli deikenler bildirilemez. rnein ayn isimli bildirim nce i blokta sonra da d blokta tanmlansa da geersizdir. public static void Main() { { 8 --> Geerli

int a; } int a; } DEKENLERE LK DEER VERLMES Bir deiken bildirilir bildirilmez ierisine deer atanabilir. Bu ileme ilk deer verme denir. rnein: --> error

int a, b=10, c;

C#ta bir deikenin ierisine henz deer atanmamsa, bu deiken ierisindeki deerin kullanlaca bir ifade kullanlamaz. Kullanlrsa error oluur. rnein:

int a, b; b = a;

--> error

Yukardaki rnekte bnin kullanm geerli, ann kullanm geersizdir. rnein:

int a, b; a = 10; b = a; --> Geerli --> Geerli

Yerel deiken bildirilir bildirilmez faaliyet alanna girmi kabul edilir. rnein:

int a = 10, b = a; int a, b = a;

--> Geerli --> Error

Bir deikenin ierisindeki deer deikenin tr ne olursa olsun Console snfnn Write ve WriteLine fonksiyonlar ile yazdrlabilir.

SABTLER Dorudan yazlan saylara sabit denir. Yalnzca deikenlerin deil sabitlerinde bir tr vardr. yi bir C# programcsnn sayya baktnda trn tespit edebilmesi gerekmektedir. 1- Say nokta iermiyorsa ve sonunda da bir ek yoksa say int, uint, long, ulong snrlarnn hangisinin iine ilk giriyorsa sabit o trdr. 0 int 1 int 3 000 000 000 uint

Say eer ulong snrlar iine de smyorsa error oluur. 2- Say nokta iermiyorsa fakat saynn sonunda kk ya da byk L son eki varsa lon ve ulong trlerinin hangisinin ierisine ilk giriyorsa o trdr. 0L long 1L long

3- Say nokta iermiyorsa fakat saynn sonunda kk ya da byk U son eki varsa say uint ya da ulong trlerinin hangisinin iine ilk kez giriyorsa o trdr. 1U uint 2U uint 5 000 000 000 ulong

Say ulong snrlarnn iine de smyorsa error oluur. 4- Say nokta iermiyorsa fakat saynn sonunda kk ya da byk UL veya LU son eki varsa sabit ulong trdr. Sabit ulong snrna da smyorsa error oluur. 1UL ulong 5- Say nokta iermiyorsa fakat sonunda ek yoksa sabit double trdendir. rnein: 3,2 Double 7,4 Double

Say nokta iersin yada iermesin sonunda D , d son eki varsa sabit double trdendir. 6- Say nokta iersin yada iermesin sonunda F , f son eki varsa sabit float trdendir. rnein: 3F Float 3,2 Float

7- Bir karakter tek trnak ierisine alnrsa bu bir sabit belirtir. O karakterin Unicode tablodaki sra numarasn belirtmektedir. 10

C#da yazlar ve karakterler Unicode olarak tutulup saklanmaktadr. C# char tr saysal tr saysal bir trdr ve aritmetik ilemlere sokulabilir. Tek trnak ierisindeki karakterler char trdendir. Baz karakterler ekrana baslmak istendiinde grntlenmez. Grnt yerine birtakm olaylar gerekleir. rnein: Bip sesi duyulur yada cursor hareket eder. Tpk Cde olduu gibi ok kullanlan grntlenemeyen karakterler ters bl biiminde ifade edilmitir. Tek trnak ierisindeki ters bl sonra zel baz karakterler baz grntlenemeyen karakterlerin yerini tutmaktadr. Bunlarn listesi aadaki gibidir: \a \b \f \n \r \t Bip sesi kar (Alert) Cursor bir geri gider (Backspace) Printere gnderilmesi ile sayfa kts (Form Feed) Cursor aa satrn bana geer (New Line) Cursor bulunan satrn bana geer (Curriace Return) Cursor bir tab ilerler

8- Say nokta iersin ya da iermesin sonunda kk yada byk harf m varsa sabit decimal trdendir. 9- True ve false anahtar szckleri bool trden sabit belirtir. 10- C#da byte, sbyte, short, ushort trden sabit kavram yoktur. Anahtar Not: Ters bl karakterine ilikin karakter sabiti \ biiminde yazlamaz. \\ biiminde yazlmak zorundadr. Benzer biimde tek trnak karakterine ilikin karakter sabiti de biiminde deil \ biiminde yazlmak zorundadr. ATAMA LEMNDE TR UYUUMU Atama ileminde sol taraf ve sa taraf farkl trlerden olursa bu trlerin durumuna gre geersiz olabilmektedir. Bu konu ileride ele alnacaktr. Fakat o ders gelene kadar tr uyuumunu salayacaz.

11

FONKSYONLAR C#da fonksiyon terimi yerine method terimi de kullanlmaktadr. Fakat kursumuzda fonksiyon terimini tercih ediyoruz. Bir fonksiyon tanmlamann genel ekli aadaki gibidir:

[Eriim Belirleyicisi] [static] <geri dn deerinin tr> <fonksiyon ismi> ([parametre bildirimi]) { // } Eriim belirleyicisi yalnzca u anahtar szclerden biri olabilir.

public, protected, private, internal, protected internal Eriim belirleyicisi hi yazlmayabilir. Eer yazlmamsa private yazlm gibi ilem grr. Fakat bu konu baka bir derste ele alnana kadar biz public belirleyicisini kullanacaz. Static anahtar szc belirtilebilir ya da belirtilmeyebilir. Static anahtar szc, eriim belirleyicisi anahtar szckle ayn grupta yer ald iin yer deitirmeli olarak yazlabilir. Static anahtar szc ile tanmlanm fonksiyonlara (static method) static, static anahtar szc kullanlmadan bildirilmi fonksiyonlara static olmayan (instance method) fonksiyonlar denilmektedir. Main fonksiyonu zel bir snfta bulunmak zorunda deildir. Herhangi bir snfta bulunabilir. Fakat Main fonksiyonu static olmak zorundadr. Eriim belirleyicisi public olmak zorunda deildir. C#da isim alanlar (namespace) i ie bulunabilir. Hibir isim alan iinde bulunmayan blmde bir isim alandr. Buna da global isim alan denmektedir. Global isim alanna da dorudan snf alan tanmlanabilir. Fakat iyi bir teknik deildir. Global isim alan ierisindeki system isim alan .Netin kendi snflarnn bulunduu isim alandr. .Netin tm snflar ya dorudan system isim alan ierisindedir ya da system isim alan ierisindeki isim alanlar ierisindedir. Anahtar Not: Foo ve Bar isimleri son 10 yldr yazlmnda rneklerde uydurma fonksiyon isimleri olarak kullanlmaktadr. Bu szcklerin bu balamda anlamlar yoktur. 12

Bir static fonksiyon en genel olarak nce isim alan ismi sonra snf ismi belirtilerek arlr. arma ilemi genel biimi aadaki gibidir:

[isim alan ismi] [.] ([parametre listesi]) ;

[snf

ismi]

[.]

<fonksiyon

ismi>

Eer arlacak fonksiyon ayn snfn static fonksiyonu ise isim alan ismi ve snf isminin belirtilmesine gerek yoktur. Sadece fonksiyon ismi belirtilebilir. arlacak static fonksiyon ayn isim alan ierisindeki baka bir snf ierisinde ise isim alan isminin belirtilmesine gerek yoktur. Nihayet fonksiyon baka bir isim alan ierisindeki snfn fonksiyonu ise bu durumda tm nitelikleri yapmak gerekmektedir. FONKSYONLARIN GER DN DEERLER (RETURN VALUE) Fonksiyon altrldktan sonra onu aran fonksiyona ilettii deere geri dn deeri denir. Geri dn deeri bir deikene atanabilir, aritmetik ilemlerde kullanlabilir. Fonksiyonun geri dn tr herhangi bir trden olabilir. Eer geri dn trnn yerine Void anahtar szc yazlrsa bu durum fonksiyonun geri dn deerine sahip olmad anlamna gelir. Fonksiyonun geri dn deeri return anahtar szc ile belirtilir. Return anahtar szcnn genel biimi aadaki gibidir:

return [ifade] ;

Return anahtar szcnn iki ilevi vardr: 1- Fonksiyonu sonlandrr. 2- Geri dn deerini oluturur. Fonksiyonun geri dn deerinde return anahtar szcnn kullanlmas zorunludur. Programn her olas aknda derleyici return anahtar szc ile karlamak zorundadr. Void fonksiyonlarda return kullanlabilir. Fakat return anahtar szcne bir deer yazlamaz. Bu durumda return, fonksiyonu sonlandrmak iin kullanlmtr. Fonksiyonun geri dn deeri nce derleyici tarafndan yaratlan geici bir deikene atanr, oradan alnarak kullanlr. Zaten fonksiyonun geri dn deerinin tr de bu geici deikenin trdr. rnein: x = Func(); Burada aslnda aadaki gibi bir ilem sz konusudur: temp = return ifadesi; 13

x = temp; Yaratlan bu geici deiken yine derleyicinin kendisi tarafndan ilgili ifade bittiinde yok edilir. O halde aslnda return ilemi bir atama ilemidir. Geici deikene atama yaplmaktadr. Fonksiyonun geri dn deerine sahip olmas onu kullanmay zorunlu hale getirmez. Yani geri dn deeri extra bir deerdir. FADE KAVRAMI Deikenlerin, operatrlerin ve sabitlerin her bir birleimine ifade denir. rnein: x , x + 1, 10, x + 1 + 5, x + y birer ifadedir. YEREL DEKENLERN MRLER Bir deikenin bellekte kald zamana mr(duration) denir. Anahtar Not: C#da /* ve */ arasndaki yazlar derleyici tarafndan dikkate alnmaz. Programc kaynak koda ilikin aklamalar bu ekilde yazabilir. Benzer biimde //dan satr sonuna kadarki yazda dikkate alnmaz. Bir yerel deiken, programn ak tanmlama noktasna geldiinde oluturulur. Ak deikenin tanmland bloktan ktnda otomatik yok edilir. Yani bir programn yerel deikenlerinin hepsi ayn anda bellekte deildir. Yerel deikenlerin bu ekilde oluturulup yok edilmeleri ok hzl yaplmaktadr. Yerel deikenler bellein stock denilen blmnde oluturulur. Yerel bir deiken tanmland blok dnda kullanamamzn nedeni zaten o deikenin blok dna kldnda bellekte yaamyor olmasndan kaynaklanmaktadr. OPERATRLER Bir ileme yol aan ilem sonrasnda bir deer retilmesini salayan atomlara operatr denir. Operatrleri biimde snflandrabiliriz: 1. levlerine gre 2. Operant saylarna gre 3. Operatrn konumuna gre 1. levlerine Gre Snflandrma: Operatrlerin kullanldna ynelik snflandrmadr. a. Aritmetik operatrler + - * / operatrleridir. 14 hangi amala

b. Karlatrma operatrleri (Comparison veya relational operators) < > gibi operatrlerdir. c. Mantksal operatrler(Logical operators) Ve veya not tarz operatrlerdir. d. Bit operatrleri (Bit seviyesinde operatrlerdir) e. zel amal operatrler (Special purposes) 2. Operant Saylarna Gre Snflandrma: Operatrlerin soktuu ifadelere operant denir. a+b a. Tek operantl operatrler(Unary operators) a! b. ki operantl operatrler (Binary operatorler) a+b c. operantl operatrler (Ternary Operators) 3. Operatrn Konumuna Gre Snflandrma: a. nek operatrler - Prefix b. Araek operatrler - Infix c. Son ek operatrler Postix C sharpta tm iki operantl operatrler araek- infix durumundadr. Bir operatr teknik olarak aklayabilmek iin snflandrmada da operatrn nereye dtn belirtmek gerekir. rnein + operatr iki operantl, araek bir aritmetik operatrdr. OPERATRLER ARASINDAK NCELK LKS Ayn ifade ierisinde birden fazla operatr kullanldnda bu operatrler belirli bir srada yaplr. Operatrlerin arasndaki ncelik ilikisi ncelik tablosu denilen bir tablo ile gsterilir. ncelik tablosu satrlarda oluur. st satrlar alt satrlardan daha nceliklidir. ncelik Tablosu: () * + = / Soldan Saa Soldan Saa Soldan Saa Sadan Sola ileme

ncelik tablosunda her satrn sana Soldan saa veya sadan sola ifadesi yazldr. Soldan saa demek, o satrda bulunan operatrlerin ifade ierisinde hangisi soldaysa o nce yaplr demektir. Ayn satrdaki operatrler eit nceliklidir. Soldan saa veya sadan sola bu eitlikteki ncelii bildirir. Yani ncelik tablosunda, ayn satrdaki operatrler farkl srada yazlsa da ayn anlama gelir. * / + - Operatrleri: Bu operatrler, iki operantl araek aritmetik operatrlerdir. Klasik drt ilem yaparlar. % Operatr: Bu operatr de, iki operantl araek bir aritmetik operatrdr. 10 % 3 eklinde gsterilir. Bu operatr soldaki operantn sadaki operanda blmnden elde edilen kalan verir. 15

Anahtar Notlar : C ve C++da % operatrnn operantlar tam say trlerine ilikin olmak zorundadr ama C# da byle bir zorunluluk yoktur. Yani 20.2 % 3 veya -20 % 3 geerli bir mod kullanmdr. ncelik Tablosu: () * + = / % Soldan Saa Soldan Saa Soldan Saa Sadan Sola

% operatr * ve / operatrleri ile ayn dzeyde soldan saa bulunur. aret + ve aret operatrleri: Tamamen farkl operatrler ayn sembolle ifade ediliyor olabilir. rnein; - a ya da + a derken kullanlan ve + operatrleri toplama ve kartma operatrleri deildir. Bunlara iaret + ve iaret operatrleri denir. Bu operatrler tek operantl, nek operatrlerdir. operatr operantn negatif deerini elde eder. aret + operatr, srf iaret eksi operatr olduu iin btnlk salamak amacyla bulundurulmutur ve bir ilevi yoktur. Yani, operandn deerinin aynsn retir. Bu operatrler, ncelik tablosunun ikinci dzeyinde sadan sola grupta bulunur. levine gre aritmetik bir operatrdr. + () * + = { int a; a = -3; System.Console.WriteLine(a); } / % Sadan Sola(iaret + ve iaret - operatrleri) Soldan Saa Soldan Saa Soldan Saa Sadan Sola Ekran kts: 3

Anahtar Notlar Atomlara ayrma ilemi srasnda tpk C/C++ daki gibi atom olmaya aday en uzun karakter kmesi tek bir atom olarak ele alnmaktadr. Bu nedenle, iki sembolden oluan baz operatrler vardr. Bu durumda bu iki semboln bitiik yazlmas gerekir. Eer bu iki sembol ayr yazlrsa, derleyici iki ayr atom olduu fikrine kaplr ve error oluur. rnein; a>=b ifadesi a> = b olarak yazlrsa error oluur.

16

Hi phesiz derleyici, toplama ve karma operatrlerini ifade ierisindeki konumlarndan hareketle iaret + ve iaret operatrlerinden ayrmaktadr. rnein; z = x ----y; z =x --kartma aret Operatr Operatr y;

Xten sonraki ilk iareti kartma olmakla beraber dier operatrleri iaret operatrleridir. Anahtar Notlar ncelik parantezinin ierisinde ifade tanmna uyan bir atom grubunun bulunmas zorunludur. Mademki, tek bana bir operatr ifade deildir, o halde tek bana bir operatr ncelik parantezi ierisine alnamaz.

++ ve -- operatrleri : Bu operatrler, tek operantl hem nek hem de sonek biiminde kullanlabilen operatrlerdir. ++ artrma (increment) operatr, -- operatrne eksiltme (decrement) operatr denir. ++, operand olan deikenin deerini bir artrr, -- ise bir eksiltir. Bu operatrlerin nek ve sonek kullanmlar arasnda bir fark vardr. Bu operatrler, ikinci dzeyde sadan sola bulunurlar. () + * + = / ++ % -Soldan Saa Sadan Sola (iaret + ve iaret - operatrleri) Soldan Saa Soldan Saa Sadan Sola

nek kullanmnda, arttrma ve eksiltme tablodaki ncelikte yaplr ve geri kalan ileme deikeni arttrlm veya eksiltilmi hali sokulur. a = 3 b = ++a * 2 i1 = ++a => 4 i2 = i1 * 2 => 8 i3 => b = i2 = 8 Hlbuki son ek kullanmda yine artrma ve eksiltme yaplr ama geri kalan ilemlere deikenin artrlmam veya eksiltilmemi hali sokulur. a = 3 b = ++a * 2 i1 = ++a => 4 i2 = i1 * 2 => 6 i3 => b = i2 = 6 17

rnein; aadaki ifade iin int a = 3, b = 2, c; c = ++a * b -- * 2 ; //c=16 b=1 a=4 deerlerini alr. System.Console.WriteLine(a); System.Console.WriteLine(b); System.Console.WriteLine(c); rnein: int a = 3, b; b = ++a; //a =4 b = 4 rnein; int a = 3, b; b = a++; //a =4 b = 3 phesiz, bu operatrler tek balarna kullanldnda n ek ya da sonek biimler arasnda bir fark olumaz. rnein; ++a; ile a++; arasnda bir fark yoktur. nk tek balarna kullanlmlardr. ++ ve operatrlerinin operantlarnn deiken olmas gerekir. rnein; ++3; //error verir. Anahtar Notlar (Cciler iin) C/C++ da bir deiken bir ifadede ++ ya da -- ile kullanlmsa o deikenin o ifadede bir daha gzkmemesi gerekir. Aksi halde, tanmsz davran oluur. Hlbuki C# da byle bir durum sz konusu deildir. Aadaki ifade tamamen geerlidir: int a=3, b; b=++a + ++a; //b = 9 a=5

Karlatrma operatrleri: C# da alt tane karlatrma operatr vardr. <, >, <=, >=, ==, != operatrleri aritmetik operatrlerden daha dk nceliklidir. () + ++ -Soldan Saa Sadan Sola(iaret + ve iaret - operatrleri) 18

* / % Soldan Saa + Soldan Saa = Sadan Sola <, >, <=, >=, ==, != Soldan Saa = Sadan Sola Bu operatrlerde bool trden deer retilir. Yani sonu yalnzca bool trden deikenlere atanabilir. nerme doruysa true deerini, yanlsa false deerini retirler. int a = 3; bool b; b = a > 1; //b=True bool b; b = 1 + 1 < 2 + 3; System.Console.WriteLine(b); Ekran kts: False

Mantksal Operatrler: adet mantksal operatr vardr. ! not operatrdr. Tek operantl ve nek bir operatrdr. && yani and operatr, || yani or operatrdrler. Bu operatrler iki operantl araek operatrlerdir. ! ncelik tablosunun ikinci dzeyinde sadan sola bulunur. && ve || karlatrma operatrlerinden daha dk nceliklidir. () Soldan Saa + ++ -Sadan Sola(iaret + ve iaret - operatrleri) * / % Soldan Saa + Soldan Saa = Sadan Sola <, >, <=, >=, ==, != Soldan Saa &&(and iareti) Soldan Saa ||(or iareti) Soldan Saa = Sadan Sola Mantksal operatrn operantlarnn bool trden olmas zorunludur. Bu operatrler, ilgili mantksal ilemi yaparlar ve sonu olarak bool trden bir rn retirler. rnein: e = a > b && c > d; Yukardaki ifade de nce a > b sonra c > d yaplr. Bu iler bool trden rn verdiine gre && operatrnn kullanm dorudur. Tabi, enin de bool trden olmas gerekir. rnein: 19

bool b; b = 3 > 2 && 2 < 8 ; System.Console.WriteLine(b); Ekran kts: True rnein: bool b; b = !Func(); System.Console.WriteLine(b); public static bool Func() { return true; } Ekran kts: False

&& ve || operatrlerinin ksa devre zellii vardr. Bu operatrler klasik ncelik kuralna uymazlar. || operatrnn sanda ne olursa olsun nce sol taraf tamamen yaplp bitirilir, eer sol tarafndaki ifade true ise sa taraf hi yaplmaz ve sonu true olarak tespit edilir. && operatrnn de nce sol taraf tamamen yaplp bitirilir. Eer sol taraf false ise sa taraf hi yaplmaz ve sonu false olarak tespit edilir. Tek | ve tek &, bit dzeyindeki or ve and operatrleridir. Her ne kadar bu operatrler bit operatrleri olsa da bool trlerle de kullanlabilir. Fakat bu operatrlerin ksa devre zellii yoktur. Yani operatrn her iki taraf da yaplmaktadr. Atama operatr: Atama operatrleri de iki operantl araek operatrlerdir. Atama operatrnn solunda bir deiken bulunmaldr. Atama operatr de bir deer retmektedir. Atama operatrnn rettii deer, deikene atanm olan deerdir. Biz bu rn, baka ilemlerde kullanabiliriz. rnek: a = b = 0 i1 = b = 0; a = i1 => 0 rnek: a = (b = 10) + 20; Burada nce bye 10 atanr. Elde edilen 10 , 20 ile toplanp aya atanr. Noktal Virgln levi: a = 10+20; 20

b = 30; ; ifadeleri sonlandrmak iin kullanlr. ki; arasndaki ifade dierlerinden farkl bir biimde nceliklendirilir ve yaplr. Eer programc ; unutursa nceki ifade ile sonraki ifade tek bir ifade olarak deerlendirilir ve error oluur. rnein; a = 10 + 20 b = 30; // bu ifade iki satrdan olumaktadr. nk st satrda; yok Programlama dillerinde, ifadeleri sonlandrmak iin kullanlan bu tr atomlara sonlandrc (terminator) denilmektedir. Basic gibi baz dillerde sonlandrc olarak \n (alt satrn bana ge) karakteri kullanlmaktadr. Bu nedenle bu dillerde her satra tek bir ifade yazlmaktadr. C#da bir ilemin sonucunun, gizli ya da ak bir deikene atanmas gerekir. rnein; a + b; ilemi anlamszdr ve error oluturur. Fakat fonksiyon armalar (fonksiyon zaten bir yan etkiye yol at iin) bu biimde deerlendirilmez. rnein; Func(); Fonksiyonun geri dn deeri kullanlmak zorunda deildir. Bu durum geerlidir. Hlbuki Func()+1; ifadesi geersizdir ve error verir. Anahtar Notlar C/C++ da bir ilemin sonucunun bir yere atanmas zorunlu deildir. Yani yukardaki rneklerde C/C++ da geerlidir ve derleyici en fazla uyar verir.

VISUAL STUDIO IDESNN TEMEL KULLANIMI Visual Studio IDEsinde bir C# programn derleyip altrmak iin nce bir proje oluturmak gerekir. Projeler ise solution denilen bir ortamda bulunmaktadr. Bir solution, bir ya da birden fazla projeyi ierebilir. O halde programcnn bir solution yaratp iine bir proje yerletirmesi gerekir. Bunun iin file/new/project mens seilir. Karmza new project isimli bir diyalog penceresi kar. Bu diyalog penceresinden proje tr olarak Visual C#/windows/empty project seilir. Normal olarak hem solution iin hem de project iin ayr bir klasr yaratlr. Yani, normal olarak yaratm ileminin sonunda bir solution klasr bir de onun iinde project klasr oluturur. 21

Solution klasrnn yaratlaca taban klasr location ksmnda belirtilir. Sonra projeye bir isim verilir. stenirse solutiona da ayr bir isim verilebilir. Bu isimler yaratlacak klasrlerin isimleri olur. Bir solution yaratldnda solution explorer isimli bir pencere de yaratlr. Bu pencere kapatlrsa view mensnden ya da ara ubuklarndan yine grntlenir. Proje yaratldktan sonra .cs uzantl bir kaynak dosyay projenin iine yerletirmek gerekir. Kaynak dosya eklemek iin project/add new item seilebilir. Ya da solution explorerda proje isminin stne sa tklanarak kan balam mensnden de seim yaplabilir. Daha sonra kan add new item diyalog penceresinden code file seilir. Kaynak dosyaya isim verilerek yaratlr. Daha sonra program dosyaya yazlr. Bu ilemlerden sonra derleme iin built/built solution seilir. Artk exe olumutur. altrma ilemi komut satrndan yaplabilir. Ya da hi komut satrna kmadan debug/start without debugging (ctrl+f5) ile yaplabilir. Eer ctrl+f5 yaplrsa zaten hem derleme hem altrma ilemi otomatik olarak gerekletirilir. Daha nce yaratlm olan bir solution file/open/projectsolution yoluyla alabilir. Programc, sln uzantl dosyay seerek solution aabilir. PARAMETRE DEKENLER Bir fonksiyonun parametre deikenleri fonksiyon tanmlanrken parametre parantezinin iinde bildirilir. Parametre parantezinin iine aralarna virgl konularak tr ve deiken isimleri verilir. Parametre deikenlerine ilk deer verilemez. rnein; public static void func (int a , int b) { //.... //.... } Parametre deikenlerinin trleri ayn olsa bile tr belirten anahtar szck her defasnda yazlmak zorundadr. rnein; public static void func (int a , b) Error verir. { //.... //.... }

Parametreli bir fonksiyon arlrken parametre deikeni says kadar ifade yazlmak zorundadr. 22

Anahtar Notlar Pek ok programlama dilinin standartlarnda parametre ve argman terimleri farkl anlamlarda kullanlmaktadr. Fonksiyon arlrken yazlan ifadelere argman (argument), fonksiyonun parametre deikenlerine parametre (parameter) denilmektedir. Halbuki kursumuzda argman yerine parametre, parametre yerine parametre deikeni kullanlmaktadr. public static void Func(int a, int b) { // } // Func(100 + 300 , 200 + 500); Parametreli bir fonksiyon arldnda srasyla unlar olur; 1. Parametrelerin deerleri hesaplanr. (100+300 gibi) 2. Fonksiyonun parametre deikenleri yaratlr. 3. Parametrelerden parametre deikenlerine karlkl atama yaplr. 4. Ak fonksiyona geirilir. Parametre deikenleri, fonksiyon arldnda fonksiyon sonlandnda da yok edilmektedir. public static void Main() { int a = 10 , b = 20 , result; result = Add(a + 1 , b + 1); System.Console.WriteLine(result); } public static int Add(int a, int b) { return a + b; } yaratlmakta ve

Grld gibi parametreli fonksiyonlarn arlmas da gizli bir atama ilemine yol amaktadr. System.Math Snf: Math snfnn temel matematiksel ilemleri yapan pek ok faydal fonksiyonu vardr. sqrt fonksiyonu double bir parametre alr ve geri dn deeri de double trdendir. Parametresi ile ald deerin karekkn geri dner. public static void Main() { Double a = 100 , result; Result = System.Math.Sqrt(a); 23

System.Console.WriteLine(result); } Pow fonksiyonu birinci parametresi ile belirtilen deerin ikinci parametresi ile belirtilen kuvvetini alr ve bu deeri geri dner. Sin, cos, tan, asin, acos, atan fonksiyonlar trigonometrik ilemler yapar. Parametre olan alar radyan cinsindendir. Abs fonksiyonlar (absolute value) mutlak deer almakta kullanlr.

Deyimler(statement): Bir C# program kabaca isim alanlarndan , isim alanlar snflardan, snflar veri elemanlar ve fonksiyonlardan, fonksiyonlar da deyimlerden oluur. Fonksiyonlar deyimlerden oluur, deyimler doal dillerdeki cmleler gibidir. Deyimler, aadaki gibi snflandrlabilir; 1. Yaln Deyimler (Simple Statement): Bir ifadenin sonuna ; konulursa bu ifade deyim olur. Byle deyimlere basit deyim denir. rnein; a=b+c; grld gibi ifade kavram ; iermez. 2. Bileik Deyimler (Compound statement): bir blok ierisine yerletirilmi 0 ya da daha fazla deyime bileik deyim denir. Yani bloklar bileik deyim belirtmektedir. rnek: { X=10; { Y=20; Z=30; } }

Burada bloun tamam tek bir deyimdir. Bu birleik deyim tek bir deyim iermektedir. Grld gibi, bir deyim baka deyimleri ierebilir. 3. Bildirim Deyimleri (Declaration statement): Bildirim yapmakta kullandmz ifadeler de bir deyim oluturur. rnein; int a, b; 4. Kontrol Deyimleri(Control Statement) : Programn ak zerinde etkili olan if, for, while gibi anahtar szcklerle oluturulan cmleler de birer deyimdir. 5. Bo deyim (null statement) : Sonunda bir ifade olmadan kullanlan ;lere bo deyim denir. rnein: x=10;;; (en sondaki iki adet ; bo deyimdir) bo deyimin karsnda derleyici bir ey yapmaz. Fakat bo deyim de bir deyim olarak deerlendirilir. IF Deyimi : If deyiminin genel biimi yledir; if (<bool trden ifade> <deyim> [else <deyim>] 24

Derleyici, if anahtar szcnden sonra parantezler ierisinde bool trden bir ifade bekler. If deyiminin doruysa ve yanlsa ksmnda tek bir deyim bulunmak zorundadr. Eer doruysa ve yanlsa ksmnda birden fazla deyim varsa programc bloklama yaparak bunlar tek deyim haline getirmek zorundadr. Anahtar Notlar C/C++da if parantezi ierisindeki ifade herhangi bir trden olabilir. If deyimi yle alr: Derleyici if parantezi ierisindeki ifadenin deerini hesaplar. Bu deer true ise if deyiminin doruysa ksmndaki deyimi altrr, yanlsa ksmn atlar. False ise yanlsa ksmndaki deeri altrr. Anahtar Notlar Klavyeden T trnden bir bilgi okumak iin aadaki ifade kullanlabilir: T.Parse(System.Console.Readline())

puclic static void Main() { int val; val = int.Parse(System.Console.ReadLine()); System.Console.WriteLine(val); }

puclic static void Main() { int val; val = int.Parse(System.Console.ReadLine()); if(val > 10) System.Console.WriteLine(Evet); else System.Console.WriteLine(Hayr); }

If deyiminin else ksm bulunmak zorunda deildir. Derleyici, if deyiminin doruysa ksmndan sonra else anahtar szcnn gelip gelmediine bakar. Eer else anahtar szc, gelmemise if deyiminin bittiini dnr. If deyiminin yanllkla ; ile kapatlmas hatas ile karlalmaktadr. rnein; 25

if (ifade1); ifade2; Burada artk if deyiminin doruysa ksmnda bo deyim Dolaysyla, ifade2; if deyiminin dndadr. vardr.

ie if deyimleri: f deyiminin tamam, doruysa ve yanlsa ksm ile birlikte tek bir deyimdir. rnein; if ifade1 if ifade2 { ifade1; ifade 2; } else { ifade3; ifade 4; } else ifade7; ifade8; ki ife karlk tek bir elsein bulunduu aadaki durumda elsein iteki ife ilikin olduu kabul edilmektedir. f(ifade1) if(ifade2) ifade3; else ifade4; Yani bu if cmlesi, u anlama gelmektedir.

if(ifade1) if (ifade2) { fade3; } Else fade4;

Eer else ksmnn dtaki ife ilikin olmas isteniyorsa bilinli olarak bloklama yaplmas gerekir. if(ifade1) { if (ifade2) 26

ifade3; } else ifade4;

Bir karlatrma doruyken dierinin doru olma olasl yoksa bu iki karlatrmaya ayrk (discreet ) karlatrmalar denir. rnein; a > 10 a < 0 Karlatrmalar ayrktr. rnein; a == 1 a == 2 Karlatrmalar ayrktr. Fakat a > 0 a > 10 Karlatrmalar ayrk deildir. Ayrk karlatrmalarn ayrk if deyimleri ile ifade edilmesi kt bir tekniktir. rnein; if(a > 10) ifade1; if(a < 0) ifade2; Ayrk karlatrmalarn else if biiminde ifade edilmesi gerekir.

if(a > 10) ifade1; else if a(a < 0) ifade2; Bazen ayrk karlatrmalarn says fazla olduu iin bir else-if merdiveni sz konusu olabilir. rnein; if(a == 1) fade1; else if (a == 2) ifade2; else if(a == 3) ifade3; else if (a == 4) 27

ifade4; System.Char isimli snfn char bir deeri parametre olarak alp onu test eden eitli isXXX (is ile balayan) fonksiyonlar vardr. Bu fonksiyonlarn geri dn deeri bool trndendir. IsUpper; byk harf mi testini, IsLower; kk harf mi testini, IsDigit; saysal bir karakter mi testini, IsLetter; harf mi testini, IsWhiteSpace; boluk karakterlerinden biri mi testini yapar. public static void Main() { char ch; ch = char.Parse(System.Console.ReadLine()); if(System.Char.IsUpper(ch)) System.Console.WriteLine(Byk Harf); else if(System.Char.IsLower(ch)) System.Console.WriteLine(Kk Harf); else if(System.Char.IsDigit(ch)) System.Console.WriteLine(Digit); else if(System.Char.IsWhiteSpace(ch)) System.Console.WriteLine(Boluk Karakteri); else System.Console.WriteLine(Dier); } If deyiminin doruysa ksm olmak zorundadr. Yalnzca yanlsa ksm olan bir if yapay olarak yle salanabilir; if (ifade) ; else ifade1; Bunun yerine, soru ifadesini aadaki gibi deitirmek daha uygundur. if (!ifade) ifade1; Dng Deyimleri: Bir program parasnn yinelemeli (literatif) olarak altrlmasn salayan deyimlere dng deyimleri denir. C#da tr deyim vardr. 1- While dngleri a- Kontroln bata yapld while dngleri b- Kontroln sonda yapld while dngleri 28

2- For dngleri 3- For Each dngleri

Anahtar Notlar C/C++da for each dngs yoktur. For each dngleri diziler konusundan sonra ele alnacaktr. Kontroln Bata Yapld While Dngleri: While dngleri bir koulun doru olduu srece yinelenen dnglerdir. Genel biimi yledir; While(<bool trden ifade>) <deyim> while anahtar szcnden sonra parantezlerin iinde bool trden bir ifade bulunmak zorundadr. Dngnn iinde tek bir deyim vardr. Eer birden fazla deyimin dng ierisinde bulundurulmas isteniyorsa bloklanmas lazmdr. while dngs yle alr: while parantezi ierisindeki ifadenin deeri hesaplanr eer bu deer true ise dng deyimi altrlr ve baa dnlr, false ise programn ak dng dndaki ilk deyimle devam eder. public static void Main() { int i = 0; Ekran kts: 0 1 2 while (i < 10) 3 { 4 5 System.Console.WriteLine(i); 6 ++i; 7 } 8 9

While parantezinin ierisinde son ek olarak bir ++ ya da -- varsa deikenin artrlmam ya da eksiltilmemi hali test ilemine girer. while (i++ < 10) { System.Console.WriteLine (i); } while (i >= 0) { System.Console.WriteLine(i); --i; }

29

Dnglerin yanllkla bo karlalmaktadr. rnein;

deyimle

kapatlmas

durumuyla

sk

int i = 0; while (i < 10) ; { System.Console.WriteLine(i); ++i; } Burada dng bo deyimle olumaktadr ve dolaysyla sonsuz dng oluur. Krmz ile iaretli olan bo deyimdir ve o gerekletirilir. Sonsuz dng yle kurulabilir; while (true) { // ..... }

Kontroln sonda Yapld While Dngleri: Bu dnglere do-while dngleri de denilmektedir. Genel biimi: Do <deyim> While (<bool trden bir ifade>); Buradaki ; iareti bir bo deyim deil syntaxn bir parasdr. rnek: int=0; do { System.Console.WriteLine(i); ++i; } while (i<10); Kontroln sonda yapld while dngleri ok seyrek kullanlmaktadr. char ch; do { System.Console.WriteLine( (E)vet / (H)ayr ); ch = char.Parse(System.Console.ReadLine()); } while (ch != e && ch != h); 30

For Dngleri: For dngleri ilevsel olarak while dnglerini kapsamaktadr. En sk kullanlan dnglerdir. Genel biimleri: For ([ifade1];[ifade2(bool)];[ifade3]) <deyim>

Derleyici for anahtar szcnden sonra ;; bekler. Bu iki noktal virgl for dngsn ksma ayrr. Bir ve nc ksmdaki ifadeler herhangi bir trden olabilir fakat ikinci ksmdaki ifade bool trden olmak zorundadr. For dngs yle alr: int i; for (i = 0 ; i < 10 ; ++i;) Birinci ksmdaki ifade dngye girite yalnz bir kez yaplr ve bir daha hi yaplmaz. Dng, ikinci ksmdaki ifade true olduu srece devam eder. nc ksmdaki ifade, dng deyimi altrldktan sonra her yinelemede baa dnerken altrlmaktadr. public static void Main() { int i; for (i = 0 ; i < 10 ; ++i) System.Console.WriteLine(i); } Asal say bulmak iin en basit fakat etkin yntemlerden biri yledir: For dngsnn birinci ksm dngnn yukarsna alnrsa edeerlik bozulmaz. rnein: int = i; i = 0; for (; i < 10 ; ++i) System.Console.WriteLine(i); Dngnn nc ksm yazlmayp dng deyiminden sonraya alnabilir: i = 0; for (; i < 10 ;) { System.Console.WriteLine(i); ++i; } 31

Dng iin iki noktal virgl mutlaka lazmdr. Bo bile olsa ; konulur. for (; i>10; ++i) { } Birinci ve nc ksm olmayan for dngs while dngs ile edeerdir. rnein; for (; ifade;) { //... } ile while (ifade) { //... } edeerdir. For dngsnn ikinci ksm yazlmazsa koulun her zaman saland kabul edilir. Yani sonsuz dng oluur. rnein;

for (i = 0 ; ; ++i) //sonsuz dng { //... } ile for (i = 0 ; true ; ++i) //sonsuz dng { //... } ayndr. Nihayet for dngsnn hibir ksm olmayabilir. Fakat ; n her zaman bulunmas gerekir. rnein; for ( ; ; ) // sonsuz dng { //... } 32

For dngsnn birinci ksmnda (fakat dier ksmlarnda deil) bildirim yaplabilir. rnein; for (int i = 0 ; i < 100;++i) { //.. } For dngsnn birinci ksmnda belirtilen deikenlerin faaliyet alan sadece dng blounun ierisini kapsar. Yani; for (int i = 0 ; i < 100 ; ++i) { // } leminin edeeri; int i; for (i = 0 ; i < 100 ; ++i) { //.. } biimindedir. Bu edeerlikten hareketle, ayn blok ierisinde aadaki gibi iki for dngsnn bulunmas soruna yol amaz. for (int i = 0 ; i < 100 ; ++i) { //... } for (int i = 0 ; i < 100 ; ++i) { //... } For dngsnn en ok kullanld kalp yledir; for (ilk deer ; koul ; artrm) { //... } Fakat dngnn blmleri bu biimde bir kalp izlemek zorunda deildir.
for (System.Console.Writeline(Bir) ; i<10 ; System.Console.Writeline()) { //.. }

33

gibi de olabilir Anahtar Notlar Bir deeri bir deikene atayp sonucu karlatrmak iin atama ilemine ncelik vermek amacyla parantez kullanmak gerekir. rnein; while ((val = func()) !=0) { //.. } Burada func fonksiyonunun geri dn eeri val deikenine atanp 0 ile karlatrlmtr. Eer parantezler olmasayd karlatrmann sonucu olan bool deer val deikenine atanrd. Bir dngnn ierisinde baka bir dng olabilir. rnein; for (int i=0 ; i<10 ; ++i) for (int k=0; k<10 ; ++k) System.Console.WriteLine(i,k); Anahtar notlar: Console snfnn write ve writeline fonksiyonlarnn daha kullanl bir versiyonu vardr. Bu fonksiyonlar iki trnak iindeki karakteri ekrana yazar. Fakat kme parantezlerini grdklerinde {n} karakterlerini ekrana yazmazlar. Burada n bir saydr ve parametre indeksi belirtmektedir. Bu Kme parantezleri bir yer tutucudur. Bu karakterler yerine ninci indeksteki parametrenin deeri yazlr. ki trnaktan sonraki ilk parametrenin indeksi sfrdr. System.Console.WriteLine(( (0) , (1) ),i ,k ); Break deyimi: Break deyiminin kullanlabilmesi iin bir dngnn ierisinde ya da switch deyiminin ierisinde olmak gerekir. Kullanm yledir: break; Programn ak break anahtar dndaki ilk deyimle devam eder. szcn grdnde ak dngnn

Bazen dngden k pek ok koula bal olabilir. Tm koullar while ya da for parantezi ierisinde deerlendirmek iyi bir teknik deildir. Belki en nemli koul while ya da for parantezinde belirtilebilir ve dier koullar dngnn ierisinde if ve break deyimleri ile sorgulanabilir. continue DEYM Continue deyimi yalnzca dngler ierisinde kullanlabilir. Kullanm biimi yledir: 34

continue; Ak continue anahtar szcn grdnde sanki dng deyimi bitmi de yeni bir yinelemeye geiyormu gibi bir etki sz konusudur. Yani while dnglerin de continue kullanlrsa ak hemen dngnn bana dndrlerek yeni bir yinelemeye geilir, for dngsnde continue kullanlrsa dngnn nc ksm yaplarak baa dnlr.(nc ksm arttrma veya azaltmann yapld ksm) public static void Main() { for (int i = 0 ; i < 10 ; ++i) { if (i % == 0) continue; System.Console.WriteLine(i); } } goto DEYM goto deyimi programn akn koulsuz olarak fonksiyon ierisinde istenilen bir noktaya aktarr. Genel biimi yledir: goto <etiket>; // etiket: <deyim> Programn ak goto anahtar szcn grdnde etiketle belirtilen noktaya atlar. Goto ile ak baka bir fonksiyona atlatlamaz. Ayn fonksiyonda yukarya ya da aaya atlatlabilir. C# standartlarna gre goto etiketinden sonra en az bir deyimin bulunmas gerekmektedir. Anahtar Notlar: Consol snfnn ReadKey isimli fonksiyonu klavyeden bir tua baslana kadar bekleme oluturur. goto deyimi zellikle i ie dnglerden kmak iin, dng iindeki switch deyiminden tek hamlede kmak iin ya da ters srada boaltm yapmak iin kullanlr. goto deyimi ile blok ilerine atlama yaplmaz. SABT FADELER Yalnzca sabit ve operantlardan oluan ifadelere sabit ifadeler(constant expressions) denir. rnein: 3 , 3+2 , 5+2-3 birer sabit ifadedir. Sabit ifadelerin net saysal deerleri derleme aamasnda hesaplanr. 35

switch DEYM switch deyimi bir ifadenin eitli saysal deerleri iin farkl ilemler yaplmas amacyla kullanlmaktadr. Genel biimi yledir: switch (<ifade>) { case <sabit ifade> : [deyim listesi] break; case <sabit ifade> : [deyim listesi] break; // default : [deyim listesi] break;

switch deyimi yle alr: Derleyici switch parantezi ierisindeki ifadenin saysal deerini hesaplar. Bu deer ile tamamen ayn olan bir case blm aratrr. Bulursa ak bir goto deyimi gibi ilgili case blmne atlatr.(Yani ak : nin sana atlatlr) Ak o noktadan deyimleri altrarak devam eder, break anahtar szc grldnde ak switch dndaki ilk deyimle devam eder. Eer switch parantezi ierisindeki ifadeye tam eit bir case blm bulunamazsa ve switch deyiminin default blm varsa ak default blmne aktarlr. Eer default blm de yoksa ak switch dndaki ilk deyimle devam eder. public static void Main() { int val; val = int.Parse(System.Console.ReadLine());
okuma

Klavyeden

bilgi

switch(val) { case 1: System.Console.WriteLine(Bir); break; case 2: System.Console.WriteLine(ki); break; case 3: System.Console.WriteLine(); 36

break; default: System.Console.WriteLine(Dier); break; } switch sonu System.Console.WriteLine(Son); } Ayn deere ait birden fazla case deyimi olamaz. Case blmlerinin sral olmas ya da default blmnn sonda olmas zorunlu deildir. Case ifadeleri tamsay trlerine ilikin deer olmaldr. Gerek say trlerine ilikin olamaz.(3,2 - 5,4 gibi) Benzer biimde switch parantezi iindeki ifadenin de tamsay trlerine ilikin olmaldr. Ancak istisna olarak switch iindeki case ifadelerinde string kullanlabilir. C#ta aaya dme(fall trough) zellii yoktur. Akn bir case blmnde dierine geiyor olmas error oluturur. Akn bir case blmnden dierine gememesini salamann en pratik yolu her case blmnn sonuna break yerletirmektir. Akn aa dmesini engellemenin tek yolu break kullanmak deildir. rnein aadaki gibi bir sonsuz dng de bu gereksinimi salar: case 1: // for( ; ;) Geerli ; case 2: // Ayn amala goto da kullanlabilir: case 1: // goto EXIT; Geerli case 2: // Ya da return deyimi de ayn grevi yapar: case 1: // return; Geerli case 2: //

37

Bazen farkl case ifadeleri iin ayn eylerin yaplmas istenebilir. Bunu salamann en pratik yolu aadaki gibi yap kullanmaktr. Daha pratik bir yolu yoktur. case 1: case 2: // break; C# standartlarna gre eer bir case blmnde hibir deyim bulundurulmamsa akn aadaki case blmne dmesi geerlidir. Fakat bir case blmnde en az bir deyim varsa ak aaya dmemelidir. rnein: case 1: ; error case 2: // break; Yine de bazen bir case blmnde bir takm eyler yapldktan sonra baka bir case blmndeki ilemlerinde yaplmas istenebilir. Bu ilem C/C++da aaya dme zellii ile salanabilmektedir. te bunu C#da salamak iin goto case deyimi eklenmitir. Goto case deyimi switch ierisinde kullanlabilir ve ak baka bir case blmne aktarlr. rnein: case 1: // goto case 2; case 2: // break; Burada case 1 blm altrldktan sonra case 2 blm altrlacaktr. goto case deyimi gibi goto default deyimi de vardr. FARKLI TRLERN BRBRLERNE ATANMASI C#ta x=y gibi bir atamada atanan ve atanlan trler farkl olabilir. Bilgi kayb oluturmayan atamalar geerli, bilgi kayb oluturabilecek atamalar geersizdir ve error oluturur. Baka bir deyile kk trlerden byk trlere dorudan atama geerli fakat byk trlerden kk trlere dorudan atama geersizdir. Byk tr kk trlere yaplan atamalara byk trn ierisindeki sayya baklmamaktadr. Yukardaki atama kural zet bir biimde belirtilmitir. Baz ayrntlar vardr: 1- Kk iaretli tamsay trnden byk iaretsiz tamsay trne dorudan atama yaplmaz. rnein: short trnden uint trne atama yaplmaz ya da int tr ulong trne atanamaz. nk byk iaretsiz tr negatif saylar tutamamaktadr. Tabi phesiz kk iaretsiz tamsay trnden byk iaretli tamsay trne atama yaplabilir. de

38

2-Tm tamsay trlerinden tm gerek tamsay trlerine dorudan atama yaplabilir fakat herhangi bir gerek say trnden herhangi bir tamsay trne atama yaplmaz. Anahtar Notlar: phesiz bir long say hatta bir int say float trne atadmz zaman bir kayp sz konusudur. Float tr, bu say ne kadar byk olursa bir mantis hatasyla basamak kayb yapmadan tutabilmektedir. Bu kayp C#ta mazur grlmtr. 3-Her ne kadar decimal tr 16 byte uzunluunda geni bir trse de bu tr 28 digitlik bir sayy yuvarlama hatasz tutmak iin dnlmtr. Float ve double ierisindeki saylar decimal tr ile ifade edilmeyebilir. Bu nedenle float ve double trnden decimal trne atama yasaklanmtr. Decimal trnden de float ve double trlerine atama yaplamaz. 4-C#ta bool trne herhangi bir trden atama yaplamaz. Bool bir deerde herhangi bir tre atanamaz. Yukarda aklanan kurallar aslnda aadaki gibi bir tablo ile ak bir ekilde belirtilebilir: sbyte byte short ushort int uint long ulong char float short, int, long, float, double, decimal short, ushort, int, uint, long, ulong, float, double, decimal int, long, float, double, decimal int, uint, long, ulong, float, double, decimal long, float, double, decimal long, ulong, float, double, decimal float, double, decimal float, double, decimal ushort, int, uint, long, ulong, float, double, decimal double

Anmsanaca gibi C#ta byte, sbyte, short, ushort trden sabit yoktur. Peki, bu trlere nasl deer atanacaktr? te bunu mmkn hale getirmek iin u ek kurallar oluturulmutur: 1- nt trnden bir sabit ifadesi hedef trn snrlar ierisinde kalmak kouluyla byte, sbyte, short, ushort trlerine dorudan atanabilir. rnein: sbyte s; s = 100 geerli s = 100 + 10; geerli s = 300; error Benzer biimde int trden bir sabit ifadesi, belirtilen say hedef trn snrlar iinde kalmak kouluyla uint ve long trlerine dorudan atanabilir. rnein: 39

uint a = 1 geerli uint a = -1 error 2- Long trden bir sabit ifadesi belirtilen say hedef trn snrlar ierisinde kalmak kouluyla ulong trne dorudan atanabilir. LEM NCES OTOMATK TR DNTRMELER Yalnzca deiken ve sabitlerin deil ifadelerinde toplam bir tr vardr. C# derleyicisi bir operatrle karlatnda nce operantlarn trlerini aratrr. Eer operantlar ayn trdense ilemi hemen yapar. lem sonrasnda elde edilen deer bu ortak trden kar. Eer operantlar farkl trlerden ise nce operantlar ayn tre dntrlr, sonra ilem yaplr. lem sonucunda elde edilen deer dntrlen bu ortak tr trnden olur. Dntrme kuralnn zeti kk trn byk tre dntrlmesi eklindedir. Kk trn byk tre dntrlmesi srasnda derleyici byk trnden geici bir deiken yaratr. Sonra kk deikeni bu deikene atar. lemde bu deikeni kullanr ve ilem sonunda bu geici deikeni yok eder. rnein: int a = 10, b; b = a + 10L; error rnein C#ta iki int deer blnrse sonu int trnden kar: double d; d = 10 / 3; Sonu: d = 3.0 Kk trn byk tre dntrlme kuralnn ayrntlar yledir: 1- Tamsay trleri ile gerek say trleri ileme sokulduunda dntrme her zaman gerek say trne doru yaplr. 2- Kk iaretli trden byk iaretsiz tre dntrme mmkn olmad iin bu iki tr bir arada ileme sokulamaz. rnein: short a = 10; ulong b = 20, c; c = a + b; error 3- Float ve double trnden decimal trne dntrme olmadna gre float ve double tr ile decimal tr birlikte ileme sokulamaz.

40

4- int trnden kk olan byte, sbyte, short, ushort, char trleri kendi aralarnda ileme sokulursa nce her iki operantta int trne dntrlr. Sonu int trnde kar. short s = 10 , b = 20 , c; c = a + b; error (int short trne dntrlmez) 5- bool tr hibir trle ileme sokulmaz. TR DNTRME OPERATR Tr dntrme operatr tek operantl nek bir operatrdr. Genel kullanm yledir: tr (operant) Tr dntrme operatr ncelik tablosunun ikinci srasnda sadan sola bulunur: () + - ++ -- : (tr) * / % + rnein: int a = 10 , b = 3; double d; d = (double) a / b; Yukarda nce a double trne dntrlr. Sonra blme ilemi yaplr. Bu durumda b zaten otomatik olarak double trne dntrlecektir. Sonu double trnden kar. Tr dntrme ilemi srasnda nce dntrlecek tr trnden geici bir deiken oluturulur sonra dntrlecek ifade bu geici deikene atanr. lemde bu geici deiken kullanlr sonra bu geici deiken yok edilir. Anahtar Notlar: C# standartlarna gre atama ilemi aslnda otomatik tr dntrmeye yol amaktadr. Atama ileminde nce sa taraf sol tarafn trne otomatik dntrlr sonra atama yaplr. Standartlarda atama ileminde yaplan bu otomatik dntrmelere implicit dntrme, tr dntrme operatr ile yaplan dntrmelere explicit dntrme denir. 41 soldan saa sadan sola soldan saa soldan saa

Grld gibi byk trden kk tre dorudan atamalar yanllkla yaplmasn diye yasaklanmtr. Yoksa programc istedikten sonra tr dntrme operatr ile dntrmeyi yapabilir. phesiz dntrme srasnda eer byk trn belirttii say kk trn snrlar ierisinde kalyorsa zaten bilgi kayb sz konusu olmaz. Fakat kalmyorsa bilgi kayb oluur. Bilgi kaybnn oluma biimi u maddelerde zetlenebilir: 1- Gerek say trlerinden tamsay trlerine yaplan dntrmelerde saynn noktadan sonraki ksm atlr tam ksm elde edilir. 2- Byk tamsay trnden kk tamsay trne yaplan dntrmelerde saynn yksek anlaml byte deeri atlr. Dk anlaml byte deeri alnr. Eer byk tamsay ierisindeki say kk tamsay trnn limitleri arasnda kalmyorsa dntrme ileminden sonra say gerei ile ilgisiz bir duruma debilir. 3- Ayn trn iaretli ve iaretsiz versiyonlar arasnda dntrme yapldnda saynn bit kalbnda deiiklik olmaz. Yalnzca iaret bitinin yorumu deiir. 4- Kk iaretli trden byk iaretsiz tre dntrmeler iki aamal yaplr. 1. aamada say byk trn iaretli biimine dntrlr. 2. aamada byk trn iaretli biiminden byk trn iaretsiz biimine dntrme uygulanr. LEML ATAMA OPERATRLER C#ta +=, -=, *=, %=biiminde bir grup ilemli atama operatr vardr. lemli atama operatrleri iki operantl araek operatrlerdir. a < op > = b le a = a < op > b ile tamamen edeerdir. lemli atama operatrleri ncelik tablosunun solunda atama operatr ile sadan sola ayn grupta bulunur: =, +=, -=, *=, %= sadan sola KOUL OPERATR Koul operatr C#n tek operantl operatrdr. Kullanm u ekildedir: < bool trden ifade1 > ? < ifade2 > : < ifade3 >

42

Koul operatr adeta if deyimi gibi alan bir operatrdr. Ancak koul operatr bir deer retmektedir. Koul operatrnn birinci operant bool trden olmak zorundadr. nce ? nin solundaki ifadenin deeri hesaplanr. Eer deer true ise ? ile : arasndaki ifade yaplr, false ise : nin sandaki ifade yaplr. Koul operatr duruma gre ? ile : arasndaki yada : nin sandaki ifadenin deerini retir. phesiz koul operatr ile yaplan her ey aslnda if deyimi ile de yaplabilir. Koul operatr if deyimi gibi kullanlmamaldr. Bir karlatrma sonrasnda elde edilen deerin ileme sokulaca durumlarda tercih edilmelidir. int val , result; System.Consol.Write(Say Giriniz: ); val = int.Parse(System.Console.ReadLine());
kalb

Klavyeden bilgi okuma

result = val > 10 ? 100 : 200; System.Console.Write(result) Koul operatrnn kullanlmasnn salk verildii tipik durumlar unlardr: 1- Karlatrma srasnda elde edilen deerin bir deikene atand durumlar. rnein: total = 0; for (int i = 1900 ; i < 2007 ; ++i) total += System.DateTime:IsLeapYear(i) ? 366 : 365; Burada 1900 ylndan 2007 ylna kadar toplam geen gn says hesaplanmtr. Ayn ekilde if ile de u ekilde yaplr: total = 0; for (int i = 1900 ; i < 2007 ; ++i) if (System.DateTime:IsLeapYear(i)) total += 366; else total += 365; 2- Koul operatr return ileminde de gzel bir biimde kullanlabilir. rnein: public static int GetMAx(int a, int b) { return a > b ? a : b; } 43

Burada a ile bden hangisi bykse o deer ile geri dnlmektedir. Ayn ilem yle de yaplabilir:

public static int GetMAx(int a, int b) { if (a > b) return a; else return b; } 3- Fonksiyon arma ileminde koul operatr kullanlabilir. rnein:

Func (a > b ? a : b); Burada fonksiyonun tek bir parametre deikeni vardr.lem aadaki ile edeerdir: if (a > b); Func(a); else Func(b); Parantezler kullanlarak baz operatrler koul operatrnn operant olmaktan karlabilir. rnein: int a = 100 , b; b = (a > 0 ? 100 : 200) + 300; Burada nce parantez ii yaplr. Koul doru da olsa yanl da olsa 300 ile toplama yaplr. ADRES KAVRAMI
(17.07.2007 Sal)

Bellek kaytlarda olumutur. Bellekteki her byte ilk byte 0 olmak zere ardk bir sayya karlk getirilmitir. Bu sayya ilgili bytein adresi denmektedir. Tanmladmz tm deikenler bir yer kaplamaktadr. Onlarn bir adresi vardr. rnein: byte = a; a 1011001 Burada ann adresi 1011001dir. Bir byte uzunluunda olan deikenlerin adresleri onlarn en dk adresleri ile ifade edilir. rnein: 44

int = x; 50500 50501 x 50502 50503 Burada x deikenin adresi 50500dr. SINIFLARIN VER ELEMANLARI Fonksiyonlarn dnda fakat snf bildirimleri deikenlere snfn veri elemanlar(field) denmektedir. ierisinde bildirilen

Snfn veri elemanlar da static olabilir ya da olmayabilir. Snfn veri elemanlarnda da eriim belirleyicisi anahtar szckler kullanlabilir. Bu anahtar szcklerden hibiri kullanlmasayd private kullanlm gibi varsaylmaktadr.(Daha nceden de belirtildii gibi static anahtar szc ya da eriim belirleyicisi yerel deikenlerde kullanlamaz) Her snf ayn zamanda bir tr belirtir. Snf trlerinde deiken tanmlayabiliriz. DEER TRLER VE REFERANS TRLER Trler kategori olarak 2ye ayrlmaktadr: 1- Deer Trleri(Value Types) 2- Referans Trleri(Reference Types) Bugne kadar grdmz int, long trleri kategori olarak deer trleridir. Deer trlerine ilikin bir deiken, deerin kendisini tutar. Oysa referans trlerine ilikin bir deiken, deerin kendisini tutmaz. Deerin kendisi bellekte baka bir yerdedir, deiken onun bellekteki adresinin tutar. Yani referans trlerine ilikin bir deiken adres tutmaktadr. Deerin kendisi referansn tuttuu adrestedir. Snf trleri kategori olarak referans trlerine ilikindir. Yani bir snf trnden deiken tanmlandnda bu deikenin ierisine bir adres yerletirilebilir. SINIF TRLERNDEN NESNELERN YARATILMASI Snf trlerinde deikenlere referansta denir. rnein Sample bir snf olsun: Sample s; Burada s nesnenin kendisi deildir. Nesnenin adresini tutacak bir adrestir. Nesnenin kendisi new operatr ile yaratlr. New operatrnn kullanm u ekildedir: new < snf ismi > ()

45

rnein: new Sample() new operatr ile tahsisat yapldnda derleyici snfn static olmayan veri elemanlar iin ardk bir biimde bellein heap denilen blmnde tahsisat yapmaktadr. Snflar bileik trlerdir. Yani paralardan olumaktadr. Bir snf nesnesinin paralar static olmayan veri elemanlardr. Snfn fonksiyonlar new ile tahsis edilen alanda yer kaplamaz. Snfn static veri elemanlar new ile tahsis edilen alanda yer kaplamaz. Yalnzca snfn static olmayan veri elemanlar yer kaplar. Bir bileik nesnenin adresi onun ilk bytenn adresi ile belirtilmektedir. new operatr heapte tahsisat yaptktan sonra yaratlan birleik nesnenin adresini verir. new operatr ile tahsis edilen nesnenin adresi ayn snf trnden referansa atanmaldr. Bylece referans artk tahsis edilmi snf nesnesini gsterir duruma gelmitir. Heap a Sample Snf b Nesnesi

Sample s; s = new Sample();

5000000 5000004 5000008

Yerel deikenler ister referans olsun isterse deer trlerine ilikin olsun stackte yer kaplar. Fakat new operatr ile tahsis edilen snf nesneleri heapte yer kaplamaktadr. rnein:

Sample s; s = new Sample(); stack s heap a b

Sample Nesnesi

NOKTA OPERATR Nokta operatr iki operantl araek bir operatrdr. Nokta operatrnn solundaki operant, bir snf alan ismi, bir snf ismi olabilecei gibi bir snf trnden referansta olabilir. Nokta operatrnn solunda snf referans varsa sanda o snfn static olmayan bir eleman olmak zorundadr.

46

r bir snf trnden referans a bu snfn static olmayan bir veri eleman olmak zere r.a ifadesi r referansnn gsterdii yerdeki nesnenin a parasn gsterir. Sample s; s = new Sample(); s.a = 10; s.b = 20; stack s Burada s.a ve s.b int trdendir. Genel rnek: class App { public static void Main() { Sample s; s = new Sample(); s.a = 10; s.b = 20; System.Console.WriteLine(s.a); System.Console.WriteLine(s.b); } } class Sample { public int a; public int b; public int static int c; public void Foo() { // } public static void Bar() { // } } Ayn trden iki snf referans birbirine atanabilmektedir. ki referans birbirine atandnda referansn iindeki adresler atanmaktadr. Bu durumda referanslar ayn nesneyi gsterir durumdadr. a b heap 10 20

47

Sample s; s = new Sample(); Sample k; k = s; stack s k heap 10 20

a b

G.rnek: public static void Main() { Sample s; s = new Sample(); s.a = 10; s.b = 20; Sample k = s; System.Console.WriteLine(k.a); System.Console.WriteLine(k.b); } Her new ilemi heapte yeni bir snf nesnesi yaratlmasna neden olmaktadr. P TOPLAYICI KAVRAMI CLR(Common Language Runtime) her nesnenin belli bir anda ka referans tarafndan gsterildiinin kaydn tutmaktadr. Buna nesnenin referans sayac denmektedir. rnein: {
1

3 4 5 6

Sample x = new Sample(); { Sample y; y = x; { Sample z; z = new Sample(); } }

48

Her new ayr bir nesnenin yaratlmasna neden olmaktadr. Burada ak 1 noktasna geldiinde heapte yaratlan 1.nesneyi tek bir referans gsteriyor. Yani bu nesnenin referans sayac 1dir. Ak 2 noktasna geldiinde 1.nesneyi 2 referans gsteriyor durumdadr. Ak 3 numaral noktaya geldiinde 1.nesneyi 2 referans, 2.nesneyi 1 referans gsteriyor durumdadr. Her nesnenin referans sayac ayndr. Ak 4 noktasna geldiinde 1.nesneyi 2 referans, 2.nesneyi 0 referans gsteriyor durumdadr.(Bloktan kld iin). Ak 5 noktasna geldiinde 1.nesneyi 1 referans, 2.nesneyi 0 referans gsteriyor durumdadr. Nihayet ak 6 noktasna geldiinde her iki nesneyi de 0 referans gsteriyor durumdadr. (Bloklardan kldka stacktaki nesneler yok olmaktadr). CLR heapteki yaratlan her nesnenin referans sayac srekli izlenmektedir. Nesnenin referans sayac 0a dtnde artk nesneyi hibir referans gstermiyor durumdadr. te CLR referans sayac 0a dm nesneleri heapten otomatik olarak silmektedir. CLRnin bu ii yapan ksmna kavramsal olarak p toplayc(Garbage Collector) denmektedir. Referans sayac 0a dm olan nesneler p toplayc iin seilebilir durumdadr. Fakat .Net standartlar nesne seilebilir duruma geldikten ne kadar sre sonra p toplaycnn bu nesneyi silecei konusunda bir belirlemede bulunmamtr. Yani nesne seilebilir duruma gelir gelmez silinmek zorunda deildir. Fakat silinmeye aday bir durumdadr. Belli bir sre sonra p toplayc tarafnda silinecektir. yi bir p toplaycdan nesne seilebilir duruma geldikten sonra nesneyi silmesi beklenir. Bazen eitli nedenlerden dolay nesnenin silinmesi gecikebilir. Nesne silinmeden program bile sonlanabilir. Grld gibi stacktaki deikenler programn ak deikenin yaratld bloktan kldnda otomatik olarak yok edilmektedir. Bu yok edilme ok hzl yaplr. Halbuki new operatr ile heapte tahsis edilen nesneler p toplayc tarafndan greceli olarak yava bir biimde silinmektedir. SINIFIN STATIC ELEMANLARI
19.07.2007 Perembe

Snfn static veri elemanlar nesne yaratldnda nesnenin ierisinde yer kaplamaz. Bunlarda toplamda tek bir kopya vardr. Snfn static veri elemanlarndan toplamda tek kopya bulunduu iin bunlara referanslarla deil snf isimleri ile eriilmektedir. rnein Sample bir snf ismi c de bunun static bir veri eleman olsun. Eriim Sapmle.c ifadesi ile yaplmaktadr. Snfn static veri elemanlar o snfn trnden nesne yaratlsa da kullanlabilir. rnein: G.. public static void Main() 49

{ Sample.c = 10; System.Console.WriteLine(Sample.c); } SINIFIN STATC OLMAYAN FONKSYONLARI Anmsanaca gibi snfn static fonksiyonlar eer baka bir isim alan ierisindeki snfa ait ise isim alan ismi ve snf ismi belirtilerek, eer ayn isim alanndaki snfa ait ise yalnz snf ismi belirtilerek, eer ayn snfa aitse yalnzca fonksiyon ismi yazlarak eriilir. Snfn static olmayan fonksiyonlar o snf trnden bir referans ile nokta operatr kullanlarak arlr. rnein: r bir snf trnden referans Func ise bu snfn static olmayan bir fonksiyonu olsun. arma r.Func(..) ifadesi ile yaplmaktadr. Snfn static olmayan veri elemanlar static olmayan fonksiyonlar ierisinde dorudan kullanlabilir. Fakat static fonksiyonlar ierisinde dorudan kullanlamazlar. rnein: class Sample { public int a; public static int b; public static void Foo() { a = 10; error } public void Bar() { a = 10; geerli } } Snfn static olmayan bir fonksiyonu arldnda bu fonksiyonun kulland static olmayan veri elemanlar fonksiyon hangi referansla arlmsa o referansn gsterdii yerdeki nesnenin veri elemanlardr. rnein: class Sample { public int a; public int b; public void Func(int x, int y) { a = x b = y 50

} public void Disp() { System.Console.WriteLine(a); System.Console.WriteLine(b); } } (Main snf olabilir) Sample s = new Sample(); s.Func(10,20); s.Disp(); Ekran kts 10,20 Sample k = new Sample(); k.Func(30,40); k.Disp(); Ekran kts 30,40 k = s; k.Disp(); Ekran kts 10,20

Static olmayan fonksiyonun bir referans ile arlmas bu fonksiyon ierisinde kullanlan static olmayan veri elemanlarnn hangi nesnenin veri elemanlar olduunun tespit edilmesi iin gerekmektedir. Static fonksiyonlar ierisinde snfn static olmayan veri elemanlar kullanlmadna gre static fonksiyonlar snf ismi ile arlmas uygun grlmtr. Snfn static olmayan bir fonksiyonu baka bir static olmayan fonksiyonu dorudan arabilir. (Ayn snf iinde). Bu durumda bu armann arlan fonksiyonda hangi referans kullanlmsa o referansla yapld varsaylr. Yani baka bir deyile arlan fonksiyonda aran fonksiyon ile ayn nesnenin veri elemanlarn kullanmaktadr. rnein: namespace CSD { class App { public static void Main() { Sample s = new Sample(); s.Func(10,20); } } class Sample { public int a; public int b; public void Func(int x, int y) { a = x; 51

s.Disp(); gibi } public void Disp() { System.Console.WriteLine(a); System.Console.WriteLine(b); } } } Snfn static olmayan bir fonksiyonu snfn static veri elemanlarn dorudan kullanabilir. Bu durumda static veri elemannn snf ismi ile kullanld varsaylr. Snfn static olmayan fonksiyonu snfn static bir bir fonksiyonunu da dorudan arabilir. Bu durumda armann da snf ismi ile yapld varsaylr. Fakat snfn static olan bir fonksiyonu static olmayan veri elemanlarn dorudan kullanamaz ve static olmayan fonksiyonlarn dorudan aramaz. Yukarda anlatlanlarn zeti yledir: 1- Snfn static olmayan fonksiyonlar, snfn hem static olmayan veri elemanlarn hem de static veri elemanlarn dorudan kullanabilir. 2- Snfn static fonksiyonlar, snfn static olmayan veri elemanlarn dorudan kullanamazlar.Fakat static veri elemanlarn dorudan kullanabilirler. 3- Snfn static olmayan bir fonksiyonu, static olmayan baka bir fonksiyonu ve static olan bir fonksiyonu dorudan arabilir. 4- Snfn static fonksiyonlar, snfn static olmayan fonksiyonlarn dorudan aramaz. Fakat static fonksiyonlarn dorudan arabilir. Yukardaki 4 madde de yle zetlenebilir: 1- Snfn static olmayan fonksiyonlar, snfn static olmayan elemanlarn ve static olan elemanlarn dorudan arabilir. 2- Snfn static kullanabilir. fonksiyonlar, yalnzca snfn static elemanlarn

a = y; Disp();

RASGELE SAYI RETM .Nette rasgele say retmek iin snf kullanlr. Random snfnn static fonksiyonu her arldnda 0 ile n-1 say belirliyoruz. rnein 1 ile 100 yledir: System isim alan ierisindeki Random olmayan int parametreli Next isimli arasnda dzgn dalm rasgele bir arasnda rasgele 10 saynn retimi

52

namespace CSD { class App { public static void Main() { System.Random r = new System.Random(); for(int i = 0; i < 10; ++i) System.Console.WriteLine(r.Next(100)); } } } Snf almas: Bir grupta Ali, Veli, Selami, Aye ve Fatma isminde be kii vardr. Rasgele bir kiinin ismini ekrana yazdran program yaznz. zm: namespace CSD { class App { public static void Main() { System.Random r = new System.Random(); switch(r.Next(5)) { Case 0: System.Console.WriteLine(Ali); Break; Case 1: System.Console.WriteLine(Veli); Break; Case 2: System.Console.WriteLine(Selami); Break; Case 3: System.Console.WriteLine(Aye); Break; Case 4: System.Console.WriteLine(Fatma); Break; } } } } 53

Snf almas: 0 ile 1 arasnda ok sayda rastsal say retiniz. 0 yaz, 1 tura anlamna gelsin. Deney says ok arttrldnda yaz ve tura gelme olaslnn 0,5 yaknsadn gsteriniz. zm: namespace CSD { class App { public static void Main() { System.Random r = new System.Random(); int head = 0, tail = 0; for(int i = 0; i < 1000000; ++i) { if (r.Next(2) == 0) ++tail; else ++head; } System.Console.WriteLine((double)head / 1000000); System.Console.WriteLine((double)tail / 1000000); } } } System.String SINIFI System isim alanndaki String snf yazlarla ilgili faydal ilemler yapmak iin kullanlmaktadr. System.String snf ok fazla kullanld iin bu snf string (kk harfle) anahtar szc ile de temsil edilmitir. Yani System.String demekle string demek tamamen ayn anlamdadr. String snfnn amac yaz tutmaktr. Yaz heapte tahsis edilmi olan nesnenin ierisinde bulunmaktadr. String nesnesi klasik olarak new operatr ile yaratlmaz. C#ta ne zaman ift trnak ierisinde bir yaz yazlsa derleyici bu yazy grdnde heapte kendisi bir string nesnesi tahsis eder ve ift trnak ierisindeki yazy bu nesnenin ierisine yerletirir. ift trnak ifadesi yerine heapte tahsis ettii nesnenin balang adresi yani referans yerletirilir. Yani C#ta ift trnak ifadeleri bir string nesnesi tahsis et, ierisine bu yazy yerletir ve nesnenin referansn elde et anlamna gelmektedir. Heapte yaratlan bu string nesnesi yine p toplayc sistem tarafndan nesne seilebilir duruma geldiinde geldiin de otomatik olarak silinecektir. 54

System isim alanndaki Console snfnn Write ve WriteLine fonksiyonlarna bir string referans verilirse bu fonksiyonlar string nesnesi ierisindeki yazy yazarlar. rnein: public static void Main() { string s; s = Ankara; System.Console.WriteLine(s); }
24.07.2007 Sal

ki string referans + operatr ile toplama ilemine sokulabilir. Bu durumda yeni bir string nesnesi yaratlr. Yeni string nesnesinin ierisindeki yaz, iki referansta belirtilen nesnelerin ierisindeki yaznn birleiminden oluturulur. rnein: string a = Ankara; string b = zmir; string c = a + b; System.Console.WriteLine(c) rnein: public static void Main() { string a, b, c, d; a = Ankara; b = zmir; c = Adana; d = a + b + c; System.Console.WriteLine(d) } Ekran kts Ankarazmir

Ekran kts AnkarazmirAdana

Burada nce a + b ilemi yaplacak, bu ilem sonunda yeni bir string nesnesi yaratlacak, sonra yaratlan nesne c string nesnesi ile toplanacaktr. Bu ilem de yeni bir nesnenin yaratlmasna yol aacaktr. a + b ilemi sonucunda yaratlm olan string nesnesi ilemden sonra hemen p toplayc tarafndan seilebilir bir duruma gelecektir. Anahtar Notlar: .Net dnyasnda assembly terimi .exe ve .dll uzantl dosyalar iin kullanlmaktadr. Buradaki assembly teriminin sembolik makine dili anlamna gelen assembly terimi ile bir ilgisi yoktur. C# standartlarna gre ayn assembly ierisindeki tamamen zde karakterlerden olumu stringler iin yeniden yerler tahsis edilmez. Bunlar iin 55

toplamda tek bir nesne tahsis edilir. Bu zde stringlerin hepsi ayn nesneye ilikin referans belirtir. rnein: a = Ankara; b = Ankara; stack a b Bo string kullanmak geerlidir. Bu durumda derleyici yine bir string nesnesi yaratr. Fakat stringin tuttuu bir yaz yoktur. rnein: string a = ; geerli heap Ankara

ki string referans == ve != operatrleri ile karlatrlabilir. Bu durumda referanslarn ayn nesneyi gsterip gstermedii deil referansn gsterdikleri nesnenin iindeki yazlarn ayn olup olmad sorgulanmaktadr. Bir string nesnesinin tuttuu yaznn herhangi bir karakterine [] operatr ile eriebiliriz. S string trnden bir referans olmak zere s[ifade] ifadesi bu referansn gsterdii yerdeki string nesnesinin ilgili indeksteki karakterini belirtir. fade char trdendir. C#ta bir string nesnesi yaratldktan sonra bir daha nesnen tuttuu yaznn herhangi bir karakteri deitirilemez. rnein: string a = Ankara; a[2] = x; error String snfnn Length isimli int trden read only, property eleman, stringin tuttuu yaznn karakter uzunluunu vermektedir. System isim alanndaki Console snfnn ReadLine isimli static fonksiyonu, klavyeden bir yaz girilip enter tuuna baslana kadar bekler. Girilen yazy yaratt bir string nesnesinin ierisine yerletirir. O string nesnesinin referans ile geri dner. Fonksiyonun parametrik yaps yledir(Kaynak MSDN): public static string Readline() rnein: public static void Main() { string s; System.Console.Write(Bir yaz giriniz: ); s = System.Console.ReadLine(); System.Console.WriteLine(s); } 56

String snfnn static olmayan ToLower fonksiyonu, yazy kk harfe dntrmek iin kullanlr. Fonksiyon yeni bir string nesnesi oluturur. Bu string nesnesi ierisine yaznn kk harfe dntrlm biimini yerletirir. rnein: string a = ANKARA; string b; b = a.ToLower(); System.Console.WriteLine(b); Snfn byk harfe dntrme yapan ToUpper fonksiyonu da vardr.(Dntrme ilemi default olarak Windows iletim sistemindeki blgesel ayarlarda belirtilen lkenin diline gre yaplmaktadr) String snfnn Substring isimli static olmayan fonksiyonu nesnenin belirttii yaznn belli bir indeksinden belli bir uzunluk kadarn alp bundan yeni bir string nesnesi yaratarak bu yeni nesnenin referansn geri dnmektedir. Parametrik yaps yledir: public string Substring (int StartIndex , int Length) rnein: public static void Main() { string a = ARI DAI OK YKSEK; string b; b = a.Substring(10 , 3) (kanc karakterden , ka tane System.Console.WriteLine(b); kt : OK } String snfnn static olmayan Insert isimli fonksiyonu nesnenin belirttii yaznn belli bir indeksine yeni bir yaz ekler. Tabi string nesnesinin karakterleri zerinde deiiklik yaplamayacana gre fonksiyon yeni bir string nesnesi yaratp onunla geri dnmektedir. Fonksiyonun parametrik yaps yledir: public string Insert (int StartIndex , string value) rnein: public static void Main() { string a = Bugn hava scak; string b; b = a.Insert(10 ,ok);
(kanc karakterden , ka tane karakter)
karakter)

57

System.Console.WriteLine(b); }

kt : Bugn hava ok scak

Eer indeks deeri yaz uzunluundan bykse exception oluur. String snfnn Trim isimli fonksiyonu yaznn bandaki ve sonundaki boluk karakterlerinin atlmasnda kullanlr. Daha nce de belirtildii gibi switch parantezi ierisinde ve case ifadelerinde string kullanlabilir. String snfnn static olmayan Remove isimli fonksiyonu, nesnenin belirttii yaznn belirli bir indeksinden itibaren belirli bir miktar karakteri silerek, bu karakterler silinmi yeni bir string nesnesinin referans ile geri dner. Parametrik yaps yledir: public string Remove (int StartIndex , int Count) rnein: string s= EskiehirHisar; string 0 result; result = s.Remove(4 , 5); System.Console.WriteLine(result) kt : EskiHisar

Stringler tek satr zerinde yazlmak zorundadr. rnein: string s; s = Bugn hava ok scak; geersiz

Eer yaz ok uzunsa + operatr kullanlarak byle bir blme yaplabilir. rnein: string s; s = Bugn hava + ok scak; geerli

ift trnak ierisinde ters bl karakterleri kullanlabilir. Bunlar tekbir karakter belirtmektedir. rnein: string = Ali\tVeli;
\t karakteri ierisinde tab anlamnda

Eer bir stringin banda bitiik bir biimde @ karakteri varsa byle stringlere dayankl (verbatim) stringler denir. rnein: @Ankara; Dayankl string 58

Dayankl stringler birden fazla satra blnebilir. Dayankl stringler ierisindeki ters bl karakterleri zel anlam ifade etmez. Normal ters bl karakteri olarak ele alnr. rnein: string path = c:\\windows\\temp; ifadesi ile string path : @c:\windows\temp; ifadesi ayn anlamdadr. String snfnn static Compare isimli fonksiyonu iki yazy karlatrmada kullanlmaktadr. Parametrik yaps yledir: public static int Compare (string StrA , string StrB) Fonksiyon 1. yaz 2. yazdan bykse pozitif herhangi bir deere, 2. yaz 1. yazdan bykse negatif bir deere, yazlar eitse sfra geri dner. rnein: string a , b; System.Console.Write(ki yaz giriniz: ); a = System.Console.ReadLine(); b = System.Console.ReadLine(); int result; result = string.Compare(a , b); if(result > 0) System.Console.Write(a > b); else if(result < 0) System.Console.Write(a < b); else System.Console.Write(a = b);

SM ALANLARI
26.07.2007 Perembe

sim alan bildirimi yle yaplr: namespace < isim alan ismi > { // } sim alanlar i ie yada ayrk bir biimde bildirilebilir. rnein: namespace A { namespace B { 59

// } } namespace C { // } Hibir isim alan ierisinde olmayan blgeye global isim alan denmektedir. Bir snf, herhangi bir isim alan ierisinde yada global isim alannda tanmlanabilir. ie isim alanlar araya nokta konularak tek hamlede bildirilebilir. rnein: namespace A.B { // } ile namespace A.B { namespace A.B { // } }

Yukardaki iki ifade tamamen ayn ifadelerdir. sim alanlar paral bir biimde bildirilebilir. Baka bir deyile bir isim alannn ikinci kez bildirilmesi ncekine ekleme yapld anlamna gelmektedir. rnein: namespace A { class x { // } } namespace A { class y { // } }

Yukarda A isim alan ierisinde hem x hem de y vardr. Farkl isim alanlarnn ierisinde ayn isimli trler bulunabilir.Fakat ayn isim alan ierisinde ayn isimli birden fazla tr bulunamaz. .Netin tm snflar System isim alan ierisinde yada System isim alan ierisindeki isim alanlarnn ierisinde bulunmaktadr. Programcnn bu isim alanna baka bir eleman yerletirmesi tavsiye edilmez. DNAMK KTPHANELERN KULLANIMI Uzants .dll biiminde olan dosyalara dinamik ktphane dosyalar denmektedir. .Net ortamnda bamsz olarak yklenebilen .exe ve .dll uzantl dosyalara assembly denmektedir. Teknik anlamda .exe ve .dll dosyalara arasnda bir format farkll yoktur. 60

Anahtar Notlar: .exe ve .dll dosyalar doal kod yad arakod ierebilir. Baka bir deyile bu dosyalarn yalnzca ismine bakarak bunlarn .Net ortam iin yazlp yazlmadn anlayamayz. Eer bir .exe yada .dll .Net ortamnda kullanlan bir assembly dosyas ise PE format bakmndan ek baz sectionlara sahiptir. rnein; Bir .Net .exe yada .dll dosyasnda assembly manifest ve meta data sectionlar vardr. Bir exe dosyas altrlmak istediinde iletim sistemi PE formatn inceleyerek bunun bir .Net program olup olmadna bakar. Eer bunun bir .Net ortamnda oluturulmu exe ise arakod iermektedir ve CLR tarafndan altrlr. Deilse doal yolla altrlr. dll dosyalar ktphane amal kullanlmaktadr. Yani bunlarn ierisinde snflar vardr. Programc bu snflar kendi yazm gibi kullanabilir. rnein; br x firmas bir grup yaral snf yazm olsun bizde bu snflar kullanmak istiyoruz. Firma bu snflar bir .dll ierisine yerletirir ve bize dll olarak verir. phesiz dll ierisindeki bu snflar derlenmi bir biimde bulunmaktadr. .Netin kendi snflar da fiziksel olarak dll dosyalar ierisindedir. phesiz bir dllnin ierisinde tek bir isim alanna ilikin snflar bulunmak zorunda deildir. Bir dllnin ierisinde ok farkl isim alanlar bulunabilir. Yani isim alan kavram ile dll kavram arasnda bir balant yoktur. DLL DOSYALARININ OLUTURULMASI Csc komut satr derleyicisinde dll oluturmak iin /target:library seenei kullanlmaldr. (/target yerine /t de kullanlabilir.) rnein: csc /target:library test.cs Aslnda /target seeneinde 4 belirleme yaplabilmektedir: 1- /target:exe Anahtar Notlar: Bir exe dosya y bir konsol yada bir GUI uygulamasdr. Konsol uygulamas, iletim sistemi program altrrken eer komut satrnda deilsek konsol ekran denilen siyah ekran aar. Fakat GUI uygulamalarnda bu tr siyah ekran bulunmamaktadr. /target:exe seenei default durumdadr. Yani /target seenei hi belirtilmezse konsol exesi yaratlr. 2- /target:winexe Bu seenek GUI exe dosyas oluturmaktadr. Yani byle bir exe altrldnda konsol ekran gzkmez. 3- /target:library dll doyas oluturmak iin kullanlr. 61 Bu seenek bir konsol exe oluturmaktadr.

4- /target:module

Modl dosyas oluturmak iin kullanlr.

IDE kullanarak dll yapmak iin bo bir proje yaratlr. Sonra proje properties mensne gelinir. Output Types blmnden Class Library olarak seilir. Bu durumda exe yerine dll oluturulur. DLL DOSYALARININ KULLANILMASI Bir dll dosyasn kullanmak iin onu referans etmek gerekir. Referans etme ilemi komut satrnda /reference:dll dosya ismi seenei ile yaplabilir. /reference yerine /r de kullanlabilir. rnein: csc /r:test.dll Sample.cs Burada Sample.cs derlenerek Sample.exe yaplmak istenmitir. Program ierisinde test.dll de bulunan bir takm snflar kullanld iin test.dllye de referans edilmitir. phesiz birden fazla dll ye referans edilebilir. rnein: csc /r:a.dll /r:b.dll /t:winexe Sample.cs Burada programc Sample.cs ierisinde hem a.dll hem de b.dll ierisindeki snflar kullanmtr. Bu nedenle bu dll dosyalarn referans etmitir. Buradan rn olarak bir GUI exe elde edilecektir. Derleme ilemi srasnda referans edilen dlllerin ayrca programn alma zamannda da exe dosyas ile ayn klasrde bulundurulmas gerekir. Bir exe dosya altrlrken o exe dosyann referans ettii dlller de alma srasnda btnsel bir biimde yklenmektedir. Yani bizim yazdmz program baka bir makineye kuracaksak exe ile birlikte o exenin referans ettii dllleri de o makineya gtrmemiz gerekir. IDE den bir dllye referans edebilmek iin Solution Explorerde References zerine gelinir. Farenin sa tuuna baslr ve Add Reference seilir. Add Reference dialog penceresinde Browse tabna geilir ve dllnin yeri bulunarak ekleme yaplr. BU biimde referans etme ilemi yapldnda IDE referans edilen dllyi zaten exeyi oluturaca klasre kopyalamaktadr. Snf almas: IDE kullanlarak bir dll dosyas oluturunuz. dllye bir tane snf ve bir static fonksiyon yerletiriniz. Sonra bir exe projesi oluturarak bu dllyi referans edip sz konusu snf ve fonksiyonu kullannz. zm: dll projesi namespace CSD { public class Sample { public static void Func() { System.Console.WriteLine(Ben dll dosyasym); } 62

} } exe projesi namespace CSD { class App { public static void Main() { Sample.Func(); referans } } }

yaplyor.

Bir snf bildiriminin nne public yada internal belirleyicilerinde bir getirilebilir. Eer hibir belirleyici kullanlmamsa internal belirleyicisi kullanlm gibi varsaylr. Public belirleyicisi snfn baka bir assemblyden (rnein bir exeden) kullanlabileceini belirtmektedir. Halbuki internal snflar yalnzca assembly iinde kullanlabilir. zetle bir dll ierisindeki snfn darda kullanlabilmesi iin snfn public belirleyicisi ile belirtilmesi gerekir. .NETN SINIFLARINA LKN DLL DOSYALARI .Netin kendi snflar da eitli dll dosyalar ierisine yerletirilmitir. Yani programcnn bu snflar kullanabilmesi iin o snflar hangi dlller ierisinde ise o dllye referans etmesi gerekir. .Netin bu dllleri frameworkun bir paras kabul edilir ve framework kurulumu yaplrken kurulum srasnda hedef makineye ekilmektedir. Bu dlller Global Assembly Cache ierisindedir. Bu nedenle exe ile ayn klasrde olmak zorunda deildir. Csc derleyicisi hi belirtilmese bile mscorlip.dll isimli dllye zaten otomatik referans etmektedir. .Netin eitli isim alanlarndaki en ok kullanlan snflar mscorlip.dll ierisindedir. Bu durumda bir .Net snf eer mscorlip.dll ierisinde ise onu kullanmak iin bir referans ilemine gerek yoktur. Fakat mscorlip.dll ierisinde olmayan snflarn hangi dll ierisinde bulunduu belirlenmeli ve o dllye referans edilmelidir. Bir .Net snf kullanlacaksa 2 eyin bilinmesi gerekir: 1- Snf hangi dll dosyas ierisindedir? 2- Snf hangi isim alan ierisindedir? SM ARAMA LEM Bir deikenin kullanldn gren derleyici o deikene ilikin bildirimi belirlemeye alr. Bu belirleme srasnda deikenin bildirimini eitli faaliyet alanlarnda arar. Eer deiken bildirimi ile karlarsa arama ilemini 63

durdurur, eer deikenin bildirimi ile hi karlamazsa ilem error ile sonlanr. Bu ileme isim aramas(name look up) denmektedir. sim aramas her trl isme uygulanmaktadr. rnein yerel deiken isimleri, snf isimleri, isim alan isimleri bu arama ilemine sokulmaktadr. sim arama ilemi 2 ye ayrlr: 1- Niteliksiz sim Arama: . operatr kullanlmadan dorudan yazlm isimlerin aranmasna denilmektedir. 2- Nitelikli sim Arama: . operatrnn sanda isimlerin aranmasna denilmektedir. rnein; X.Y ileminde X niteliksiz olarak Yde nitelikli olarak aranmaktadr. Niteliksiz sim Aramas: Nokta operatr kullanlmadan dorudan yazlan isimler iin niteliksiz arama kurallar uygulanr. Niteliksiz arama ilemi u admlarla gerekletirilir: 123Derleyici ismin kullanld yerden yukarya doru alan ierisinde fonksiyonun yerel bloklarnda ismin bildirimini arar. sim snf bildiriminin her yerinde aranr. sim kullanld snfn iinde, bulunduu isim alannn her yerinde aranr.

Anahtar Notlar Sample s; gibi bir bildirim ileminde s isimi bildirilmektedir. Bu nedenle bu isim aranmaz. Fakat Sample ismi niteliksiz arama ilemine sokulacaktr. 4sim kullanld snfn iinde, bulunduu isim alanlarnda iten da doru bu isim alanlarnn her yerinde aranr. rnein; farkl isim alanlarnda ayn isimli snflar bulunabilir. Eer kapsayan ve kapsanan isim alanlarnda ayn isimli snflar varsa arama iten da doru yapldndan iteki isim alanndaki snf bulunur. sim nihayet global isim alann her yerinde aranr.

5-

Nitelikli sim Aramas: Nokta operatrnn sandaki isimlerin aranmasnda nitelikli isim arama kurallar uygulanr. Nokta operatrnn sol tarafndaki operand bir isim alan ismi, tr ismi ya da bir snf trnden deiken olabilir. 1- Nokta operatrnn solundaki isim bir isim alan ismi ise sandaki isim yalnzca o isim alannn her yerinde aranr. Kapsayan isim alanlarnda aranmaz. 2- Nokta operatrnn solunda bir snf ya da yap ismi varsa sandaki isim o snf ya da yap bildiriminin her yerinde aranr. Fakat Kapsayan isim alanlarnda aranmaz.

64

3- Nokta operatrnn solunda bir snf trnden referans ya da bir yap deikeni varsa sandaki isim o referansn ya da deikenin ilikin olduu snf ya da yap bildiriminin her yerinde aranr. Kapsayan isim alanlarna baklmaz. A.B.C gibi birden fazla . operatr ile bir isim belirtilmi olsun. Bu durumda A niteliksiz olarak aranr, B ve C nitelikli olarak aranr. (Yani kabaca nce Ann bulunmas gerekir. B A ierisinde Cde A.B ierisinde aranr) sim arams karlalan her isim iin yaplmaktadr. rnein: Sample s = new Sample(); Burada s bildirilmitir aranmayacaktr. Fakat iki Sample ismi niteliksiz olarak aranacaktr. namespace A { namespace B { class App { public static void Main() { Sample s = new Sample(); s.Func(); } } } } namespace A { namespace B { class Sample { public void Func() { // } } } } Referans edilen dlller ierisindeki bildirilmi isimler sanki programc kendisi yazm gibi arama ilemine sokulmaktadr. rnein; System.Console.WriteLine gibi bir isim alan kullanlm olsun. Burada System niteliksiz olarak aranacaktr. Fakat bu arama ilemi yalnzca kaynak kod la deil referans edilmi olan dlllerle de yaplacaktr. System isim alan en azndan mscorlib.dll ierisinde bulunacaktr. 65

Framework 1.1aadaki gibi bir durumda yaplacak bir ey yoktu: namespace CSD { namespace System { class App { public static void Main() { System.Console.WriteLine(Test); } } } }

error

Buradaki System isim alan .Netin global isim alan altndaki System isim alan deildir. Anahtar Notlar Anmsanaca gibi bir isim alannn iki kez bildirimi yapldnda bu durum ekleme anlamna gelmektedir. Farkl isim alanlarnn altnda bulunan ayn isimli isim alanlar gerekte farkl isim alanlardr.rnein: namespace A { namespace x { // } } namespace B { namespace x { // } } Burada x isim alanlar birletirilmez. nk ayn isim alan deildir. rneimizde System isim alan niteliksiz olarak arandn da CSDnin altndaki isim alan olarak bulunacaktr. Bundan sonra artk Console ismi CSDnin System isim alannda bulunacandan bulunamayacaktr. Framework 2.0da bu sorun yeni eklenen global:: operatr ile zlmtr. global:: operatrnn sandaki isimler yalnzca global isim alannda aranmaktadr. O halde sorun yle zlebilir:

66

namespace CSD { namespace System { class App { public static void Main() { global::System.Console.WriteLine(Test); } } } }

using DREKTF using direktifi nokta operatr ile nitelendirme ilemini kolaylatrmak iin dnlmtr. using direktifinin genel biimi yledir: using < isim alan ismi > rnein: using A; using X.Y; using direktifi isim alanlarnn bana yerletirilmek zorundadr. Baka bir deyile using direktiflerinden nce baka bildirimler bulunamaz. rnein: namespace CSD { using A; using B; class x; { // } using C; } Using direktifi global isim alanna da yerletirilebilir. Global isim alannn ba kaynak dosyann tepesidir. Using direktifinde bir direktifin yerletirildii isim alan, bir de direktifte belirtilen isim alan vardr. rnein

doru kullanm doru kullanm

yanl kullanm

namespace CSD { 67

using System; // } Burada direktifin yerletirildii isim alan CSD, direktifte belirtilen isim alan System isim alandr. Direktifte belirtilen isim alan nokta operatryle kombine edilmi olabilir. Bu durumda direktifte belirtilen isim alannn bulunmas iin yine daha nce grlen isim arama kurallar uygulanr. rnein: namespace CSD { using A.B.C; // } Burada belirtilen isim alan A.B ierisindeki C isim alandr. Niteliksiz isim arama srasnda isim using direktifinin yerletirildii isim alannda bulunamasayd, isim using direktifi ile belirtilen isim alanlarnda da aranr. rnein; Console ismi niteliksiz aranrken CSD isim alannda bulunamayacaktr. Bu durumda direktifte belirtilen System isim alanna da baklacaktr ve orada bulunacaktr. rnein. namespace CSD { using System; // Console.WriteLine(Test); } sim using direktifinde belirtilen isim alannda arandktan sonra baka bir isim alanna baklmaz. Yani kapsayan isim alanlarna baklmaz. rnein: namespace CSD { using B; // X a; } namespace A { class X { // } namespace B; { 68 X bulunamaz

// } } X ismi A.Bde aranmayacaktr. aranacaktr. Fakat kapsayan isim alan olan Ada

Using direktifi geili deildir. Yani isim using direktifi ile belirtilen isim alannda bulunamadnda o isim alanna yerletirilmi using direktifleri dikkate alnmaz. rnein: namespace CSD { using B; X a; X bulunamayacaktr. } namespace A { class X { // } } namespace B { using A; // } Using direktifi, isim direktifinin yerletirildii isim alannda bulunamazsa etkili olmaktadr. sim bulunursa using direktifi de dikkate alnmaz. rnein: namespace CSD { using A; // X a; X CSD isim alannda bulunmutur. class X; { // } } namespace A { class X { // } }

69

sim using direktiflerinin yerletirildii isim alannda bulunamam olsun. Fakat ismin birden fazla using direktifinde belirtilen isim alannda belirtilen isim alannda bulunduunu varsayalm. Bu durum error oluturur. rnein: namespace CSD { using A; using B; X a; error hem A hem de Bde bulunuyor } Yukarda biz hem A firmasnn hem de B firmasnn yazm olduu snflar kullanmak istiyoruz. A firmas snflarn A isim alannda, B firmas da B isim alannda bildirmi olsun. Burada gereksiz niteliklendirmeyi engellemek iin hem A hem de B isim alanlarna using direktifi uygulanmtr. Fakat grld gibi tesadfen X ismi her iki isim alannda da bulunmaktadr. te bu tr durumlarda artk X isminin A.X ya da B.X biiminde nitelikli olarak kullanlmas gerekir. Grld gibi isim alanlar ierisindeki isimler akmadktan sonra using direktifi kolaylk salamaktadr. Fakat akma sz konusu ise nitelendirme yaplmak zorundadr. Using direktifi nitelikli aramalarda etkili olmaz. rnein: namespace CSD { // A.X c; // } namespace A { using B; // } namespace B { class X { // } } Bir isim using direktifinin yerletirildii isim alannda bulunamam olsun. Eer isim using direktifi ile belirtilen isim alannda bir isim alan ismi olarak bulunursa bu bulma ilemi dikkate alnmamaktadr. Baka bir deyile isim 70 namespace A; { class X { // } } namespace B; { class X { // } }

X nitelikli arand iin A ierisindeki using direktifi dikkate alnmaz.

using direktifinde belirtilen isim alannda aranrken o isim alanndaki isim alan isimleri dikkate alnmamaktadr. rnein: namespace CSD { using A; // B.X k; // } namespace A { namespace B; { class X { // } } } Burada sorunu zmek iin A.B isim alanna using direktifi uygunmaldr: namespace CSD { using A.B; // X k; geerli // } namespace A { namespace B; { class X { // } } } Burada artk X ismi A.B ierisinde bir snf ismi olduu iin bulunacaktr. Bu kuraldan dolay C# programlarnda aadaki gibi bir using merdiveni ile karlalr: using System; using System.Windows; using System.Windows.Forms;

error B ismi Ann ierisinde bir isim alan ismi olduu iin bulunamayacak

71

Bundan sonra mmkn olduunca using direktifi kullanlarak rneklerde daha az nitelendirme yaplacaktr. DZLER [Arrays] Birden fazla deikenin (datann) oluturduu toplulua veri yaps denilmektedir. rnein; tek bana int trden a veri yaps deildir. Oysa bir snf bir veri yapsdr. nk snf denildiinde bir grup eleman anlalmaktadr. Elemanlar ayn trden olan ve bir index yardmyla eriilebilen veri yaplarna dizi(array) denilmektedir. C# ta T tr iin T[] ile temsil edilen bir dizi tr vardr. rnein: int a; int [] b; Burada a int trdendir, b ise int trden bir dizidir. bnin tr int[] ile belirtilir. C# ta diziler kategori olarak referans trlerine ilikindir. rnein: int [] a; Burada a yalnzca bir referanstr. Dizi nesnesi henz tahsis edilmemitir. C# ta diziler bir eit snftr. Dizi elemanlar da bu snf nesnesinin ierisinde kabul edilmektedir. Dizi nesneleri tpk snf nesnelerinde olduu gibi new operatr ile heap ta tahsis edilir. New operatr ile dizi tahsis etmenin genel biimi yledir: new < tr > < [uzunluk] > rnein: int [] a; a = new int [10]; Bu ilemin sonucunda heap ta bir dizi nesnesi yaratlmtr. Bu dizi nesnesi 10 tane int tutmaktadr. Dizile new operatr ile yaratlrken [] ierisine uzunluk ifadesinin tamsay trlerine ilikin olmas zorunludur. Bu uzunluk ifadesi sabit ifadesi olmak zorunda deildir. rnein: // int [] a; int size; size = int.Parse(Console.ReadLine()); a = new int [size * 2]; // 72

Ayn trden iki dizi referans birbirine atanabilir. Bu durumda tpk snflarda olduu gibi iki referansta ayn nesneyi gsterir durumdadr. rnein: int [] a = new int [10]; int [] b; b b = a; r, T trnden bir dizi referans olmak zere r[ifade] ifadesi referansnn gsterdii yerdeki dizi nesnesinin ifade ile belirtilen indexteki elemann temsil eder. Dizinin ilk eleman 0. indexteki elemandr. Bu durumda n elemanl bir dizinin son eleman n-1. indexteki elemandr. Dizinin her eleman bamsz bir deiken gibi kullanlabilir. Dizinin en nemli kullanm nedeni bir dng ierisinde bir indis yardmyla dizinin tm elemanlarnn gzden geirilebilmesidir. rnein: int [] a = new int [10]; // for (int i = 0; i < 10; ++i) a[i] = i; r T[] trnden bir dizi referans olsun. Bu durumda r[ifade] trndendir. using System; namespace CSD { class App { public static void Main() { int [] a = new int[100]; for (int i = 0; i < 100; ++i) a[i] = i; int [] b = a; for (int i = 0; i < 100; ++i) Console.WriteLine(b[i]); } } } ki dizi referansnn birbirine atanabilmesi iin trlerinin tamamen ayn olmas gerekmektedir. rnein; int trnn long trne dorudan atabilmesi, 73 T a

int trden bir dizi referansnn long trnden bir dizi referansna atanaca anlamna gelmez. Dizi elemanlarna eriirken [] ierisindeki ifade tamsay trlerine ilikin olmak zorundadr. Bir dizinin pozitif ya da negatif bakmdan olmayan bir elemanna erimeye almak exception olumasna neden olmaktadr. Anahtar Notlar Exception, program hatasz olarak derlendikten sonra alma zaman srasnda oluan bir hatadr. Yani exception derleme zamanna deil alma zamanna ait bir deyimdir. Her dizinin Lenght isimli int trden bir property eleman vardr. Bu property eleman dizinin uzunluunu belirtmektedir. Yani biz r bir dizi referans olmak zere r.Lenght ifadesi ile bu dizinin uzunluunu bulabiliriz. Lenght property eleman read only bir elemandr. Yani bu eleman kullanabiliriz. Fakat bir deer atamamayz. i < 100 ifadesi ile i < a.Lenght ayn trdendir.

DZLERN FONKSYONLARA PARAMETRE OLARAK AKTARILMASI Bir diziyi fonksiyona geirmek olduka kolaydr. Fonksiyonun parametre deikeni dizi trnden referans olur. Fonksiyon da ayn trden bir dizi referans ile arlr. rnein: using System; namespace CSD { class App { public static void Main() { int [] a = new int[100]; for (int i = 0; i < a.Lenght; ++i) a[i] = i; Disp(a); } public static void Disp(int[] r) { for (int i = 0; i < r.Lenght; ++i) Console.WriteLine(r[i]); } } } C# ta bir dizi nesnesi new operatr ile yaratldnda new operatr nesneyi yarattktan sonra dizinin tm elemanlarn sfrlamaktadr. Eer dizi bir 74

referans dizisi ise sfrlama dizinin her elemanna null deerinin atanmas anlamna gelmektedir. Bylece dizi yaratldktan sonra elemanlarna bir deer atanmam olsa bile elemanlarn ierisinde 0 deer olacaktr. new operatr ile bir dizi nesnesi yaratlrken dizi elemanlarna ayn zamanda ilk deer verilebilir. []den sonra hemen kme parantezi alarak ilk deerler belirtilir. rnein: int [] a; a = new int [5] {1, 2, 3, 4, 5,}; Bir diziye new operatr ile ilk deer verilirken {} ierisindeki dizi uzunluunun sabit ifadesi olmas zorunludur. Ayn zamanda verilen ilk deerlerin tam olarak belirtilen uzunluk kadar olmas gerekir. rnein: a = new int[size] {1, 2, 3}; error Yukarda diziye ilk deer verilmitir. Fakat uzunluk sabit ifadesi eklinde verilmemitir. Fakat rnein: a = new int[1 + 1 + 1] {1, 2, 3}; geerli Yukarda ilk deer verme ilemi geerlidir. a = new int[5] {1, 2, 3}; error Yukarda verilen ilk deerle dizi uzunluu uyumamaktadr. Diziye ilk deer verilirken [] parantezlerinin ii bo braklabilir. Bu durumda derleyici verilen ilk deerleri sayar ve sanki [] parantez ierisine o deer yazlm gibi ilem yapar. rnein: a = new int[] {1, 2, 3, 4, 5}; bo Bu ilem tamamen aadaki ile edeerdir. a = new int[5] {1, 2, 3, 4, 5}; geerli

75

C# ta diziye ilk deer verilirken [] ierisine ilk deerler sabit ifadesi ile oluturulmak zorunda deildir. rnein: int x = 1; int [] a; a = new int [] {x, x + 1, x + 2, x + 3}; geerli Bir dizi referans [] ierisinde bir deer listesi ile ilk deer verilerek tanmlanabilir. rnein: int [] a = {1, 2, 3}; geerli

Fakat phesiz ayn ilem ilk deer verme haricinde geerli deildir. rnein: int [] a; a = {1, 2, 3}; error

Dizi referansna bu biimde ilk deer verildii zaman derleyici verilen ilk deerleri sayar ve new operatrn kendisi uygulayarak dizi nesnesini bu uzunlukta yaratr. Bu ilk deerleri de dizi elemanlarna yerletirir. Yani: int [] a = {1, 2, 3}; ile int [] a = new int[3] {1, 2, 3}; tamamen edeerdir. Grld gibi bu biimde ilk deer verme tamamen kolaylk salama amac ile dnlmtr. Yoksa yine new ilemi uygulanmaktadr. Fonksiyonun geri dn deeri bir dizi trnden olabilir. BU durumda geri dn deerinin ayn trden bir dizi referansna atanmas gerekir. rnein: // public static void Main() { int [] r; r = Func(); for (int i = 0; i < r.Lenght; ++i) Console.WriteLine(r[i]); } public static int[] Func() { int [] a = new int [] {1, 2, 3, 4, 5}; return a; } //

76

imdiye kadar verdiimiz rneklerde hep temel trlere ilikin diziler oluturduk. Halbuki referans trlerine ilikin diziler de olabilir. rnein; x bir snf olmak zere x [] a = new x [10] ilemi ile 10 elemanl x trnden bir referans dizisi oluturulmutur. Yani burada dizinin 10 eleman da bir referanstr ve henz bunlar iin bir tahsisat yaplmamtr. Sample bir snf olmak zere aada yeni bir dizi yaratm olalm: Sample [] a; a = new Sample [10]; Burada dizi elemanlar olan a[i] ler Sample trndendir. Yani a[i] ler aslnda birer referanstr. Bir dizi yaratldnda dizi temel trlere ilikinse tm elemanlarnn ierisinde 0, referans trlerine ilikinse null deeri bulunur. Referans dizisini tahsis ettikten sonra bu referanslar iin gerek nesnelerin de tahsis edilmesi gerekir. Sample [] a; a = new Sample [10]; for (int i = 0; i < a.Lenght; ++i) a[i] = new Sample; Bu durum aadaki gibi gsterilebilir: a a[0] a[1] a[2] a[3] a[4] Sample trnden nesne

phesiz bir referans dizisi de new operatr ile yaratlrken ilk deer verilebilir. Bu durumda verilen ilk deerlerin ayn trden snf referanslar olmas gerekir. rnein: Sample [] a; a = new Sample [] {new Sample(), new Sample(),new Sample()}; string bir snf olduuna gre ve iki trnak ifadeleri iin string nesneleri derleyici tarafndan yaratldna gre aadaki gibi bir string dizisi oluturabiliriz: string [] a; a = new string [] {Ali, Veli, Selami, Aye, Fatma}; 77

Durum ekilsel olarak yle gsterilebilir: a a[0] a[1] a[2] a[3] a[4] Ali Veli
Selami

Aye Fatma

public static void Main() { string [] a; a = new string [] {Ali, Veli, Selami, Aye, Fatma}; for (int i = 0; i < a.Lenght; ++i) Console.WriteLine(a[i]); } public static void Main() { string [] names; names = GetNames(); for (int i = 0; i < names.Lenght; ++i) Console.WriteLine(names[i]); } public static string [] GetNames() { return new string [] {Ali, Veli, Selami, Aye, Fatma}; } System.IO isim alanndaki Directory isimli snfn static GetFiles fonksiyonunun parametrik yaps yledir: public static string [] GetFiles {string path}; Directory snf mscorlip.dll ierisinde olduu iin bir dll referans etmeye gerek yoktur. GetFiles fonksiyonu bir klasrn yol ifadesini referans olarak alr. O klasrdeki tm dosya isimlerini bir string dizisine yerletirir ve o dizinin referans ile geri dner. Yani bu fonksiyon sayesinde herhangi bir klasrdeki dosyalar elde edilebilir. rnein: public static void Main() { string [] files; files = System.IO.Directory.GetFiles(@c\windows); 78

for (int i = 0; i < files.Lenght; ++i) Console.WriteLine(files[i]); } Directory snfnn baka faydal fonksiyonlar da vardr. rnein; snfn GetDirectories static fonksiyonu klasr ierisinde bulunan klasrleri verir. Her iki fonksiyonda da parametre olarak var olmayan bir klasr geirilirse exception oluur. FOREACH DNGS Foreach dngs Cde ve C++da yoktur. ok benzeri Java da bulunmaktadr. Anahtar Notlar C#ta INumerible arayzn destekleyen snf ve yaplara dizilim denilmektedir. Normal diziler de bu arayz desteklediklerinden onlar da bir dizilim olarak deerlendirilmektedir. .Netin collection snflar INumerible snfn desteklemektedir. Bu nedenle onlarda bir dizilim olarak deerlendirilir. Foreach dngleri genel olarak bir dizilimi (dizi ya da collection snf) dolamakta kullanlr. Foreach dngsnn genel biimi yledir: foreach (< tr > < dng deikeni > in < dizilim >) < deyim > Foreach dngsnde her yinelemede dizilimin dier bir eleman dng deikeni ierisine yerletirilir. Dizilimin tm elemanlar yerletirildikten sonra dng sonlanr. rnein: int [] a = {1, 2, 3, 4, 5}; foreach (int x in a) System.Console.WriteLine(x); Burada ilk yinelemede dizinin ilk eleman olan 1 xe yerletirilir. Sonraki yinelemede 2, sonrakiler de 3,4,5 yerletirilecektir. Dizi elemanlarnn dng deikenine atanmas dntrme operatr ile yapld varsaylmaktadr. rnein: int [] a = {1, 2, 3, 4, 5}; foreach (byte x in a) System.Console.WriteLine(x); Yukardaki dng geerlidir. Burada dizinin her eleman int trdendir. int trnden byte trne dorudan dntrme yoktur. Fakat tr dntrme operatr ile vardr. te xe atamann bu ekilde yapld varsaylr. Bu ilemin for edeeri aadaki gibidir: 79 ileminin tr

// int [] a = {1, 2, 3, 4, 5}; for (int i = 0; i < a.Length; ++i) { byte x = (byte)a[i]; System.Console.WriteLine(x); } // rnein bir string dizisi de benzer biimde foreach dngs ile dolalabilir: // public static void Main() { string [] names; names = new string Fatma};

[]

{Ali,

Veli,

Selami,

Aye,

foreach (string name in names) System.Console.WriteLine(name); } // rnein bir dizideki dosya isimlerini foreach dngs ile yle yazdrabiliriz: // string [] files; files = System.IO.Directory.GetFiles(@c:\windows); foreach (string file in files) System.Console.WriteLine(file); // phesiz hi ara deiken kullanmadan ayn ilem pratik bir biimde yle de yaplabilir:
// foreach (string file in System.IO.Directory.GetFiles(@c:\windows)) System.Console.WriteLine(file); //

Benzer biimde aadaki ilem de geerlidir: foreach (int x in new int [] {1, 2, 3, 4, 5}) System.Console.WriteLine(x); Foreach dngsndeki dng deikeni, yalnzca dng deyimlerinde kullanlabilir. Dng deikeninin read only olduu varsaylmaktadr. Yani bu deiken kullanlabilir fakat bu deikene yeni bir deer atanamaz.

80

Java da foreach dngs yine for anahtar szc ile oluturulmaktadr. Semantik olarak benzerdir fakat syntax olarak in anahtar szc yerine : atomu bulunmaktadr. rnein: int [] a = {1, 2, 3, 4, 5}; for (int x : a) System.out.printLn(x); FARKLI PARAMETRK YAPILI AYNI SML FONKSYONLAR Anmsanaca gibi C# ta ayn isim alan ierisinde, ayn isimli birden fazla snf bulunamaz. Fakat farkl isim alanlar ierisinde, ayn isimli snflar bulunabilir. Yine daha nce farkl snflarda ayn isimli ve ayn parametrik yapya sahip fonksiyonlarn bulunabileceini grmtk. Bir snfta parametrik yaplar farkl olmak koulu ile ayn isimli birden fazla fonksiyon bulunabilir. Bu zellie nesne ynelimli programlama tekniinde ingilizce function overloading denilmektedir. Parametrik yapnn farkl olmas parametrelerin sayca ve/veya trce farkl olmas demektir. Yani ayn isimli fonksiyonlarn ya parametre saylar farkl olmaldr eer parametre saylar ayn ise bunlarn trleri farkl olmak zorundadr. // class Sample { public void Func() { // } public void Func(int a) { // } public void Func(long a) { // } } // Burada Func fonksiyonu da Sample snfnda bulunabilir. nk bu fonksiyonlarn parametrik yaplar farkldr. Parametre deikenlerinin isimlerinin farkl olmasnn hibir etkisi yoktur. nemli olan trlerin farkl olmasdr. Fonksiyonlarn geri dn deerinin parametrik yapy deitirmede bir etkisi yoktur. Yani parametrik yaps ayn fakat geri dn deeri farkl ayn isimli fonksiyonlar ayn snfta bulunamaz. rnein:

81

// class Sample { public void Func(int a) { // } public int Func(int a) { // } } //

geersiz

Benzer biimde eriim belirleyicilerinin farkl olmas ya da static olma durumu parametrik yapy farkl hale getirmez. Yani rnein ayn isimli ve ayn parametrik yapya sahip biri normal dieri static olan iki fonksiyon ayn snfta bulunamaz. Parametrelerin sras farkllatrmada etkilidir. rnein; aadaki iki fonksiyon ayn anda bulunabilir: // class Sample { public void Func(int a, long b) { // } public void Func(long a, int b) { // } } // Ayn isimli bir fonksiyon arldnda acaba derleyici bu fonksiyonlarn hangisinin arlm olduunu anlayacaktr? Kabaca ifade edilirse derleyici nce arlma ifadesindeki parametrelerin trlerini hesap eder. Bu parametrik tre tam uygun, ayn isimli fonksiyon varsa onun arlm olduunu kabul eder. Peki ya yoksa? Ayn isimli bir fonksiyon arldnda, arlacak olan fonksiyonun tespit edilmesi ilemine ingilizce overload resolution denilmektedir. Overload resolution ilemi karmak bir ilemdir. Programclarn ou bu ilemin ayrntlarn tam olarak bilmez. Programc, arma ifadesindeki trleri tam olarak parametrik yapdakine uygun hale getirirse, armak istedii fonksiyonu her zaman arabilir. Eer arma ifadesindeki parametrelere tam uygun olan bir fonksiyon yoksa ite bu durumda hangi fonksiyonun arlaca overload resolution kurallarna gre tespit edilir.

82

OVERLOAD RESOLUTION LEM Overload resolution ilemi aamada yrtlmektedir. Birinci aamada aday fonksiyon belirlenir. kinci aamada aday fonksiyonlar ierisinden uygun fonksiyonlar seilir. nc aamada ise uygun fonksiyonlar yara sokularak en uygun fonksiyon seilir. arlma ifadesindeki snfta bulunan tm ayn isimli fonksiyonlar aday fonksiyonlardr. rnein: // class Sample { public void { // } public void { // } public void { // } public void { // } public void { // } public void { // } } //

Func()

-1-

Func(int a)

-2-

Func(int a, long b)

-3-

Func(long a, int b)

-4-

Func(int a, int b)

-5-

Func(double a, double b)

-6-

Fonksiyonun yle arldn varsayalm: Sample.Func(a, b); Burada ayn isimli tm fonksiyonlar (1,2,3,4,5,6 nolu fonksiyonlar) aday fonksiyonlardr. Uygun fonksiyonlar arlma ifadesindeki parametrelerle ayn sayda parametre deikenine sahip olan ve arlma ifadesindeki parametrelerin her birinden, parametre deikenlerine dorudan dntrmenin sz konusu olduu fonksiyonlardr. rneimizde 1 ve 2 nolu fonksiyonlar uygun fonksiyonlar deildir. nk parametre saylar uyumamaktadr. 3 nolu fonksiyon uygundur. nk char int, char long dorudan dntrmesi 83

baka bir deyile dorudan atama ilemi sz konusudur. Benzer biimde 4,5,6 nolu fonksiyonlar aday fonksiyonlardr. imdi fonksiyonun aadaki gibi arldn varsayalm: Sample.Func(10,10,2); Bu durumda tm fonksiyonlar adaydr fakat yalnzca 6 nolu fonksiyon uygun fonksiyondur. En uygun fonksiyon yle bir fonksiyondur ki arlma ifadesindeki parametrelerle yara sokulduunda her parametresi daha iyi dnm salayan ya da daha kt bir dnm salamayan fonksiyondur. ki dorudan dntrme arasnda kalite fark vardr. Kalite farkll u maddelerle aklanabilir: 1- Eer zde dntrme varsa bu kesinlikle dier dntrmelerden daha kalitelidir. rnein intten inte dntrme intten longa dntrmeden daha kalitelidir. 2- T1 T2 dntrmesi ile T1 T3 dntrmesi kyaslanacak olsun. Eer T2den T3e dorudan dntrme var fakat T3ten T2ye dorudan dntrme yoksa T1 T2 dntrmesi, T1 T3den daha iyidir. rnein; char int , char long dntrmeleri kyaslanacak olsun. charint dntrmesi, char long dntrmesinden daha iyidir. nk intten longa dorudan dntrme vardr fakat longdan inte dorudan dntrme yoktur. rnein int long dntrmesi ile int double dntrmesi kyaslanacak olsun. int long dntrmesi daha iyidir. 3- T1 T2 dntrmesi ile T1 T3 dntrmesi kyaslanacak olsun. Eer ne T2den T3e ne de T3den T2ye dorudan dntrme yoksa bu durumda iaretli tre yaplan dntrme daha iyi kabul edilir. rnein; ushort int dntrmesi ile ushort uint dntrmesi kyaslanacak olsun. te burada ne int trnden uint trne ne de uint trnden int trne dntrme vardr. O halde bu durum bu maddeye girmektedir. ushort int dntrmesi daha kalitelidir. nk iaretli tre yaplan dntrme tercih edilmektedir. 4- Decimal dntrmesi en kt dntrme olarak belirlenmitir. Bu nedenle rnein; int decimal dntrmesi ile int double dntrmesi kyaslanacak olsun. Bu kyaslamay bu madde de ele alarak, int double dntrmesinin daha iyi olduu sylenebilir. En uygun fonksiyon, arlma ifadesindeki tm parametreler uygun fonksiyonlar yara sokulduunda daha iyi bir dntrme sunan ya da daha kt dntrme sunmayan fonksiyondur.

84

// class Sample { public static { // } public static { // } public static { // } public static { // } public static { // } } //

void Func(int a)

void Func(int a, int b)

void Func(int a, long b)

void Func(long a, double b)

void Func(long a, long b)

imdi fonksiyonun yle arldn varsayalm: Sample.Func(x, y); Burada 1,2,3,4,5 nolu fonksiyonlarn hepsi aday fonksiyonlardr. 2,3,4,5 nolu fonksiyonlar uygun fonksiyonlardr. imdi en uygun fonksiyonu bulmaya alalm. Uygun fonksiyonlarn her parametresi arma ifadesindeki parametreler ile yara sokulur. rnein birinci parametre char trdendir. char int dntrmesi char long dntrmesinden daha iyi olduuna gre 2 ve 3 nolu fonksiyonlar en uygun fonksiyon olabilir. Fakat artk 4 ve 5 nolu fonksiyonlar en uygun fonksiyon olamaz. Ancak 4 ve 5 nolu fonksiyonlar yara devam etmektedir. kinci parametreler yara sokulduunda char int dntrmesi char long ve char double dntrmelerinden daha iyi olduuna gre 2 nolu fonksiyon en uygun fonksiyon olarak belirlenir. nk 2 nolu fonksiyonun her parametresi arlma ifadesindeki parametreler dikkate alndnda dierlerine gre daha iyi ya da daha kt olmayan bir dntrme sunmaktadr. Fonksiyonun yle arldn varsayalm: Sample.Func(10, 2.3F); Burada zaten uygun fonksiyon bir tanedir.(4 nolu fonk.) Dolaysyla yar zaten bu fonksiyon kazanacaktr.

85

Fonksiyonun yle arldn varsayalm: Sample.Func(10L, 20); Burada uygun fonksiyon 4 ve 5 nolu fonksiyonlardr. En uygun fonksiyon 5 nolu fonksiyondur. Sample snfnn aadaki gibi olduunu varsayalm: // class Sample { public static void Func(int a) { // } public static void Func(int a, int b) { // } public static void Func(long a, int b) { // } } // Fonksiyonun yle arldn varsayalm: Sample.Func(10, 20); Burada 1,2,3 nolu fonksiyonlar aday fonksiyonlardr. 2 ve 3 nolu fonksiyonlar uygun fonksiyonlardr. Burada en uygun fonksiyon yoktur. Dolaysyla arlma error ile sonulanr. Birinci parametre yara sokulduunda 2 nolu fonksiyon dntrmesi, ikinci parametreler yara sokulduunda 3 nou fonksiyon dntrmesi daha iyidir. Dolaysyla her parametre dierleri ile yara sokulduunda daha iyi dntrme salayan ya da daha kt dntrme salayan fonksiyon yoktur. Grld gibi eer programc armay uygularken parametre trlerini ayn yaparsa buna kar gelen fonksiyon kesinlikle en uygun fonksiyon olarak seilecektir. SINIFLARIN BALANGI FONKSYONLARI smi snf ismi ile ayn olan fonksiyonlara snfn balang fonksiyonlar denilmektedir. Balang fonksiyonlar C# ta static de olabilir. Fakat balang fonksiyonlar tipik olarak static olmayan fonksiyonlardr. Static balang fonksiyonu daha ileride ele alnacaktr.

86

rnein: // class Sample { public Sample() { // } } //

balang fonksiyonu

Balang fonksiyonunda geri dn deeri kavram yoktur. Geri dn deeri yerine bir ey yazlmaz. Yazlrsa error oluur. Fakat balang fonksiyonu ierisinde return anahtar szc kullanlabilir. Ancak yanna bir ifade yazlamaz. Snfn birden fazla balang fonksiyonu bulunabilir. phesiz bunlarn parametrik yaplar farkl olmak zorundadr. rnein: // class Test { public Test() { // } public Test(int a, int b) { // } public Test(int a, int b, int c) { // } } // Snfn parametrik olmayan balang fonksiyonuna zel olarak default balang fonksiyonu denir. Eer bir snf iin hibir balang fonksiyonu yazlmamsa, default balang fonksiyonu derleyici tarafndan ii bo bir ekilde yazlmaktadr. rnein: // class Foo { public void Func() { // } } // 87

Burada Foo snf iin programc herhangi bir balang fonksiyonu yazmamtr. O halde default balang fonksiyonu derleyici tarafndan ii bo olarak yazlacaktr. Fakat rnein: // class Sample { public Sample(int a) { // } public void Func() { // } } // Burada derleyici default balang fonksiyonunu kendisi yazmaz. Eer programc hibir balang fonksiyonu yazmam olsayd yazacakt. Snfn balang fonksiyonu new ilemi srasnda nesne heap ta tahsis edildikten sonra derleyici tarafndan otomatik olarak arlmaktadr. Aslnda new operatrnde snf isminden sonra parantezler ierisinde bir parametre listesi girilebilir. Yani new operatr ile snf nesnesi tahsis etmenin genel biimi yledir: new < snf ismi > ([parametre listesi]) Bu durumda derleyici tahsisat yaptktan sonra parametre listesine uygun olan balang fonksiyonunu arr. Burada overload resolution kurallar iletilmektedir. rnein: Sample a = new Sample(); Sample a = new Sample(10); Sample a = new Sample(10, 20); Burada farkl nesne farkl balang fonksiyonu ile yaratlmtr. BALANGI FONKSYONLARINA NEDEN GEREKSNM DUYULUR? Bir nesne yaratldnda bir takm ilk ilemlerin yaplmas gerekebilir. Bu ilemler, tipik olarak snfn balang fonksiyonu yaplrsa, nesne yaratlr yaratlmaz otomatik bir ilkleme gerekletirilmi olur. Balang fonksiyonu ayn zamanda snfn eitli veri elemanlarna uygun ilk deerlerin atanmas amac ile de kullanlmaktadr. Anmsanaca gibi new operatr tahsisat yaptktan sonra zaten snfn veri elemanlarn sfrlyordu. Eer balang fonksiyonunda veri elemanlarna deer atanmazsa veri elemanlarn da 0 88

deeri bulunmaya devam edecektir. Eer deer atama ilemi yaplrsa, atanan deer bu elemanlarda gzkecektir. arlan balang fonksiyonu ierisinde kullanlan veri elemanlar o anda yeni yaratlm olan nesnenin veri elemanlardr. rnein dosya ilemleri yapmakta kullanlan FileStream snfnn balang fonksiyonu, parametresi ile ald dosyay amaktadr. rnein: FileStream fs = new FileStream (a.dat); Ya da rnein seri port ilemlerini yapan SerialPort snfnn balang fonksiyonu seri portu uygun deerlerle set edebilir. FARKLI PARAMETRK YAPILARA LKN AYNI SML FONKSYONLAR NEDEN KULLANILIR? Bir snfn farl parametrik yaplara ilikin ayn isimli fonksiyonlarnn bulunabilme durumu (function overloading) nesne ynelimli programlama dillerinin hemen hepsinde olan bir zelliktir. Nesne ynelimli programlama teknii algsal aklk salamay hedeflemektedir. Bir snfn benzer ilemlerini yapan fonksiyonlarna ayn isimlerin verilmesi alglamay ve renmeyi kolaylatrmaktadr. Bylece programc, snfta ok fazla fonksiyon olduu duygusuna kaplmaz. Nesne ynelimli programlama teknii, insan-nesne ilikisi gz nne alnarak tasarlanmtr. Gnlk yaamda aslnda birbirinin tam ayns olmasa da nesnelere ayn cins isimler verilmektedir. nk nesnelerin ilevleri birbirine benzerdir. Anahtar Notlar Nesne ynelimli programlama teknii snflar kullanlarak program yazma tekniidir. Birtakm anahtar prensipler topluluundan olumaktadr. C++, Java, C# gibi diller bu tekniin uygulanmasn mmkn hale getirmek iin tasarlanmtr. Fakat bu dillerin kullanlmas, bu tekniin iyi bir ekilde kullanlmasn garanti etmez. Bu tekniin prensipleri iyi alglanmal ve yazlm bu prensiplere uygun olarak tasarlanmaldr. Nesne ynelimli programlama teknii baz anahtar kavramlardan olumaktadr. Bu kavramlar birbiri ile i ie gemi, birbirini dlamayan kavramlardr ve bu kavramlarn hepsi algsal bir aklk salamaya yneliktir. Benzer ilemleri yapan fonksiyonlara ayn isimlerin verilmesi tavsiye edilen bir durumdur. nk bu durum nesne ynelimli programlama tekniinin algsal aklk salama fikri ile rtmektedir. .Net snf ktphanesindeki snflarda da pek ok ayn isimli fonksiyon bulunmaktadr. rnein; aslnda Console snfnn tek bir Write ya da WriteLine fonksiyonu yoktur. Her temel tr iin ayr bir Write ya da WriteLine fonksiyonu vardr. 89

Biz bu fonksiyona hangi trden parametre geersek derleyici overload resolution ilemi ile uygun fonksiyonu tespit etmektedir. SINIFLARIN TEMEL ERM KURALLARI imdiye kadar iki tr snf eleman grdk; snfn veri elemanlar ve fonksiyonlar. Bunlar static olabilir ya da olmayabilir. Snf elemanlarnn nne bildirim srasnda eriim belirleyici szcklerden biri getirilebilir. Eriim belirleyici anahtar szckler yerel deiken bildirimlerinde kullanlamaz. Eriim belirleyici anahtar szckler unlardan biri olabilir: private, public, protected, internal, protected internal. Snf eleman bildiriminde eriim belirleyici anahtar szckler hi yazlmayabilir. Bu durumda private yazlm gibi ilem grr. Anahtar Notlar C++ ta snfn default blm private blmdr. Ancak Java da default internal biimdedir. C# genel olarak Java ya kyasla daha fazla C++ a yaklatrlmtr. C++ ta da internal ve protected internal blm yoktur. Ayrca protected internal yerine internal protected yazlmas da geerlidir. Snflardaki eriim kurallar birka madde ile zetlenebilir: 1- Snfn fonksiyonu olmayan bir fonksiyon ierisinden (yani baka bir snfn fonksiyonu ierisinde), ilgili snf trnden ya da snf ismi yoluyla (eleman static ise) snfn yalnz public elemanlarna eriilebilir. 2- Snfn bir fonksiyonu ierisinde, eriim belirleyici ne olursa olsun snfn tm elemanlarna dorudan eriilebilir. Yani snf ierisinde herhangi bir koruma sz konusu deildir. internal eriim belirleyici ayn zamanda assembly ierisinde public, farkl bir assembly ierisinde private etkisi yaratr. Yani biz snfn internal elemanna ayn assembly ierisindeki baka bir snftan eriebiliriz. nk bu durumda internal, public gibi etki yapmaktadr. Fakat internal bir elemana baka bir assembly ierisindeki elemandan ulalamaz. Snfn protected ve protected internal elemanlar ancak tretme durumu sz konusu olduunda private elemanlardan farkl bir eriime sahip olur. Bu nedenle protected ve protected internal elemanlar tretme konusunda ele alnacaktr. Sonraki anlatmlarda snfn public blm, snfn private blm biiminde ifadeler kullanlacaktr. Snfn public blm demek, snfn tm public elemanlar, snfn private blm demekle snfn tm private elemanlar anlalmaktadr. Yani sanki snf blmlerden oluuyormu ta bu elemanlar o blmdeymi gibi

90

ERM KURALLARININ ANLAMI Snfn bir elemann private blme yerletirmekle biz o eleman darnn kullanmna kapatrz. Yani o eleman ancak snf ierisinden kullanlabilir durumda olur. Halbuki biz bir eleman public blme yerletirirsek o eleman herkesin kullanmna sokarz. Bir snf iin iki bak as sz konusudur: 1- Snf Kullanan Kiinin Bak As: Snf kullanan kii, snfn public blmne younlamaldr. Zaten dier blmleri kullanmayacaktr. Yani snf kullanan kii iin snf adeta public blm kadardr. 2- Snf Tasarlayann Bak As: Snf tasarlayan kii snfn her blmn bilmek zorundadr. Nesne ynelimli programlama teknii, insan-nesne ilikisi modellenerek oluturulmutur. Yani rnein; kullandmz pek ok nesnede de public ve private blm vardr. Bir snf tasarlanrken yalnzca darnn ilgisini ekecek olan elemanlar public blmne yerletirmeliyiz. Snfn i ileyiine ait olan, snf kullanan kiilerin bilmesine gerek olmayan elemanlar, snfn private blmne yerletirilmelidir. Bu abaya nesne ynelimli programlama tekniinde kapslleme(encapsolution) denilmektedir. Kapslleme snfn i ileyiine ilikin zelliklerini darya gizleyerek kullanm az sayda public elemana brakma anlamndadr. phesiz snfn i ileyiine ilikin elemanlarnn private blme yerletirilmesi hem algsal aklk salarken hem de dardan yaplacak bozucu etkilere kar snf korumaktadr. Yani rnein; arabann private blmn oluturan blmler bir kaputun altna gizlenmeseydi bunlarn kurcalanmasna ak bir durum oluurdu ve araba daha kolay bozulabilirdi. rnein bir snfn dardan arlacak DoSometingImportent isimli nemli bir fonksiyonu olsun. Fakat bu fonksiyon bu nemli ii yaparken Func1(), Func2(), Func3() isimli, iin paralarn yapan yardmc fonksiyonlar aryor olsun: // class Sample { public void DoSometingImportent { Func1() { // } Func2() { // } 91

Func3() { // } } } // Buradaki Func1(), Func2(), yerletirilerek gizlenmelidir. Func3() fonksiyonlar private blme

SINIFIN VER ELEMANLARINI GZLENMES Snfn veri elemanlar aslnda snfn i ileyiine ilikindir. Bu nedenle private blme yerletirilmelidir. Snfn veri elemanlar private blme alnarak gizlenmesine nesne ynelimli programlama tekniinde veri elemanlarnn gizlenmesi(data hiding) denilmektedir. Veri elemanlarnn gizlenmesi, nesne ynelimli programlama tekniinin anahtar kavramlarndan birisidir. phesiz data hiding kavram, encopsolution kavramndan btnyle farkl deildir. Onun bir ynn belirtmektedir. Bir snf iin, snfn kendi kodlarndan ve snf kullanan kodlardan bahsedilebilir. Snfn veri elemanlar daha sonra deitirilmeye yatkn elemanlardr. Yani snfn daha sonraki versiyonlarnda bu elemanlar tr ve isim bakmndan deitirilebilir. Eer biz veri elemanlarn snfn public blmne yerletirirsek onlar dardan kullanabilirler. Daha sonra bu veri elemanlar deitirildiinde o kodlar geersiz hale gelebilir. Snfn veri elemanlarn private blme yerletirdikten sonra yine de baz veri elemanlarna dardan eriilmesi anlaml ve gerekli olabilir. te bu durumda, bu veri elemannn deerini veren ve bu elemana deer atayan public fonksiyonlar bulundurulur. Bu tr fonksiyonlara Get/Set fonksiyonlar ya da eriimci fonksiyonlar denir. C# ta bu tr Get/Set fonksiyonlarn kolay yazmak iin property kavram uydurulmutur. Property elemanlar, private elemanlara ulam salayan Get/Set fonksiyonlardr. Java da ve C++ ta property kavram yoktur ve bu fonksiyonlar aka yazlmak durumundadr. rnein; Date isimli bir snfn day, mount, year isimli veri eleman olsun. Ayn zamanda programcnn bu elemanlara dardan eriilmesini de istediini varsayalm. Burada programc veri elemanlarn private blme yerletirmeli ve onlara public Get/Set fonksiyonlar ile eriimi salamaldr: // class Date { private int day; private int mount; private int year; public int GetDay() { return day; 92

} public void SetDay(int d) { day = d; } public int GetMonth() { return month; } public void SetMonth(int m) { day = d; } public int GetYear() { return year; } public void SetYear(int y) { year = y; } } // Grld gibi veri elemanlarna dorudan deil public fonksiyonlar yoluyla eriilmektedir. Snf Kullanan Kii public eriimci fonksiyonlar private veri elemanlar

Bir dilin nesne ynelimli olabilmesi iin zelliin dilde bulunmas gerekir: 1- Dilde snf kavramnn bulunmas gerekir. 2- Dilde snflarn tretilmesi kavramnn bulunmas gerekir. 3- Dilde ok biimlilik kavramnn bulunmas gerekir. Eer dilde ilk iki kavram var fakat nc kavram yoksa dile nesne ynelimli deil nesne tabanl(object based) denir. C++, Java ve C# ta bu zelliklerin hepsi vardr. Bu nedenle bu diller nesne ynelimli dillerdir. Fakat rnein Visual Basicin eski versiyonu olan VB 6.0da ok biimlilik kavram olmad iin bu dil nesne tabanldr. Fakat VB.Net nesne ynelimlidir. VER ELEMANLARININ PRIVATE BLME YERLETRLP ONLARA PUBLIC ERMCLER LE ERLMESNN ANLAMI Veri elemanlarnn private blme yerletirilerek dar ile ilikisinin kesilmesi ve bunlara gerektiinde public get/set fonksiyonlar ile eriilmesi uzun dnemde olduka faydal sonular dourmaktadr: 1- Veri elemanlar private blme yerletirilirse snf kullanan kiiler bunlara eriemez. Gnn birinde bu veri elemanlarnn genel yapsnda bir deiiklik yapldnda daha nce yazlm olan snf kullanan kodlar 93

bu deiikliklerden etkilenmez. nk veri elemanlarna get/set arayz fonksiyonlarla eriilmitir. Tabi programcnn bu get/set fonksiyonlarnn iini, parametrik yapda deiiklik oluturmadan yeni duruma uygun bir biimde yazmas gerekir. rnein; yukarda yazlm olan Date snfn kullanan aadaki gibi bir kod sz konusu olsun: // Date date = new Date(); date.SetDay(10); date.SetMonth(12); date.SetYear(2000); // if (date.GetMonth() == 12) { // } // imdi Date snfn yazan irketin tarih bilgisini tane ayr int deikende deil de dd/mm/yyy formatnda tek bir string nesnesinde tutmaya karar verdiini dnelim. // class Date { string date; } // irketin tek yapaca bu get/set fonksiyonlarnn iini string ile alacak ekilde deitirmektedir. Snf kullanan kodlarda ki get/set fonksiyonlarnn armalar, ayn geerli anlamn koruyacaktr. 2- Snfn birbirleri ile ilikili olan veri elemanlar bulunabilir. Bu ver elemanlarnn birinin deitirilmesi dier baz veri elemanlarnn deitirilmesini gerektirebilir. Eer veri elemanlarn public blme yerletirirsek btn bu deiiklikler snf kullanan kii tarafndan yaplmak zorundadr. Bu da snfn kullanmn zorlatrr. Halbuki veri elemanlarn private blmde tutup bunlara public get/set fonksiyonlar ile eriirsek snfn veri elemanlar arasndaki bu uyum set fonksiyonu ierisinden salanabilir. Bylece veri elemanlar arasndaki ilikiyi snf kullanan kii bilmek zorunda kalmaz. rnein; dairesel ilemler yapan Circle isimli bir snfn veri elemanlar, dairenin merkez koordinatlar ve yarap olabilir. Fakat snfn iinde dairenin alan pek ok yerde gerekiyorsa programc snfn veri eleman olarak dairenin alann tutan bir deiken bulundurmak isteyebilir. Bylece snf tasarlayan kii dairenin alann kullanaca yerlerde, her zaman pi r2 ilemini yapmak yerine, yarap set edilirken bir kere dairenin alann tutan deikene deer atayp bunu kullanmak isteyebilir. Grld gibi eer biz yarap tutan veri elemann public blme yerletirirsek, 94

bunu deitirecek kiinin alan deikenini de deitirmesi gerekir. Halbuki biz yarap deikenini private blmde tutup onu bir set fonksiyonu ile deitirmeye alrsak o fonksiyon ierisinde alan deikenine gizlice yeni deerini atayabiliriz. class Circle { private double centerx, centery; private double radius; private double area; // public Circle(double x, double y, double r) { centerx = x; centery = y radius = r; area = Math.PI * r * r; } public double GetRadius() { return radius; } public void SetRadius() { radius = r; area = Math.PI * r * r; } } 3- Bir veri eleman set edilirken arka planda baka ilerinde yaplmas gerekebilir. te bu ilemler gizlice set fonksiyonu ierisinde yaplabilir. Ya da benzer biimde bir veri elemannn deeri alnrken de baka ilemlerin yaplmas gerekebilir. rnein seri port ilemlerini yapan SerialPort isimli bir fonksiyon olsun. Portun hz snfn bir veri elemannda tutuluyor olabilir. Yalnzca bu veri elemannn set edilmesi portun hznn ayarlanaca anlamna gelmez. te portun hzn set fonksiyonu, hem bu veri elemanna yeni deerini atarken hem de bir takm sistem fonksiyonlar ile portun hzn gerekten set edebilir. SINIFIN PROPERTY ELEMANLARI Snfn property elemanlar aslnda bir veri elemanna dardan erimeyi salayan get/set fonksiyonlarndan baka bir ey deildir. Bir property elemannn genel biimi yledir: [eriim belirleyicisi] [static] <tr> <isim> { get { // } set { // } } 95

Aslnda property eleman, veri eleman gibi yazlr fakat genel biiminden de grld gibi ; yerine blok alr. Bir property eleman get ve set olmak zere iki blmden oluur. Property elemannn yalnzca get blm olabilir. Ya da hem get blm hem de set blm ayn yazlabilir. get ve set blmlerinin hangi srada yazldnn bir nemi yoktur. Yalnzca get blm olan property Read Only, yalnzca set blm olan property Write Only, hem get hem set blm olan property eleman Read/Write property denir. Property eleman onlar sanki bir veri elemanym gibi eriilmektedir. rnein; r snf trnden bir referans, A da bu snfn bir property eleman olmak zere eriim r.A eklinde yaplr. Bir property eleman bir ifade ierisinde kullanldnda, ya bir deer alma ya da deer atama amal kullanlr. rnein: // x = r.A + 1; deer alma amal kullanlmtr. r.A = 10; deer atama amal kullanlmtr. Console.WriteLine(r.A); deer alma amal kullanlmtr. // Fakat istisna olarak eer property eleman ++ ve -- operatrlerinin bir operand biiminde kullanlmsa onun hem deer alma hem de deer yerletirme amal kullanld kabul edilir. rnein: ++r.A hem deer alma hem de deer atama amal kullanlmtr. Property elemannn get blm sanki bir get fonksiyonu gibi, set blm ise sanki bir set fonksiyonu gibidir. Eer property eleman deer alma amal kullanlmsa onun get blm, deer atama amal kullanlmsa onun set blm altrlr. Eer ++ ve -- operatrleri ile kullanlmsa nce get blm sonra set blm altrlr. Propertynin get blm, parametresi olmayan geri dn deeri property trnden olan bir fonksiyon gibidir. Bu nedenle get blmnde return kullanlmak zorundadr. Programc get blmnde tipik olarak propertynin ilikili olduu geri dn elemannn tr ile geri dner. Tabi get blmnde baka tamamlayc ilemlerde yaplabilir. rnein: // class Sample { private int a; private int b; get { // return a; 96

} set { // } } // Property eleman deer alma amal kullanldnda elemann get blm altrlr. Burada elde edilen geri dn deeri ileme sokulur. rnein: Sample s = new Sample(); // x = s.A + 1; C# ta kullanm x = s.GetA() + 1; Java da kullanm

Property elemannn set blm, parametresi property trnden olan geri dn deeri void olan bir fonksiyon gibidir. Set blmnde value anahtar szc, bu set blmnn parametresini temsil eder. Value anahtar szc yalnzca set blmnde kullanlr, get blmnde kullanlmaz. Set blmndeki value anahtar szc, property elemanna yerletirilecek sonu ifadesini temsil etmektedir. O halde programc tipik olarak set blmnde value anahtar szcn ilgili private elemanna atamaldr. Tabi nceki konularda da sz edildii gibi set ilemi srasnda baka ilemlerde yaplabilir. rnein: Sample s = new Sample(); // s.A = x + y; Burada propertye atanmak istenen deer x + y ifadesidir. Yani x + y deeri hesaplanacak, sonra propertynin set blm altrlacak, set blmnn value anahtar szc de, x + y deerini temsil edecektir. Ayn ilem C++ ya da Java da aadaki gibi yaplrd: s.SetA(x + y); Bu durumunda property yle yazlacaktr: // class Sample { private int a; private int b; get { // return a; 97

} set { // a = value; } } // using System; namespace CSD { class App { public static void Main() { Sample s = new Sample(10); Console.WriteLine(s.A); s.A = 100 + 200; Console.WriteLine(s.A); } } class Sample { private int a; public Sample() { } public Sample(int x) { a = x; } public int A { get { return a; } set { a = value; } } } } Aslnda property kavram ile daha ncede karlamtk. rnein; string snfnn Lenght isimli property eleman yaznn uzunluunu vermektedir. Yani muhtemelen string snf ierisinde sadece yaz deil private bir eleman da yaznn uzunluunu tutmaktadr. Lenght property eleman get blmnde yine muhtemelen bu veri elemannn deerini vermektedir. rnein: string s = Ankara; Console.WriteLine(s.Lenght); 98

Burada Length property elemannn get blm altrlr. Get blmnde elde edilen deer yazdrlmtr. Read Only bir property(yalnzca get blm olan property) deer atama amal kullanlmaz. Benzer biimde Write Only property deer alma amal bir ifade de kullanlmaz. rnein; Lenght property eleman read only bir propertydir. Anmsanaca gibi diziler aslnda birer snftr ve tm dizi snflarnn Lenght isimli read only bir property eleman vardr. Bu property eleman dizinin uzunluk deerini vermektedir. phesiz bir property eleman yalnzca snfn private elemanyla iliki kuran bir fonksiyon biiminde olmak zorunda deildir. rnein; property elemannda set ilemi yaplrken aslnda arka planda baka ilemlerde yaplyor olabilir. Aslnda bir property elemannn private veri elamann hedef almas gibi bir zorunluluk yoktur. .Net GUI programlama modelinde eitli GUI snflarnn pek ok property eleman vardr. Bunlara set ilemi yapldnda arka planda bu propertylerin set blmleri, eitli faydal ve kark ilemleri yapmaktadr. Bylece bir .Net programnda yalnzca eitli propertyleri set ederek program bir dereceye kadar oluturulabilmektedir. Property kavram grsel programlama fikrini de kuvvetlendirmektedir. STATIC PROPERTYLER Anmsanaca gibi snfn static veri elemannn toplamda tek bir kopyas vardr. te static veri eleman da snfn private blmne yerletirilmeli ve onlara public static propertyler ile eriilmelidir. Static propertylerin get ve set blmlerinde, snfn static olmayan veri elemanlar ve fonksiyonlar dorudan kullanlamaz. Static propertylere, snf ismi ile eriilir. rnein: class Sample { private static int m_a; public static int A { get { return m_a; } set { m_a = value; } } } 99

Eriim yle yaplabilir: public static void Main() { Sample.A = 10; Console.WriteLine(Sample.A); }

SINIFLARIN TRETLMES Tretme (inheritence) daha nce yazlm bir snfn geniletilmesi iin kullanlan bir tekniktir. rnein; elimizde zaten yazlm olan bir A snf bulunuyor olsun. Biz bu A snfna eitli fonksiyonlar eklemek istiyoruz. lk akla gelecek yntem eer A nn kaynak kodlar varsa A nn orijinal biimini bozmak istemediimiz iin ondan B gibi bir kopya karmak ve eklemeleri bu kopya zerinde yapmaktr. Fakat bu yntem zayf bir yntemdir. A nn kaynak kodlar elimizde olmayabilir. Elimizde olsa bile B snfnda gereksiz bir biimde A snfndaki ayn elemanlar bulunacaktr. Tretme ynteminde mevcut bir A snfna ekleme yaplmak isteniyorsa bir B snf A snfnda tretilir. B snfna yalnzca eklenecek eler yerletirilir. Bylece B snf hem tamamen A snf gibi davranr hem de eklentilere sahiptir. Burada eklenti yaplmak istenen snfa (yani A snfna) taban snf(base class), eklentilerin yerletirilecei snfa (yani B snfna) tremi snf denilmektedir. Tretme ilemi UML gibi snf diyagramlarnda tremi snftan taban snfa ekilen bir okla gsterilmektedir. A

B Tretme ileminin genel biimi yledir: class <tremi snf> rnein: class A { // } class B:A { // } : <taban snf>

100

Tremi snf trnden bir referans, dardan tremi snf ile taban snfn tm public elemanlarna eriilebilir. rnein: // class App { public static void Main() { B b = new B(); b.Foo(); b.Bar(); } } class A { public void Foo() { Console.WriteLine(Foo); } // } class B:A { public void Bar() { Console.WriteLine(Bar); } // } // phesiz tretme yapabilmek iin taban snfn kaynak kodlarnn elde bulunuyor olmas zorunlu deildir. rnein taban snf bir dll ierisinde olabilir. Biz de o dll ye referans ederek tretmeyi yapabiliriz. Ya da rnein taban snf baka bir isim alann da bulunabilir. Bu durumda taban snf isminin, isim arama kurallarna gre bulunabilecek ekilde belirtilmesi gerekir. rnein: namespace X { class A { // } } namespace CSD { class B : X.A { // } // }

101

TREM SINIFLARDA ERM KURALLARI Daha nce tremi snfn taban snf gibi de davranabildiini belirtmitik. Tremi snfn taban snfa eriimi iin u kurallar geerlidir: 1- Tremi snf trnden bir referans yoluyla ya da tremi snf ismi ile (static ise), tremi snf fonksiyonu olmayan bir fonksiyon ierisinden, tremi snfn yalnzca public blmne eriilebilir. 2- Tremi snf fonksiyonlar ierisinde anmsanaca gibi tremi snfn her blmne dorudan eriilebilir. te ayn zamanda tremi snf fonksiyonlar ierisinde taban snfn public ve protected blmlerine dorudan eriilebilir. 3- Taban snfn private blmne ne dardan ne de tremi snftan eriilebilir. PROTECTED BLMN ANLAMI Public blm snfn herkese ak olan korunmam blmdr. Public blmdeki elemanlar herkes tarafndan her zaman kullanlabilir. Snfn private blm tam olarak korunmu blmdr. Private blme yerletirilen elemanlar yalnzca snf ierisinden kullanlabilir. Dardan ya da tremi snftan kullanlamaz. Protected blm darya kapal fakat tremi snfa ak olan blmdr. Biz bir eleman protected blme yerletirirsek onu dardan kullanamayz. Fakat snfn kendi ierisinden ve tremi snflarda kullanabiliriz. Snfn internal blm daha nce de belirtildii gibi ayn assembly ierisinde public, farkl bir assembly ierisinden eriimde private gibi davranr. Internal ok fazla kullanlmaz. Protected internal blm, ayn assembly ierisinden eriimlerde public (tpk internal blmde olduu gibi), farkl bir assembly den eriimlerde protected etkisi yaratan blmdr. Protected internal blm de ok seyrek kullanlmaktadr. Snfn hangi elemanlarnn protected blme yerletirmeliyiz? Snfn dary ilgilendirmeyen isel, isel ileyiine ilikin olabilecek fakat tremi snf yazanlar tarafndan gereksinim duyulabilecek elemanlar protected blme yerletirmeliyiz. Programc daha snf tasarlarken ondan tretme yaplp yaplmayacan gz nnde bulundurmal ve baz elemanlar eer tretme yaplrsa, tremi snfI yazanlar tarafndan kullanlsn diye protected blme yerletirilmeli. Bakalar tarafndan yazlm bir snf olduunu dnelim (.Net Ktphanesi). Bir snfn dokmantasyonun da kesinlikle public, protected, 102

protected internal blmdeki elemanlar aklanmaldr. Public blm herkes iin, protected ve protected internal blmler o snftan tretme yapmak iin dokmante edilmelidir. BR DZ TRETME YAPILMASI DURUMU Tremi bir snftan tekrar tretme yaplabilir. rnein: // class A { // } class B:A { // } class C:B { // } //

Burada C snf, hem B gibi hem de A gibi davranabilmektedir. Yani dardan C snf trnden bir referans yoluyla ya da C snf ismi yoluyla (static olmas durumunda) hem C snfnn, hem B snfnn hem de A snfnn public elemanlarna eriilebilir. Benzer biimde C snfnn bir fonksiyonu ierisinden dorudan hem B snfnn hem de A snfnn public ve protected elemanlarna eriilebilir. Anahtar Notlar Nesne ynelimli programlama tekniinde bir eyin sfrdan yazlmas yerine daha nce yazlm olanlarda faydalanlmas nerilen bir davrantr. rnein; sfrdan bir snf yazmak yerine az ok gereksinimimizi karlayan daha nce yazlm olan bir snf kullanarak ya da o snftan tretme yaparak bu yeni snf oluturmak iyi bir tekniktir. Daha nce yazlm olan kodlardan faydalanma temas nesne ynelimli programlama tekniinin anahtar kavramlarndandr. Buna yeniden kullanlabilirlik denilmektedir. Bir snf birden fazla snfn taban snf olabilir. rnein: // class A { // } class B:A { 103 C

// } class C:A { // } // Burada B ile C arasnda bir iliki yoktur. Yukardaki durumun tersi zel bir durumdur. Bir snfn birden fazla taban snf olabilir mi?

Burada C snfnn iki taban snf vardr. Bu tretme ilemine nesne ynelimli programlama tekniinde oklu tretme denilmektedir. Ancak maalesef C# ve Java oklu tretmeyi desteklememektedir. C# ve Java da bir snfn tek bir taban snf olabilir. NE ZAMAN TRETME UYGULANMALIDIR? Bir B snf yazma isteyelim. Kabaca seenek sz konusu olabilir: 1- B snfn sfrdan yazabiliriz. 2- Elimizde bir A snf vardr. A snfndan tretme yaparak yazabiliriz. 3- Elimizde bir A snf vardr. Biz B snfnn ierisinde, A snf trnden bir veri eleman alrz. B snfnn balang fonksiyonunda A y yaratrz. Sonra B nin fonksiyonlarn bu A nesnesini kullanarak yaratrz. class B { private A a; public B() { a = new A(); // } // } Eer B bir eit A ise fakat birtakm fazlalklar varsa bu durumda B A dan tretilerek yazlmaldr. rnein; ister otomobil olsun, ister kamyon olsun, isterse motosiklet olsun her motorlu tatn ortak birtakm zellikleri vardr. 104

Bir tatn btn bu ortak zellikleri, tat isimli bir snf ile temsil edilebilir. rnein; her tatn bir ruhsat bilgisi, bir plakas, bir motoru vardr. Tm bu bilgiler ve zellikler tat snfnn zellikleri olabilir. imdi bir otomobil snf yazmak isteyelim. Otomobil de bir eit tattr. Bu durumda otomobil snfnn sfrdan deil tat snfndan tretilmesi gerekir. Bir kamyon snf yazacak olsak ta kamyon da bir eit tat olduuna gre kamyon snf da tat snfnda tretilmelidir.

TAIT

OTOMOBL

KAMYON

MOTOSKLET

Eer B bir eit A deilse, A B nin paralarndan bir ise ya da B yi yazarken A y kullanyor isek bu durumda tretme uygulanmamaldr. rnein; genel olarak bir tat motoru zerinde ilem yapan, motor isimli bir snf olsun. Otomobil bir eit motor deildir. O halde otomobil snfn yazarken motor snfndan tretme yapmamalyz. Otomobil snfn yazarken motor snfndan yararlanmalyz. Bu tr kapsama ya da kullanma ilemine nesne ynelimli programlama tekniinde composition ve aggregation denir. Bu iliki UML gibi aralarn snf diyagramlarnda, kullanan ya da ieren snf tarafnda ii dolu bir yuvarlak ya da baklava olacak bir biimde ekilen ok ile gsterilir. TAIT MOTOR OTOMOBL

TRETME LEMNE ETL RNEKLER 1- Bir iletme ile ilgili bir program yazlacak olsun. Nesne ynelimli programlama tekniinde, bir projeye konu olan tm gerek nesneler ve kavramlar snflarla temsil edilir ve program bu snflar kullanarak yazlr. Bu balamda iletmede alan kiiler grevlerine gre snflarla temsil edilecek olsun. Tm alanlarn bilgileri ve alan kim olursa olsun onun zerinde ilem yapan genel fonksiyonlar Employee isimli bir snf ile temsil edilebilir. iler bir eit alandr. Fakat bir iinin ii olmasndan kaynaklanan bir takm farkl zellikleri vardr. iler Worker snf ile temsil edilebilir. Worker snf Employee snfndan tretilebilir. Yneticiler de bir eit alandr. O halde Manager snf da Employee snfnda tretilebilir. st dzey yneticiler de bir eit 105

yneticidir. O halde Executive snf da Manager tretilebilir. Tretme emasn bir ekille belirtirsek: Employee

snfndan

Manager

Worker

SalesPosition

Executive Bir tretme emasnda yukar kldka genelleme, aa inildike zelleme oluur. 2- Windows GUI programlamada ekranda kontrol edilebilen bamsz alanlara pencere (window) denir. rnein; programn ana penceresi, dmeler, edit alanlar, seenek butonlar, listeleme kutular hep birer penceredir. Her pencerenin ortak baz zellikleri vardr. rnein; her pencerenin (pencere ne olursa olsun) bir zemin rengi sz konusudur. Her pencerenin bir boyutu ve konumu vardr. te .Net snf ktphanesinde tm bu farkl pencereler farkl snflarla temsil edilmitir. Tm pencerelerin ortak zellikleri Control isimli bir snfta toplanmtr. Pencere snflar bir Control snfnda tretilmitir.

Control

Button

TextBox

ListBox

Grld gibi tm pencere snflarnda Control elemanlar ortaktr. Bu snf sisteminin renilmesinde ncelikle ortak elemanlara younlalmas daha anlamldr. 3- Bir tetris program yazdmz dnelim. Tetris oyunundaki pek ok kavram ve e birer snfta temsil edilebilir. rnein; oyundaki her bir ekil ayr bir snfta temsil edilebilir. ekiller birbirlerinden farkl olmasna karn zemin renkleri, konumlar gibi ortak zellikleri vardr. O halde bu ortak zellikler Shape isimli bir snfta toplanabilir ve bu spesifik ekiller Shape snfndan tretilmi snflarla temsil edilebilir. Shape

BarShape

TShape 106

ZShape

LShape

TREM SINIFLARDA VERELEMANLARININ DURUMU Tremi snf trnden bir referans yaratldnda, tremi snf nesnesi yalnzca kendi static olmayan veri elemanlarn deil taban snfn static olmayan veri elemanlarn da ierir. Taban snfn veri elemanlar ile tremi snfn veri elemanlar, pei sra bir blok oluturmaktadr. Taban snfn veri elemanlar yukarda (yani daha dk adreste), tremi snfn veri elemanlar aada (yani daha yksek adreste) bir blok oluturacak ekilde bulunur. rnein B snf A snfnda tremi olsun: Adat Bdat B nesnesi

b B b = new B();

Burada Adat demekle A snfnn static olmayan veri elemanlarn, Bdat demekle B snfnn static olmayan veri elemanlar kastedilmektedir. rnei biraz daha somutlatrabiliriz: class A { private private // } class B:A { private private // }

int x; int y;

int z; int k;

B b = new B(); x y z K Adat Bdat B nesnesi

C snf B snfndan, B snf da A snfndan tretilmi olsun: A B C

107

imdi C snf trnden bir nesne yaratalm: C c = new C(); Adat Bdat Cdat

C nesnesi

this ANAHTAR SZC Aslnda bilgisayarn alma prensibi gz nne alndnda static olmayan fonksiyon kavram yapay bir kavramdr. Nesne ynelimli programlama dillerinde kolaylk salasn diye uydurulmutur. Aslnda biz her zaman static bir fonksiyonu sanki static olmayan bir fonksiyon gibi kullanabiliriz. Bunun iin tek yapacamz ey, static fonksiyona ayn snf trnden bir parametre gemek ve snfn static olmayan veri elemanlarna bu parametre yoluyla erimektir. rnein: class Sample { private int a; private int b; public static void Bar(Sample s) { s.a = 10; s.b = 20; } // } Fonksiyonu yle arabiliriz: Sample s = new Sample(); Sample.Bar(s); Ayn ilemin edeeri static olmayan bir fonksiyon ile yle yaplabilir: class Sample { private int a; private int b; public void Bar(s) { a = 10; b = 20; } // } 108

Sample s = new Sample(); s.Bar(); Grld gibi her static olmayan fonksiyon aslnda ek bir parametre ile static fonksiyon biimine dntrlebilir. Aslnda static olmayan fonksiyon yapay ve uydurma bir kavramdr. Static fonksiyonlar gerek bir kavramdr. Derleyici aslnda kod retimi yaparken static olmayan fonksiyonlar, onlara ek bir parametre geirerek static fonksiyon gibi ifade etmektedir. Aslnda static olmayan fonksiyonlarn ierisinde snfn veri elemanlarna dorudan eritiimizde, derleyici aslnda bu elemanlara geirilen bu gizli parametre yoluyla erimektedir. rnein; aslnda static olmayan bir fonksiyonun 0 parametresi varsa gerekte 1 parametresi, 1 parametresi varsa gerekte 2 parametresi vardr. Derleyici static olmayan fonksiyona, bu fonksiyon hangi referans ile arlmsa onu gizlice geirmektedir. te static olmayan fonksiyon, geirilen bu gizli parametreli fonksiyon ierisinde aka this anahtar szc ile kullanlabilir. this anahtar szc gizlice geirilen bu parametreyi temsil eder. this anahtar szc hangi snfta kullanlrsa o snf trnden bir referans belirtir. this referans hangi nesneyi gstermektedir? Static olmayan fonksiyon hangi referansla arlmsa, o referansn gsterdii nesneyi gsterir. this anahtar szc yalnzca static olmayan fonksiyonlar ve propertylerde kullanlr. Static fonksiyonlarda ve propertylerde kullanlmaz. nk static fonksiyonlar snf ismi ile arlr ve bunlara gizli bir referans geirilmemektedir. Static olmayan bir fonksiyon ierisinden, snfn rnein a isimli static olmayan bir veri elemanna dorudan a ifadesi ile erimekle this.a ifadesi ile erimek arasnda hibir etkinlik fark yoktur. Snfn Foo isimli static olmayan fonksiyonun, Bar isimli static olmayan dier bir fonksiyonu aracan dnelim. Bu ilem dorudan Bar() biiminde yaplabilir. Bu durumda aslnda derleyici Bar fonksiyonuna gizlice this referansn geirmektedir. Yani bu armann this.Bar() armasndan bir fark yoktur. this referans read only bir referans kabul edilmektedir. Yani this referansn kullanabiliriz ama ona bir deer atayamayz. this anahtar szcne neden gereksinim duyulmaktadr? this anahtar szc baz tipik durumlarda faydal bir biimde kullanlabilir. rnein; snfn veri elemanlar ile ayn isimli parametre deikenlerinin ya da yerel deikenlerin bulunduu durumda, snfn veri elemanlarna eriebilmek iin this anahtar szc kullanlabilir. nk this anahtar szc ile 109

eriim uygulandnda artk noktann sandaki isim nitelikli arama kurallarna gre snf bildiriminde aranr. rnein: class Date { private int day; private int month; private int year; public Date(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } } Burada dorudan kullanlan day parametre kullandmz ise snfn veri elemandr. deikeni, this.day ile

Programclarn ou hibir isim akmas olmasa bile snfn veri elemanlarna yine de this anahtar szc ile erimektedir. Bunun tek nedeni okunabilirlii arttrmaktr. rnein this.a gibi bir ifadeyi gren birisi a nn hemen snfn veri eleman olduunu anlar. Halbuki eriim dorudan a diyerek yaplsayd kodu inceleyen kii bu sonucu hemen elde edemezdi. Bu sonucu karabilmek iin kii, fonksiyonun tamamn incelemesi gerekirdi. Yine programclarn ou static olmayan bir fonksiyonun ierisinde, static olmayan bir fonksiyonu this anahtar szc ile armaktadr. Burada da ama okunabilirlii arttrmaktr. rnein bir fonksiyonu yalnzca Foo diyerek arrsak kodu inceleyen kii, fonksiyonu static de sanabilir static olmayan bir fonksiyon da sanabilir. Halbuki this.Foo eklinde arrsak kodu inceleyen kii kesinlikle fonksiyonun static olmadn anlayacaktr. TREM SINIFTAN TABAN SINIFA YAPILAN ATAMALAR C# ta farkl trden iki snf referans birbirine atanamaz. rnein A snf trnden bir referans, B snf trnden bir referansa dorudan atanamaz. Fakat tremi snf trnden bir referans, taban snf trnden bir referansa dorudan atanabilir. Bu zel bir durumdur. rnein: A x; B y = new B(); x = y //geerli tremiten tabana atama B A

Fakat bunu tersi olan durum yani taban snf trnden referansn, tremi snf trnden referansa atanmas durumu geerli deildir.

110

A a = new A(); B b; b = a //error tabandan tremie atama

A B

Tremi snf nesne referansn, taban snf trnden bir referansa atadmzda artk taban snf referans, tremi snf nesnesinin taban snf ksmn gsteriyor durumdadr. Yani biz bu taban snf referans ile ilem yaptmzda bu ilemlerden b nesnesinin a ksm etkilenir. B b = new B(); A A a; B a = b a
Bdat

Adat

b nesnesi

Grld gibi burada a referans, b nesnesinin a ksmn gsteriyor durumdadr. public static void Main() { B b = new B(); A a; b.ValB = 10; b.ValA = 20; Consol.WriteLine(a.ValA); a.ValA = 20; Consol.WriteLine(b.ValA); } class A { private int m_a; public int ValA { get { return m_a; } set { m_a = value; } } } class B:A { private int m_b; public int ValB { get { return m_b; } set { m_b = value; } } }

111

Bir dizi tretme sz konusu olsun. Bu durumda tremi snfa ilikin bir referans, onun tm taban snf referanslarna dorudan atanabilir. rnein: A B A B C C c = new C(); A a; B b; b = c a = c c b a
Adat Bdat Cdat

c nesnesi

Burada b = c atamas ile birlikte b referans, c nin b ksmn gsterir duruma gelir. Biz b referans ile hem B snfnn veri elemanlarn hem de A snfnn veri elemanlarn deitirebiliriz. Tremiten tabana atama yaplabilmesinin gerekesi, tremi snfn taban snf iermesindendir. Eer tabandan tremie atama yaplabilseydi, bu durumda tremi snf referans ile gerekte var olmayan elemanlara erime potansiyeli oluurdu. rnein: A a = new A(); A b = a; // geersiz B b
Bdat

Adat

a nesnesi

Fonksiyon arma ilemi de aslnda parametrelerden, parametre deikenlerine yaplan bir eit atama ilemidir. O halde bir fonksiyonun parametre deikeni, taban snf trnden bir referans ise biz o fonksiyonu herhangi bir tremi snf referans ile arabiliriz. rnein: Employee

Worker

Manager

SalesPosition

Executive

112

Public static void DoSometing (Employee e) { // } Manager m = new Manager(); DoSometing(m); Manager nesnesinin Employee blm Worker w = new Worker(); DoSometing(m); Worker nesnesinin Employee blm Burada Employee snf muhtemelen tm alanlarn hepsinin sahip olduu ortak elemanlar iermektedir. DoSometing fonksiyonu bir Employee bilgisi almaktadr. Fakat Manager snfnn Employee ksm da olabilir, Worker snfnn Employee ksm da olabilir. Biz DoSometing fonksiyonunu Manager nesnesi(m) ile ardmzda DoSometing, Manager nesnesinin Employee ksm zerinde ilem yapacaktr. rnein: Control

Button

TextBox

ListBox

Forms

Public static void DoSometing (Control c) { // } Biz burada DoSometing fonksiyonun da Form nesnesini de , ListBox nesnesini de, TextBox nesnesini de, Button nesnesini de parametre olarak geirebiliriz. DoSometing fonksiyonu, parametre olarak geirilen nesneler farkl olsa bile onlarn Control ksmna ilikin ilemler yapar. Windows iletim sisteminde ekranda bamsz olarak kontrol edilebilen dikdrtgensel alanlara pencere denilmektedir. Pencerenin tr ne olursa olsun, onlarn eitli ortak zellikleri vardr. te Control snf, tm farkl pencerelerin pencerelik zellii ile ilgili ortak zelliklerini iermektedir. rnein; her pencerenin bir zemin rengi sz konusudur. Zemin renginin deitirilmesine izin veren eleman Control snfnn eleman olmaldr. System.Object SINIFI System isim alan ierisinde Object snf .Net snf sistemi iin ok nemli bir snftr. Bu snf ok kullanld iin object anahtar szc ile de temsil edilmektedir. Bu durumda bu snf belirtmek iin Using.System direktifinden Object ismini kullanabiliriz, System.Object ismini kullanabiliriz ya da object ismini kullanabiliriz. C# ta tpk Java da olduu gibi her snf 113

dorudan ya da dolayl olarak object snfndan tretilmitir. Biz bir snf tanmlarken, hi tretme yapmam olsak bile derleyici yine de o snfn object snfndan tretildiini varsayar. C# ta object snfndan tretilmemi bir snf oluturmak mmkn deildir. rnein: class Sample { // } Burada hibir tretme syntax kullanlmamtr. Fakat derleyici yine de Sample snfnn object snfnda tretildiini varsayar. Tabi biz snf aka object snfnda tretebiliriz. Bu yasak deildir. Fakat gereksizdir. rnein: class Sample : object { // } Burada zaten :object yazlmasa da sanki yazlm gibi ilem grecektir. Her snfn ister istemez object snfndan tretilmi olmas, C# ve Java gibi dillerde baz kolaylklar salamaktadr. C++ gibi dillerde byle bir kolaylk ngrlmemitir. Her snf object snfndan tretildiine gre aslnda her snf nesnesinin bir object ksm da vardr. Fakat biz bugne kadar izimlerde bu durumu dikkate almamtk. Bundan sonrada izimlerde bu durum dikkate alnmayacaktr. rnein; B snf A snfndan tretilmi olsun. Aslnda A snf da object snfndan tretilmitir. Gerek izimin yle olmas gerekirdi:
Objec dat

B b = new B();

b
Adat Bdat

b nesnesi

object snfnn Equals, GetHashCode, GetType, ToString gibi static olmayan, Equals, ReferenceEquals isimli static olan fonksiyonlar vardr. Bu fonksiyonlar daha sonra ele alnacaktr. Madem ki her snf object snfndan tretilmitir, o halde her snf trnden referans object snfna atanabilir. rnein: Sample s = new Sample(); object o; 114

o = s; //geerli TREM SINIFLARDA BALANGI FONKSYONLARININ ARILMASI Balang fonksiyonlarnn temel amac, snfn veri elemanlarna bir takm gvenli ilk deerler vermektir. Tremi snf trnden bir nesne new operatr ile yaratldnda, tremi snfn balang fonksiyonu arlr. Tremi snfn balang fonksiyonu, tremi snf veri elemanlarna ilk deerlerini verebilir. Fakat taban snfn private blmne eriemediine gre taban snfn elemanlarna ilk deerleri veremeyecektir. Halbuki taban snf veri elemanlarna da ilk deerlerin verilebiliyor olmas gerekir. te tremi snfn balang fonksiyonu, taban snfn balang fonksiyonunu otomatik olarak armaktadr. Bylece new operatr ile tremi snf trnden bir nesne yaratldnda, tremi snfn balang fonksiyonu arlr. Tremi snfn balang fonksiyonu da, taban snfn balang fonksiyonunu aracaktr. Tremi snf balang fonksiyonunun hangi taban snf balang fonksiyonunu araca :base syntax ile belirtilir. :base syntax tremi snf balang fonksiyonlarnn kapan parantezinden sonra yerletirilir. Genel biimi aadaki gibidir: :base ([ parametre listesi ]) Base syntax hi belirtilmeyebilir. Bu durumda sanki :base() belirtmesi yaplm gibi kabul edilir. Yani base syntax belirtilmemise taban snfn default balang fonksiyonu arlr. :base syntaxnn parametre parametreleri kullanlabilir. rnein: listesinde, balang fonksiyonu

class A { // } class B:A { public B() { // } public B(int a) : base (a) { // } public B(int A, int B) : base (a) { // } } 115

:base syntax yalnzca balang fonksiyonlarnda kullanlabilir. Herhangi bir fonksiyonda kullanlmaz. Balang fonksiyonu altrlma sras nce, taban snf sonra tremi snf biimindedir. Taban snfn balang fonksiyonun arlmas, derleyicinin tremi snf balang fonksiyonunun ana blounun bana yerletirdii gizli bir kod yoluyla yaplmaktadr. arlma srasnn nce taban sonra tremi olmasnn gerekesi ak tremi snf balang fonksiyonuna geldiinde burada taban snf veri elemanlar ya da fonksiyonlar kullanldnda, taban snf veri elemanlarnn ilk deerlerini alm olmas gerekliliidir. Anahtar Notlar Bir snfn dorudan taban snf, onun bir yukarsndaki taban snftr. Snfn dier taban snflarna dolayl taban snflar denilmektedir. rnein; A B C C in dorudan taban snf B, B nin A, A nn object snfdr. :base syntaxnda dorudan taban snf belirtilmektedir. Bir dizi tretme yapldnda, balang fonksiyonlarnn arlma sras en tepeden aaya dorudur. rnein: A C c = new C(); B C Burada C snfnn balang fonksiyonu arlacaktr. Fakat balang fonksiyonunun ana blounun banda ak B snfnn balang fonksiyonuna oradan da A snfnn balang fonksiyonuna gidecektir. O halde balang fonksiyonu arlma sras A,B,C eklindedir. Bir snf iin bir balang fonksiyonu yazdmzda derleyici artk default balang fonksiyonunu yazmaz. Bu durumda aadaki rnekteki gibi error oluur: class A { public A(int a) { 116

// } // } class B:A { public B() error { // } // } Tremi snf iin hibir balang fonksiyonu yazmam olalm. Derleyicinin ii bo olarak yazaca default balang fonksiyonunu, taban snfn default balang fonksiyonunu aracak ekilde yazlacaktr. rnein: class A { public A() { // } // } class B:A { // } B b = new B(); Burada A nn balang fonksiyonu altrlacaktr. Yukardaki anlatmlarda object snfnn balang fonksiyonundan bahsedilmemitir. phesiz en nce object snfnn balang fonksiyonu arlmaktadr. SINIF BLDRM ERSNDE VER ELEMANLARINA LK DEER VERLMES Snfn veri elemanlarna snf bildirimi ierisinde ilk deer verilebilir. rnein: class Sample { private int a = 10; private int b = 20; //... }

117

Derleyici verilen bu ilk deerleri srasyla atama deyimlerine dntrerek snfn her balang fonksiyonunun bana yerletirir. Bu ilem, snfn pek ok balang fonksiyonu olduunda ve her balang fonksiyonunda, veri elemanlarna ayn deerlerin atanmas istendiinde pratik olabilmektedir. phesiz programc ayrca balang fonksiyonunda bu deikenlere deer atarsa, onun atad deerler kalacaktr. Atama deyimlerinin yerletirilme sras bildirimdeki sraya gre yaplmaktadr. using System; using System.IO; namespace CSD { class App { public static void Main() { Sample s = new Sample(100); Console.WriteLine(s.a); Console.WriteLine(s.b); Console.WriteLine(s.name); } } class Sample { public int a = 10; public int b = 20; public string name = "Savas"; //... public Sample(int x) { a = x; } } } SINIFIN BAKA SINIF TRNDEN REFERANS VER ELEMANLARINA SAHP OLMASI Bir snf baka snf trnden veri elemanlarna sahip olabilir. Bu durumda elemana sahip snfn balang fonksiyonu ierisinde, eleman iin new operatr ile tahsisat yaplmaldr. Tabi bu tahsisat veri elemanna ilk deer verme eklinde de yaplabilir. rnein: class A { //... } class B { 118

private A a; int b; public B() { a = new A(); b = 10; } //... } B r = new B();

r a b B nesnesi phesiz ayn ilem yle de yaplabilir: class A { //... } class B { private A a = new int b = 10; public B() { } } B r = new B();
. . . . . .

A nesnesi

A();

buras farkl

NULL REFERANS KAVRAMI Tpk dier trlerde olduu gibi referanslar da henz kendilerine deer atanmadan herhangi bir biimde kullanlamazlar. rnein: Sample a; a.Func(); error

null anahtar szc bo bir adres belirtmektedir. Her trl referansa dorudan atanabilir. Bir referansa null atanmsa, o referansa deer atanmtr fakat referans hibir nesneyi gstermiyor durumdadr. erisinde null deer tayan bir referans kullanlrsa, derleme ilemi baaryla 119

sonulanr fakat programn alma zaman srasnda exception oluur. Oluan bu exception programn kmesine neden olur. rnein: Sample a; a = null; a.Func(); Derleme aamasn geer fakat alma zaman srasnda exception oluur. Bir referansn ierisinde null olup olmad == ve != operatrleri ile test edilebilir: if (a == null) { //... } if (a != null) { //... }

null referans bir nesneyi p toplayc iin seilebilir duruma getirmek iin kullanlabilir: Sample a = new Sample(); //... a = null; // Nesne p toplayc tarafnda seilebilir durumda!

new operatr tahsisat yaptktan sonra, snfn temel trden veri elemanlarna 0, referans trden veri elemanlarna ise null deerini yerletirir. Temel trlerin ierisine null deeri atayamayz.

YAPILAR Yaplar snflara ok benzer trlerdir. Bir yap struct anahtar szc ile belirtilir. rnein: struct Foo { //... } Bugne kadar snflar hakknda sylenilen her ey burada aksi belirtilmedi ise yaplar iin de geerlidir. Yaplar kategori olarak deer trlerine ilikindir. Yani bir yap trnden deiken tanmlandnda bu bir referans deildir. Deerlerin kendisini tutan paral bir nesnedir. struct Test { public int a; public int b; 120

//... } Test t; Biz imdi dorudan t.a ve t.b elemanlarn kullanabiliriz. t.a ve t.b bamsz deikenler gibi kullanlabilir fakat tabi kullanmadan nce deer atam olmak yine bunlar iinde geerlidir. using System; using System.IO; namespace CSD { class App { public static void Main() { Test t; t.a = 10; t.b = 20; Console.WriteLine(t.a); Console.WriteLine(t.b); } } struct Test { public int a; public int b; //... } } Yap deikenleri stack ta yaratlmaktadr. Dolaysyla bunlarn yok edilmelerinin p toplayc ile bir ilgisi yoktur. Yap nesneleri programn ak nesnenin tanmlad bloktan kldnda otomatik olarak yok edilmektedir. Yaplarnda fonksiyonlar, balang fonksiyonlar olabilir. Ayn trden iki yap deikeni birbirine atanabilir. Bu durumda yapnn karlkl veri elemanlar birbirine atanacaktr. rnein: Test x; x.a = 10; x.b = 20; Test y; y = x; Burada artk y nin a ve b paralar ierisinde 10 ve 20 vardr. Yaplar iin de new operatr ile tahsisat yaplabilir. Fakat bu durum snflar iin tahsisat yaplmasndan farkl bir anlam ifade eder. new 121

operatrnn operand bir yap ise new operatr nce stack ta ilgili yap trnden geici bir deiken oluturur. Sonra belirtilen balang fonksiyonu arlr. new operatrnden rn olarak stack ta yaratlm geici nesne elde edilir. Elde edilen bu rn ayn trden bir yap deikenine atanabilir. Bu geici yap nesnesi, ilgili ifade bittiinde otomatik derleyici tarafndan yok edilir. Tabi atanan deikende bu deerler kalacaktr. rnein: struct Test { private int a; private int b; public Test(int x, int y) { a = x; b = y; } public void Disp() { Console.WriteLine(a); Console.WriteLine(b); } //... } Test t; T = new Test(10,20); t.Disp(); Yaplar iin hibir zaman programc default balang fonksiyonu yazamaz. Her zaman default balang fonksiyonunu derleyici yazar. Derleyici yaplar iin default balang fonksiyonunu, programc herhangi bir balang fonksiyonu yazsa da yazmasa da her zaman yazmaktadr. (halbuki snflar iin eer biz hi balang fonksiyonu yazmamsak, derleyici default balang fonksiyonu yazmaktadr). Derleyicinin yazd default balang fonksiyonu yapnn tm elemanlarn sfrlamaktadr. Anmsanaca gibi snflar iin new operatr kullanldnda, new operatr heap ta tahsisat yaptktan sonra, snfn tm temel trden elemanlarn sfrlayp, referans veri elemanlarna null yerletiriyordu. Balang fonksiyonu bu ilemden sonra arlyordu. Halbuki yaplar iin new uygulandnda, new operatrnn kendisi sfrlama yapmaz. new operatr dorudan yapnn balang fonksiyonunu arr. Sz konusu balang fonksiyonu default balang fonksiyonu ise sfrlama onun ierisinde yaplmaktadr. rnein: Test t; t = new Test(); Burada sfrlama iini new operatr deil default balang fonksiyonu yapmaktadr. Halbuki snf sz konusu olsayd new operatr yapacakt.

122

Eer programc yap iin parametreli bir balang fonksiyonu yazacaksa balang fonksiyonu bitene kadar kesinlikle yapnn her elemanna deer atam olmak zorundadr. Aksi halde derleme zamannda error oluur. Bylece bir yap iin new operatr ile tahsisat yapldnda, yaratlan geici nesnenin her eleman kesinlikle deer alm olmak durumdadr. Aslnda bu durum snflar iin de byledir. Fakat snflarda bu ilem, balang fonksiyonu yoluyla deil new operatr ile salanr. Bir yap hibir yap yada snftan tretilemez. Yani yaplar tretmeye kapaldr. Bu nedenle yaplarda : tretme syntax kullanlamaz. Fakat derleyici tm yaplarn System isim alanndaki ValueType snfnda tretildiini varsayar. ValueType snf da Object snfnda tretilmitir. System.Object

System.ValueType Herhangi Bir ey Benzer biimde bir yap, bir yapya yada snfa tabanlk ta yapamaz. Bir yap protected ve protected internal elemanlara sahip olamaz. Zaten yaplarda tretme yaplamadna gre bunlar iin protected ve protected internal elemanlarn da bir anlam olmayacak. TEMEL TRLERE LKN YAPILAR C# ta daha nce temel trler olarak grdmz int, long, double gibi trler aslnda birer yap belirtmektedir. rnein; int tr aslnda System.Int32 denen yapy, long tr System.Int64 denen yapy gstermektedir. rnein: int a bildirimi ile System.Int32 bildirimi tamamen ayndr. Madem ki temel trler aslnda birer yapdr System.ValueType snfndan tretilmitir. o halde bu trlerde

SINIF ELEMANI OLARAK YAPILARIN KULLANILMASI Bir yap eer yerel bir deikense stack ta yaratlr. Yoksa bir snfn eleman olduu zaman kendisi de snf nesnesi ile birlikte, snf nesnesinin bir paras olarak heapta bulunacaktr. rnein:

struct Foo { public int a; public int b; 123

//... } class Bar { private int x; private Foo y; //... } //... Foo foo = new Foo() stacta yaratm yaplyor. Bar bar; bar = new Bar(); heapta yaratm

Yukardakinin tersi bir durum yani bir yapnn elemannn, bir snf referans olmas durumu da geerli ve normaldir. Bu durumda eer yap nesnesi yerel bir biimde yaratlmsa, yaratm stack ta yaplr. Fakat eleman olan snf referans heapta bir nesneyi gsterecektir. rnein: class Foo { private int a; private int b; //... } struct Bar { private int x; private Foo y; public Bar(int x) { this.x = x; y = new Foo(); //.. } //... } { Bar bar = new Bar(10); //... } Burada programn ak, yap nesnesinin tanmland blou bitirdiinde heap ta tahsis edilmi olan snf nesnesi de p toplayc tarafndan seilir duruma gelir. KUTULAMA DNTRMES(Boxing Corversion) Bir referans hibir zaman stack taki bir nesneyi gstermez. Her zaman heaptaki bir nesneyi gstermek zorundadr. Bir yap, onun taban snf olan 124

ValueType yada Object trnden snflara dorudan atanabilir. Fakat bu durumda referans stack taki yapy gsteremeyeceine gre ne olacaktr? te ne zaman bir yap deikeni ValueType yada object referanslarna atansa, derleyici otomatik olarak o yap nesnesinin heapta bir kopyasn oluturur ve bu referans heaptaki bu nesneyi gsterir durumda olur. Otomatik yaplan bu ileme kutulama dntrmesi denir. { int a = 10; object o; o = a; //... } stack o heap
a nn kopyas
10

Burada o = a ilemi ile derleyici a nn heapta bir kopyasn oluturur. o artk heaptaki kopyay gsterir durumdadr. Bu ilemden sonra artk stack taki a ile heaptaki kopyas bamsz iki ayr nesnedir. Bu ilemden sonra artk biz rnein stack taki a y deitirsek bu ilemden heaptaki a etkilenmez, heaptaki a y deitirsek stack taki a etkilenmez. Stack taki a, ak bloktan ktktan sonra otomatik olarak, heaptaki a ise p toplayc tarafndan yok edilecektir. phesiz o referans heaptaki a nn object ksmn gstermektedir. AAIYA DORU YAPILAN DNTRMELER Anmsanaca gibi tremi snf referansndan taban snf referansna dorudan atama yani dntrme vardr. Fakat taban snf referansn dorudan tremi snf referansna atayamayz. Bu ilemi ancak tr dntrme operatr ile yapabiliriz. rnein: B b = new B(); A a; a = b; //geerli B x; x = a; //error x = (B)a; //geerli 125

B phesiz dorudan yaplan her atama ayn zamanda tr dntrme operatr ile de yaplabilir. Aralarnda tretme ilikisi olmayan iki snf arasnda tr dntrme operatr ile de dntrme yaplamaz. rnein: A

B b = new B(); C c; C = (B)c; error Burada B ile C arasnda bir tretme ilikisi yoktur. O halde B ile C arasnda biz tr dntrme operatr ile de dntrme yapamayz. Tabanda tremie dntrme(down_cast) ilemi derleyici tarafndan her zaman kabul edilir. Ancak bu ilem ayrca programn alma zaman srasnda da CLR tarafndan kontrol edilmektedir. CLR ak dntrmenin yapld blme geldiinde dntrlecek referansn gsterdii yerdeki nesnenin ierisinde, dntrlecek tre ilikin bir blmn olup olmadna bakar. Eer byle bir blm varsa dntrme hakldr ve sorun kmaz. Eer byle bir blm yoksa, dntrme hakszdr ve alma zaman srasnda InvalidCastException ortaya kmaktadr. Bu da programn kmesine yol aar. rnein: A

C c = new C(); A a; a = c; //geerli B b; b = (B)a; //derleme aamasn geer fakat alma zamannda exception oluur. c Adat 126 a

Yukardaki kod baarl bir biimde derlenecektir. Fakat ak b = (B)a blmne geldiinde a referansnn gsterdii yerdeki nesnede B datalar olmad iin dntrme hakszdr. CLR exception oluturacaktr. Aslnda burada programc araya taban bir snf sokarak C den B ye dntrme yapmak istemitir. Derleyici kandra bilmitir ama CLR durumu tespit etmitir. rnein: A

C A B b

c = new C(); a = c; //geerli b; = (B)a; //hakl dntrme c Adat Bdat a Cdat

Burada b = (B)a dntrmesi hakl bir dntrmedir. nk a referansnn gsterdii yerde B trnden datalar vardr. Grld gibi bir referans taban snf trnde bir referansa atayp onu yeniden tremi snf trne dntrrsek bu dntrme her zaman hakl bir dntrme olur. Grld gibi yukarya doru dntrme her zaman geerlidir. Fakat aaya doru dntrme ancak tr dntrme operatr ile yaplabilir ve ayrca programn alma zaman srasnda CLR tarafndan da denetim uygulanmaktadr.

127

Anahtar Notlar Baz programclar snfn veri elemanlarnn m_ ya da d_ gibi neklerle balatarak isimlendirmektedir..... Bylece akma durumunda this anahtar szcn kullanmaya gerek kalmaz. Ayn zamanda bu neklerle balayan isimlerin veri eleman olduu anlalabilir. Kursumuzda baz rneklerde m_ neki de kullanlacaktr. KUTUYU AMA DNTRMES(UNBOXING CORVERSATION) Kutulama dntrmesi ile heape aktarlan bir yap, sonra yeniden aaya doru dntrme yaplarak stacka ekilebilir. Tabi aaya doru dntrme iin tr dntrme operatrnn kullanlmas gerekir. System.ValueType ya da System.Object trnden bir referans, o referansn ilikin olduu yapya dntrmeye altmzda, stackta dntrlecek yap trnden bir geici yap nesnesi oluturulur. Heapte bulunan bu yap nesnesi, stacktaki bu geici nesneye kopyalanr. lgili ifade bittiinde stacktaki bu geici nesne yok edilir. Bu ileme kutuyu ama dntrmesi denilmektedir. rnein: int a = 100; object o = a; //... int x; x = (int)o; kutuyu ama dntrmesi Burada x = (int)o ilemi ile nce stackta geici bir deiken yaratlr. Sonra o referansnn grd yerdeki nesne, bu geici nesneye kopyalanr. x = (int)o ilemi ile ierisinde 100 deeri olan bir geici deiken elde edilir. public static void Main() { int a = 100; object o = a; int x = (int) o; Console.WriteLine(x); } Kutuyu ama dntrmesinde bilinli dntrme, eer farkl trden bir yapya uygulanrsa (temel yap trleri de dahil olmak zere) programn alma zaman srasnda exception oluur. rnein: public static void Main() { int a = 100; object o = a; long x = (long) o;
derleme aamasn geer ,alma srasnda exception oluur.

128

Console.WriteLine(x); } phesiz kutulama dntrmesi sabitler ile de gerekletirilir. rnein: object o = 123; Burada yine heapte int trden bir deiken yaratlr, 123 deeri bu deikenin ierisine atanr, o referans da artk heapteki bu nesneyi gsteriyor durumda olur. Bu deeri kutuyu ama dntrmesi ile geri alabiliriz. rnein: object o = 123; int x; x = (int) o; rnein object trnden bir diziye kutulama dntrmesi yoluyla eitli deerler atayabiliriz. Sonra foreach dngs ile bunlar geri alabiliriz. Anmsanaca gibi foreach dngs, her yinelemede dizilimin bir elemann tr dntrmesi yoluyla dng deikenine atamaktadr: object [] obj = new object [] {10,20,30,40,50}; foreach (int x in obj) { Console.WriteLine(x); }

collection SINIF KAVRAMI Amac birden baka snf nesnelerini tutmak olan snflara collection snf denilmektedir. rnein; dizilerde bir bakma collection snflardr. .Net ierisinde pek ok collection snf vardr. Bu snflar System.Collection isim alannda bulunmaktadr. DZLERN TRETME DURUMLARI Aslnda diziler de birer snf olarak deerlendirilebilir. .Nette btn dizilerin tr ne olursa olsun System.Array isimli snftan tretildii varsaylmaktadr. System.Array snf da System.Object snfndan tretilmitir.

129

System.Object

System.Array

Herhangi trde bir dizi

Yani biz herhangi bir dizi referans ile System.Array snfnn yada Object snfnn elemanlarna eriebiliriz. Aslnda dizinin uzunluunu elde etmekte kullandmz Lenght isimli property ve dizi elemanlarna ulamakta kullandmz indeksleyici System.Array snfnn elemanlardr. Madem ki tm diziler dolayl olarak object snfndan tretilmitir o halde biz bir dizi referansn object trnden bir referansa atayp geri dntrebiliriz. rnein: { int [] a = {1,2,3,4,5}; object o = a; int b[] = (int []) o; foreach (int x in b) Console.WriteLine(x); }

ArrayList Collection SINIFI Aslnda dizilerde birer collection snfdr. Fakat baz gereksinimleri karlamakta diziler yetersiz kalmaktadr. rnein; bir dizi am olalm ve bir kaynaktan gelen bilgileri diziye ekleyelim. Dizi dolunca ne olacaktr? C# ta diziler bytlemez. te bu durumda tek seenek daha byk yeni bir dizi tahsis etmek, eski dizideki elemanlar yeni diziye kopyalamak ve yeni diziden ileme devam etmektir. Bu yeni dizi de taarsa bu ilemleri yinelemek gerekir. in banda ok byk dizi tahsis etmek bellein verimsiz kullanlmasna yol aar. te C# ta bu tr durumlarla ok sk karlalmaktadr. Bu tipik duruma dinamik olarak byyen dizi denilmektedir. 130

Anahtar Notlar Bir diziyi bir diziye kopyalama basit bir for dngs ile yaplabilir. Ya da bunun iin System.Array snfnn, static Copy fonksiyonlar ya da static olmayan CopyTo kullanlabilir. public static void Copy destinationArray, int length) (Array SourcaArray, Array

Fonksiyonun birinci parametresi kaynak diziyi, ikinci parametresi hedef diziyi ve nc parametresi dizinin kopyalanacak eleman saysn almaktadr. rnein: { int [] a = new int [5] {1,2,3,4,5}; int [] b = new int [10]; Array.Copy(a,b,5); foreach (int x in b) Console.WriteLine(x); } Ayn ilem static olmayan Copyto fonksiyonu ile de yaplabilir. public void CopyTo(Array array, int index) Fonksiyonun birinci parametresi hedef diziyi, ikinci parametresi kopyalamann hedef dizinin hangi indeksinden itibaren yaplacan belirtir. Yani kaynak dizinin tm elemanlar hedef dizinin belli bir indeksinden itibaren kopyalanabilir. rnein: { int [] a = new int [5] {1,2,3,4,5}; int [] b = new int [10]; a.CopyTo(b,0); foreach (int x in b) Console.WriteLine(x); } ArrayList snf dinamik bytlen bir diziyi temsil etmektedir. Snfn ierisinde muhtemelen private blmnde object trnden bir dizi vardr. Snf kendi ierisinde ayrca count ve capacity biiminde iki bilgi de tutmaktadr. Bu bilgiler Count ve Capacity isimli property elemanlarla ulalabilir. Capacity snfn iindeki object dizisi iin ka elemanlk yer tahsis edildiini gsterir. Count ise o anda dizinin ka elemannn dolu olduunu belirtmektedir. Snfn object parametreli bir Add fonksiyonu vardr. Bu fonksiyon alnan, deeri Count ile belirtilen indekse yazar ve Count deerini bir arttrr. Count deeri Capacity e geldiinde Add fonksiyonu kendi 131

ierisinde eski Capacity deerinin iki kat kadar yeni bir dizi tahsis eder ve ilemlere bu yeni diziden devam eder. ArrayList snfnn indeksleyicisi olduu iin istenilen eleman keli parantez operatr ile geri alnabilir. ArrayList snf elemanlar object gibi tutar ve yine bize objectmi gibi verir. rnein: { ArrayList al = new ArrayList(); for (int i = 0; i < 100; ++i) al.Add(i); for (int i = 0; i < al.Count; ++i) { int x = (int) al[i]; Console.WriteLine(x); } }

Add fonksiyonunun parametrik yaps yledir: public virtual int Add(object value) Fonksiyon parametre olarak yerletirilecek eleman alr, geri dn deeri olarak elemann yerletirildii indeksi verir. Keli parantez ile elde edilen deer object trndendir. Grld gibi biz ArrayList ierisinde int trnden deerleri saklamak istediimizde aslnda ArrayList kutulama dntrmesi ile onu object trne dntrmekte ve onu object olarak saklamaktadr. Foreach deyimi aslnda Ienumerable arayzn destekleyen her trl snfta kullanlabilir. Diziler de ArrayList snf da Ienumerable arayzn desteklemektedir. O halde foreach deyimi ArrayList snf ile kullanlabilir. rnein: { ArrayList al = new ArrayList(); for (int i = 0; i < 10; ++i) Al.Add(i); foreach (int x in al) Console.WriteLine(x); }

132

ArrayList snfnn Insert isimli fonksiyonu, belirli bir deeri o deer ArrayList ierisindeki dizide belirli bir indekste olacak ekilde ekleme yapar. public virtual void Insert (int index, Object value) Fonksiyonun birinci parametresi Insert ileminin yaplaca indexi ikinci parametresi Insert yaplacak deeri belirtmektedir. phesiz bu fonksiyonda ArrayList ierisindeki dizide bir kaydrmaya yol amaktadr. using System; using System.Collections; namespace CSD { class App { public static void Main() { ArrayList al = new ArrayList(); for (int i = 0; i < 10; ++i) al.Add(i); al.Insert(3, 100); foreach(int x in al) Console.WriteLine(x); } } } ArrayList.RemoveAt fonksiyonu belirli bir indeksteki deeri silmek iin kullanlr. Fonksiyon parametresi ile belirtilen indeksteki deeri silmektedir. phesiz silme ilemi srasnda bir sktrma ilemi yaplmaktadr. (ArrayList snfnda eleman sildiimiz zaman Capacity deeri hibir zaman kltlmemektedir.) ArrayList snfnn Reverse fonksiyonu elemanlar ters yz eder. Sort fonksiyonlar sraya dizme ilemi yapmaktadr. enum TR VE enum SABTLER Bazen bir fonksiyonun parametresi kstl sayda seenekten hangisinin sz konusu olduunu belirlemek iin kullanlr. rnein; bir ekli hareket ettiren MoveShape isimli fonksiyon eklin hangi ynde hareket ettirileceini belirlemek iin bir yn parametresi almaktadr. void MoveShape (int direction) { //... } 133

Burada parametre olan yn bilgisi int tr ile temsil edilmi olmasna karn kstl sayda deer almaktadr. phesiz fonksiyonun parametresini string yapmak daha okunabilir bir durum oluturur. Fakat tamsaylarla almak her zaman daha hzldr. rnein: MoveShape(3); Daha hzl fakat daha az okunabilir. MoveShape(Left); Daha okunabilir fakat daha yava. Haftann gnleri, aylar, meyveler, klavyedeki tular gibi pek ok bilgi aslnda int trden bir say ile temsil edilebilir. Fakat hangi saynn hangi kavram belirttii, kodu inceleyen kii tarafndan doal olarak bilinmediinden dolay int gibi bir tamsay ile temsil ilemi okunabilirlii azalmaktadr. Bir enum bildiriminin genel biimi yledir: enum <isim> { S1, S2, S3... } rnein: enum Gnler { Pazartesi, Sali, Carsamba, Persembe, Cuma, Cumartesi, Pazar } Bir enum sabiti, enum ismi ve . operatr ile kullanlr. rnein: Gnler.Pazar;

134

rnein: enum Directions { Up, Down, Left, Right } Direction.Up Her enum sabiti aslnda bir say belirtmektedir. lk enum sabiti 0 olmak zere her enum sabiti ncekinden bir fazla deer belirtmektedir. Yani Direction.Up 0 Direction.Down 1 Direction.Left 2 Direction.Right 3 Her enum ayr bir tr belirtir ve enum sabitleri ilikin olduu enum trndendir. rnein: Direction.Up ifadesi Direction isimli bir enum trndendir. Gnler.Sali ifadesi Gnler isimli enum trndendir. Bir enum trnden deikin tanmlanabilir. rnein: Direction d; Gnler g; d = Direction.Up g = Gnler.Sali enum trleri kategori olarak deer trlerine ilikindir. Yani tpk int trnde olduu gibi enum trnden bir deikenin ierisine bir adres bilgisi deil deerin kendisi yerletirilir. Her ne kadar enum tr aslnda bir tamsay tr ise de temel trlere ilikin bir deer dorudan bir enum trne atanamaz. rnein: Direction d; d = 2; error Ayn trden iki enum tr birbirine atanabilir. rnein: Direction d; d = Direction.Up; geerli Direction x; x = d; geerli te bir bilginin hem saysal olmasn hem de okunabilir bir biimde ifade edilmesini istiyorsak enum kullanmalyz. rnein:

void MoveShape(Direction d) { //... } 135

//... MoveShape(Direction.Left); Bir enum sabitine eittir ile bir deer verilebilir. Bu durumda onu izleyen enum sabiti bir ncekine verilen deerin bir fazlas olur. Ayrca iki farkl enum sabiti ayn saysal deerde de olabilir. rnein: enum Test { XX, YY = 10, ZZ, KK = -1, MM } Burada XX = 0 , YY = 10, ZZ = 11, KK = -1, MM = 0 deerdedir. Enum sabitine verilen ilk deer sabit ifadesi olmaldr. nceki enum sabitleri kullanlabilir. rnein: enum Test { XX, YY = XX + 2 } switch parantezinin ierisinde enum trnden bir ifade olabilir. Bu durumda case ifadeleri enum trnden olmaldr.
Directions d = GetSomeDirection(); Switch (d) { case Directions.Up //... break; case Directions.Right //... break; //... } static Directions GetSomeDirection() { return Directions.Right; } enum Direcitons { Up,Down,Left,Right }

Aslnda ou kez bir enum sabitinin hangi deerde olduu programcy ilgilendirmemektedir. Programc enum sabitinin isminden hareketle ne olacan tahmin edebilmektedir. Her enum trnn ilikin olduu karde bir 136

tamsay tr vardr. Karde tamsay tr : syntax ile belirtilir. Eer bu syntax kullanlmazsa karde tamsay tr int anlalr. rnein: enum Foo { XX, YY } enum Bar : long { MM, ZZ } enum trlerinden tamsay trlerine, tamsay trlerinden enum trlerine dorudan atama yaplamaz. Fakat tr dntrme operatr ile atama yaplabilir. Tr dntrme operatr kullanldnda oluacak durum, enum trnn ilikin olduu karde tamsay trnn, ilgili tamsay trne dntrlmesi srasnda oluan durumla ayndr. Dntrme sonucunda enum trnn ierisindeki saysal deer elde edilir. rnein: static Directions GetSomeDirection() { Directions d = Directions.Right; long i; i = d; // error i = (long)d; } (long)d dntrmesinde Directions isimli enum trnn ilikin olduu tamsay tr int ise, int trnden long trne dntrme kurallar uygulanr. Grld gibi d ifadesi Directions trndendir. Fakat (long)d ifadesi long trdendir. Grld gibi bir enum trnden deerin belirttii tamsay deeri istenildii zaman tr dntrme operatr ile elde edilebilir. Enum trnden bir deer Console snfnn Write ve WriteLine fonksiyonlar ile yazdrlabilir. Fakat bu durunda enum deerine ilikin saysal deil yazsal bilgi ekrana baslr.rnein: Directions d = Directions.right; Console.WriteLine(d); Console.WriteLine((int)d); Right 3 geerli i de 3 var

Enum Directions (class dna yaz) { 137

Up, Down, Right, Left } Bir tamsay trnden deer de, tr dntrme operatr ile bir enum trne dntrlebilir. Bu durumda nce dntrlecek deer, enum trnn ilikin olduu karde tamsay trne dntrlr. Sonra dntrlm olan bu deer, ilgili enum trne dntrlr. Ayrca enum trnden bir deikenin kendi trnden bir enum sabitinin deerini tutmas zorunu deildir. rnein: long x = 1234567; Directions d; d = x; error d = (Directions)x; geerli Burada (Directions)x dntrmesi srasnda nce long trden int tre dntrme kural uygulanr. Yani herhangi bir kayp olumayacaktr. Daha sonra int trne dntrlen bu deer Directions trne dntrlecektir. imdi artk d nin ierisinde saysal olarak 1234567 deeri vardr. phesiz burada biz d deikeninin ierisindeki deeri Console snfnn Write ve WriteLine fonksiyonlar ile yazdrmaya alsak ekrana bir yaz baslamayacana gre say baslacaktr. .Net snf ktphanesinde enum tr ok sk kullanlr. rnein DateTime isimli yapnn DayOfWeek isimli property eleman DayOfWeek isimli bir enum trndendir. DayOfWeek isimli enum trnn elemanlar da haftann gnlerini barndrmaktadr. Bugnn hangi gn olduu u ekilde yazdrlabilir: DayOfWeek dow = DateTime.Today.DatOfWeek; Console.WriteLine(dow); MSDN dokmanlarnda DayOfWeek isimli enum trnn Sunday isimli elemanndan Saturday elemanna kadar olan deerlerin 0 ile 6 arasnda olduu belirtilmitir. Eer gnleri Trke yazdrmak istersek switch kullanabiliriz. switch (DateTime.Today.DayOfWeek) { case DayOfWeek.Sunday: C.W.(Pazar); break; //... } Ayn ilem yle de yaplabilirdi:

138

string [] days = {Pazar, Pazartesi, Perembe, Cuma, Cumartesi}; int index = (int) dateTime.Today.DayOfWeek; Console.WriteLine(days[index]); Anahtar Notlar

Sal,

aramba,

Bir yap ya da snfn bir elemannn ismi, o elemana ilikin tr ismi ile ayn olabilir. Bu durum karkla yol amaz. phesiz snf ya da yap ierisinde bu isim kullanlrda isim arama kuralna gre eleman olan isim anlalr. Darda kullanlrsa zaten isim niteliklendirilecei iin sorun kalmaz. rnein: enum Test { XX,YY,ZZ } class Sample { public Test Test; //... } //... Sample s = new Sample(); Test t = s.Test; geerli System.Windows.Forms isim alan ierisindeki MessageBox isimli snfn Show isimli fonksiyonlar mesaj penceresi kartmak iin kullanlr. Bir mesaj penceresinin drt zellii vardr: balk yazs, pencere ierisindeki mesaj yazs, tu takm ve ikon grnts. Show fonksiyonlarndan biri yledir: public static DialogResult MessageBoxButtons buttons) Show (string text, string caption,

Fonksiyonun birinci parametresi pencere ierisine yazlacak yazy, ikinci parametresi pencere balk yazsn, nc parametresi tu takm belirtir. MessgeBoxButtons isimli enum trnn elemanlar tu takm seeneklerini belirtir. Show fonksiyonunun geri dn deeri DialogResult trnden bir enumdr. DialogResult isimli enum trnn elemanlar dialog penceresinin hangi tula kapatldn belirtir. 4 parametreli Show fonksiyonunun drdnc ve son parametresi grntlenecek ikonu belirlemede kullanlr. public static DialogResult Show (string text, MessageBoxButtons buttons, MessageBoxIcon icon) string caption,

using System; using System.Collections; 139

using System.Windows.Forms; //Windows.Forms dll referans namespace CSD { class App { public static void Main() { DialogResult dr; dr = MessageBox.Show("Emin misin?", "Uyar", MessageBoxButtons.YesNoCancel); if (dr == DialogResult.Yes) MessageBox.Show("Yes"); else MessageBox.Show("No"); } } }

enum TRLER ZERNE LEMLER Ayn trden iki enum ==, !=, <,>, >=,<= operatrleri ile karlatrlabilir. Bu durumda aslnda o enum deerlerinin belirttii tamsay karlatrlmaktadr. Bir enum deeri ile o enum trnn ilikin olduu karde tamsay trne ilikin yada karde tamsay trne dorudan dntrlebilen bir deer toplanabilir. lem sonucunda ilgili enum trnden bir deer elde edilir. e E isimli bir enum trnden, u da bu enum trnn ilikin olduu U trnden ya da U trne dorudan dntrlebilen bir trden olsun. Bu durumsa e + u ya da u + e ilemi geerlidir. ilem sonucunda (E)((U)e + (U)u) sonucu elde edilir. rnein: enum Test { XX, YY, ZZ } //... Test x = Test.XX; Test y; y = x + 1; Burada y nin ierisinde tamsay olarak 2 deeri bulunmaktadr. Ayn trden iki enum operatr ile kartlabilir. Elde edilen deer enum trnn ilikin olduu karde tamsay trndendir. Yani e1 ve e2 ayn trden iki enum deeri olsun. U da bu enum trnn ilikin olduu tamsay tr olsun. (U)e1 (U)e2 ile edeerdir. rnein: enum Test { 140

XX, YY, ZZ } //... Test x = Test.YY; Test y = Test.XX; int result; result = x-y; result deikeninde 1 deeri bulunacaktr. Bir tamsay deerinden bir deerinden o enum trnn ilikin trne dorudan dntrlebilen ilgili enum trnden olur. Yani e edeerdir. enum deeri karlamaz. Fakat bir enum olduu tamsay trnden yada o tamsay bir deer kartlabilir. Elde edilen sonu u ilemi (E)((U)e (U)u) ilemi ile

Bir enum trnden deiken ++ yada -- operatr ile nek yada sonek biiminde kullanlabilir. Bu durumda enum trnden deikenin ierisinde nceki deerinin bir fazlas ya da bir eksii bulunacaktr. Ayn trden iki enum birbiri ile toplanamaz. Enum trleri herhangi bir trden tretilemez ve enum trnden de tretme yaplamaz. Fakat herhangi bir enum trnn System.Enum isimli snftan tretilmi olduu varsaylmaktadr. System.Enum tr de System.ValueType snfnda tretilmitir.

System.Object

System. ValueType

System. Enum

Herhangi trde bir dizi

Bu durumda tm trlere ilikin tretme emas yledir: 141

System.object

Herhangi bir snf tr

System.ValueType

System.Array

Herhangi bir yap tr

System.Enum

Herhangi bir dizi tr

Herhangi bir enum tr

Delege LEMLER Delege (delegate) fonksiyon tutan zel bir snftr. Biz bir delegeye istediimiz bir fonksiyonu verdiimizde delege bu fonksiyonu tutar. Sonra biz delegenin tuttuu fonksiyonun arlmasn delegeden isteyebiliriz. Anahtar Notlar Aa seviyeli ele alnrsa aslnda her fonksiyonun bir adresi vardr. Bir fonksiyonun tutulmas fonksiyonun kodlarnn deil adresinin tutulmas anlamndadr. Adresini bildiimiz bir fonksiyonun arlmasn salayabiliriz. Delege snf bildiriminin genel biimi yledir: delegate <geri dn parametre bildirimi ]); rnein: delegate void Foo(); delegate int Bar(int a, int b); Grld gibi delege snf bildirimi sanki bir fonksiyon bildirimi gibi yaplmaktadr. Fakat aslnda yukardaki rnekte Foo ve Bar birer snftr. Delege snf terimi ile delege ayn anlamda kullanlacaktr. Delegeler kategori olarak referans trlerine ilikindir. Yani bir delege trnden deiken tanmlandnda o bir referanstr ve o referans heap ta delege nesnesini gstermektedir. 142 deeri tr> <delege snf isim> ([

Delege nesnesinin kendisi tpk dier snf nesnelerinde olduu gibi new operatr ile yaratlr. Bir delege snf her trden fonksiyonu tutmaz. Ancak geri dn deerinin tr ve parametrelerin tr uygun olan fonksiyonlar tutar. rnein: delegate void Foo(); Burada Foo isimli delege snf static olsun yada olmasn geri dn deeri void olan ve parametresi olmayan fonksiyonlar tutar. rnein: delegate int Bar(int a, int b); Burada Bar isimli delege snf, geri dn deeri int, parametre trleri int,int olan fonksiyonlar tutar. Delege bildiriminde parametre deiken isimlerinin hibir nemi yoktur. Yani delegenin tutaca fonksiyonun parametre deikenlerinin isimleri bildirimdeki ile uyumak zorunda deildir. Her delege snfnn, tutulacak fonksiyonu parametre olarak alan bir balang fonksiyonu vardr. Delege snflarnn default balang fonksiyonlar yoktur. rnein: delegate void Proc(); //... Proc p = new Proc(); error balang fonksiyonlar yoktur. Proc p = new Proc(Sample.Func); delege snflarnda default

geerli

d bir delege referans olmak zere, bu delege referans d(...) biiminde fonksiyon arma operatr ile kullanlabilir. Bu durumda delegenin tuttuu fonksiyonlar arlr. arma ifadesinden arlan gerek fonksiyonun geri dn deeri elde edilir. using System; using System.Collections; using System.Windows.Forms; //Windows.Forms dll referans namespace CSD { class App { public static void Main() { Proc p = new Proc(Sample.Func); p(); } } delegate void Proc(); 143

class Sample { public static void Func() { Console.WriteLine("Func Called"); } } } using System; namespace CSD { class App { public static void Main() { Proc p = new Proc(Sample.Add); int result = p(10, 20); Console.WriteLine(result); } } delegate int Proc(int a, int b); class Sample { public static int Add(int x, int y) { return x + y; } } }

Bir delege yaratlrken, delegenin tutaca fonksiyonun ismi niteliksiz olarak belirtilirse sz konusu fonksiyon, isim arama kuralna gre bulunan snfta aranacaktr. rnein: class App { public static { Proc d = //... } public static { return x } }

void Main() new Proc(Add);

int Add(int x, int y) + y;

144

Burada fonksiyon ismini App.Add belirmeye gerek yoktur. Bir delege static olmayan fonksiyonlar da tutabilir. Fakat static olmayan fonksiyonlar, referans.fonksiyon ismi biiminde verilmelidir. Bylece delege hem referans hem de fonksiyonu tutar. Bu fonksiyon arlaca zaman o referansla arr. rnein: using System; namespace CSD { class App { public static void Main() { Sample s = new Sample(100); Proc d = new Proc(s.Disp); d(); } } delegate void Proc(); class Sample { private int m_a; public Sample(int a) { m_a = a; } public void Disp() { Console.WriteLine(m_a); } //... } } Grld gibi d isimli delege nesnesi s referans ile birlikte Disp() fonksiyonunu tutmaktadr. d() ifadesi ile aslnda s.Disp() ilemi yaplmaktadr. Ayn trden iki delege referans + operatr ile toplama ilemine sokulabilir. Bu ilem sonucunda yeni bir delege nesnesi yaratlr. Bu yeni delege nesnesinin fonksiyon listesi iki delegenin tuttuu fonksiyonlarn birleiminden oluur. rnein: Proc d1 = new Proc(Sample.Foo); Proc d1 = new Proc(Sample.Bar); Proc d3; 145

d3 = d1 + d2; Burada d1 delegesi Sample.Foo(), d2 delegesi Sample.Bar() fonksiyonlarn tutmaktadr. d1 + d2 ilemi ile yeni bir delege nesnesi yaratlr. Bu delege nesnesinin fonksiyon listesi Sample.Foo ve Sample.Bar fonksiyonlarndan oluur. Grld gibi balangta delege nesneleri tek bir fonksiyonu tutacak ekilde yaratlmaktadr. Fakat daha sonra + operatr ile birden fazla fonksiyon tutabilen delege nesneleri oluturulabilir. Bir delege referansna fonksiyon arma operatr uygulandnda o delegenin tuttuu fonksiyonlarn hepsi sras ile arlr. Eer delegenin geri dn deeri varsa, geri dn deeri olarak, son arlan fonksiyonun geri dn deeri elde edilir. ki delege toplanrken delege referanslarndan birinde null referans varsa toplama ileminde yeni bir delege nesnesi yaratlmaz. null olmayan delegenin referans elde edilir. rnein: Proc d1 = new Proc(Sample.Foo); Proc d2 = null; d3 = d1 + d2; Bu ilemden sonra d3 ile d1 ayn delege nesnesini gsterir. Eer toplama ileminde her iki delege referans da null ieriyorsa toplama ileminin sonucunda null referans elde edilir. a += b ilemi a = a+b anlamna geldiine gre aada ilem geerlidir. Proc d = null; d += new Proc(Sample.Foo); d(); Burada d referansnn gsterdii delege nesnesi Sample.Foo() fonksiyonun tutuyor durumdadr. rnein: Proc d = null; d += new Proc(Sample.Foo); d += new Proc(Sample.Bar); d(); Burada d referansnn gsterdii delege nesnesinde hem Foo() hem de Bar() fonksiyonlar tutulmaktadr.

146

Ayn trden iki delege referans operatr ile kartlabilir. kartma sonucunda yeni bir delege nesnesi yaratlr. Yeni yaratlan delege nesnesinin fonksiyon listesinde sol taraftaki delegenin fonksiyon listesinden, sa taraftaki delege nesnesinin fonksiyon listesinin kartlmas ile elde edilen fonksiyon listesine sahip, yeni bir delege nesnesi elde edilir. rnein: d1 Foo(), Bar(); d2 Foo();

d3 = d1 d2; kartma ileminden elde edilen fonksiyonu bulunur. rnein: Proc d1 = new Proc(Sample.Foo); d1 += new Proc(Sample.Bar); Proc d2 = new Proc(Sample.Foo); Proc d3 = d1 d2; d3(); Eer kartma ileminde sol taraftaki delegenin fonksiyon listesinde, sa taraftaki delegenin fonksiyon listesi yoksa bu durumda yeni bir nesne yaratlmaz. lem sonucunda sol taraftaki delege referansnn ayns elde edilir. rnein: d1 Foo(), Bar(); d2 Tar(); delegenin fonksiyon listesinde Bar()

d3 = d1 d2; Burada kartma ileminin sonucu olarak d1 referansnn ayns elde edilir. Yani d1 ve d3 referanslarnda ayn adres bulunmaktadr. kartma ileminde sra nemlidir. Yani kartmann gereklemesi iin fonksiyonlarn ayn srada bulunmas gerekir. rnein: d1 Func1 + Func3 + Func2 d2 Func1 + Func2

d3 = d1 d2; Burada d2nin fonksiyon listesi, d1in fonksiyon listesinde ayn srada yoktur. Dolaysyla kartma ileminde d1 referans elde edilir. Sadaki delegenin fonksiyon listesi soldaki delegenin fonksiyon listesinde birden fazla kez varsa, listede en son bulunan kartlr. Yani son eklenen kartlr. rnein: d1 Func1 + Func2 + Func1 147 d2 Func1

d3 = d1 d2; Burada yeni bir delege nesnesi yaratlacaktr. Onun fonksiyon listesinde Func1 + Func2 srasnda fonksiyon bulunacaktr. kartma ileminde sa taraftaki delege referansnda null varsa yani d1 d2 ileminde d2 de null referans varsa kartma ileminde yeni bir nesne yaratlmaz. D1 referansnn ayns elde edilir. Eer soldaki operand da null varsa yada her iki operand da null varsa kartma ileminde null referans elde edilir. kartma ileminin uyguland her iki operandn da fonksiyon listesinde ayn fonksiyonlar bulunuyorsa (d1 d1 ileminde olduu gibi) yine kartma ileminden null referans elde edilir. Toplama ve kartma ileminde operandlardan biri, bir delege referans ise dieri o delegenin tutaca bir fonksiyon olabilir. Bu durumda fonksiyon, otomatik olarak bir delege nesnesi yaratlarak onun ierisine yerletirilmektedir. rnein: Proc d1 = new Proc(Sample.Foo); d2 = d1(delege) + Sample.Bar(fonksiyon) Bu ilemle aadaki edeerdir. d2 = d1 + new Proc(Sample.Bar);

using System; namespace CSD { class App { public static void Main() { Proc d1 = new Proc(Sample.Foo); Proc d2; d2 = d1 + Sample.Bar; d2(); } } delegate void Proc(); class Sample { public static void Foo() { 148

Console.WriteLine("Sample.Foo"); } public static void Bar() { Console.WriteLine("Sample.Bar"); } } }

Ayn dntrme atama ilemi iinde sz konusudur. rnein: Proc d = Sample.Foo; geerli

phesiz += yada -= operatr ile de ayn kullanm geerlidir. Proc d = Sample.Foo; d += Sample.Bar; using System; namespace CSD { class App { public static void Main() { int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; DoForEach(a, new DoProc(Display)); DoForEach(a, new DoProc(Add)); Console.WriteLine(m_total); } public static void DoForEach(int[] a, DoProc dp) { foreach (int x in a) dp(x); } public static void Display(int a) { Console.WriteLine(a); } public static void Add(int a) { m_total += a; } private static int m_total; } delegate void DoProc(int a); } 149 geerli

SINIFLARIN VE YAPILARIN EVENT ELEMANLARI Bir snfn ya da yapnn delege trnden veri elemanlar event eleman yaplabilir. Bunun iin event anahtar szc, eriim belirleyicisi ve varsa static anahtar szcnden sonra getirilir. rnein: delegate void Proc(); class Sample { public Proc A; public event Proc B; public event int C; error delege deil public event string D; error delege deil //.. } Snfn ya da yapnn event olmayan delege trnden veri elemanlar kstlamasz olarak(eer public blmde ise ve eriim geerlilii varsa) tam bir delege olarak kullanlabilir. rnein: Sample s = new Sample(); s.A = new Proc(Test.Foo); s.A(); Bir event delege eleman snfn darsnda ancak += ve -= operatrleri ile kullanlabilir. Snfn ya da yapnn dnda event delege elemana = operatr ile atama yaplamaz. Delege fonksiyonlar fonksiyon arma operatrleri ile arlamaz. Event delege eleman += ve -= operatr dnda hibir ekilde dardan kullanlamaz(halbuki delege eleman event yaplmasayd byle bir kst sz konusu olmayacakt ve dardan istenildii gibi kullanlacakt). r bir snf ya da yap trnden referans ya da deiken, E de Proc isimli bir delege trnden event veri eleman olsun. r.E = new Proc(Tes.Foo); error atama yaplamaz r.E(); error arlamaz. r.E += new Proc(Test.Foo); r.E -= new Proc(Test.Foo); geerli geerli

Bir event delege eleman kendi snf ierisinde kstlamasz olarak tam bir delege yetenei ile kullanlr. Anmsanaca gibi tremi snf, taban snfn public ve protected blmlerine eriebilir. Fakat event eriiminde tremi snfta taban snfn event elemanlarnn += ve -= operatrleri ile kullanabilmektedir. Yani event elemanlar tam bir delege olarak, yalnzca kendi snf ya da yaps kullanabilmektedir. 150

Madem ki event elemanlar dardan yalnzca fonksiyon eklemek ve kartmak amal kullanlabiliyor peki bu durumda event elemann fonksiyonlar nasl arlacaktr? phesiz arma ancak dolayl olabilmektedir. Yani yap ya da snfn public bir fonksiyonu event fonksiyonlarn armaktadr. rnein: r.E += new Proc(Test.Foo); r.Fire(); Burada Fire() fonksiyonu aadaki gibi yazlm olabilir: public void Fire() { //... E(); //... } event anahtar szc bir tr belirtmez. event eleman delege trndendir. event anahtar szc yalnzca delegeye dardan kullanm kstl getirmektedir. .Netin snf ktphanesindeki pek ok snf ve yapnn delege trnden veri elemanlar vardr. Bu veri elemanlar event yaplarak darnn kullanm iin kstlanmtr. EVENT ELEMANLARIN .NET PROGRAMLAMA MODELNDE KULLANILMASI .Netin snf ktphanesinde pek ok snfn ve yapnn event eleman vardr. Bu event elemanlara fonksiyonlar eklenip kartlabilir. Baz olaylar gerekletiinde framework, bu event elemana ait event fonksiyonlar arr. rnein; dmeler Button isimli snfla temsil edilmitir. Button snfnn aadaki gibi Click eleman vardr: public event EventHandler Click; Grld gibi Click event eleman EventHandler trndendir. EventHandler isimli delege yledir: isimli bir delege

delegate void EventHandler(object sender, EventArgs ea); Dmeye klik yapldnda framework, Click eventinin tuttuu fonksiyonlar kendisi armaktadr. Bu durumda dmeye klik yapldnda bir fonksiyonun arlmasn istiyorsak Click event elemanna bu fonksiyonu girmeliyiz. 151

Button button = new Button(); //... button.Click += new EventHandler(Test.Func); Burada Test snfnn Func() fonksiyonu, geri dn deeri void, birinci parametresi Object trnden, ikinci parametresi EventArgs snf trnden olmaldr. Grld gibi .Nette ne zaman bir olay gerekletiinde bir fonksiyonun arlmas isteniyorsa, arlmas istenen fonksiyon bir delegeye yerletirilmektedir. O delege de bir snf ya da yapnn veri eleman durumdadr ve event yaplarak darya kstlanmtr. REFERANSLARIN STATIC VE DNAMK TRLER Bir referansn static tr bildirimde belirtilen trdr. Referansn dinamik tr ise referansn gsterdii btnsel trdr. rnein referans daha byk bir nesnenin bir parasn gsteriyorsa, referansn dinamik tr o nesnenin btnsel en geni halinin trdr. A r Adat Bdat B B nesnesi

A r = new B();

Burada r referansn static tr A dr. r referansnn gsterdii yerde bir A nesnesi yoktur. B nesnesinin A ksm vardr. O halde r referansnn dinamik tr B dir. rnein:

152

A x; B y; C z; z = new C(); y = z; x = y; Burada z referansnn static ve dinamik tr C dir. y referansnn static tr B dinamik tr C dir. x referansnn static tr A dinamik tr C dir. Static tr bildirim srasnda bildirilir ve bir daha deimez. Halbuki dinamik tr program ierisinde srekli deiebilir. rnein: A

A r; r = new A(); // r nin dinamik tr A r = new B(); // r nin dinamik tr B r = new C(); // r nin dinamik tr C rnein: int a; object o = a; Burada o nun static tr object, dinamik tr Int32 yani int trdendir. OKBMLLK(POLYMORPHISM) Bir dilin nesne ynelimli olmas iin, o dilde snf kavramnn olmas, tretme kavramnn olmas ve okbiimliliin bulunmas gerekir. okbiimlilik biyolojiden aktarlm bir terimdir. Evrim srecinde eitli canllarn alt trlere ayrlmas srasnda baz organlarn o alt tre zg bir biimde deiiklie uramasna denilmektedir. rnein kulak bir ok canlda vardr ve duyma ilevine yerine getirmektedir. Fakat her canlda kulak onun yaam koullarna zg bir biimde deilik gstermitir. 153

Nesne ynelimli programlama tekniinde okbiimlilik ekilde tanmlanabilir: 1-Biyolojik Tanm: Taban snfn bir takm fonksiyonlarn tremi snflarn kendilerine zg bir biimde yeniden tanmlamalarna okbiimlilik denir. 2-Aa Seviyeli Tanm: okbiimlilik nceden yazlm kodlarn sonradan yazlan kodlar arabilme zelliidir. 3-Yazlm Mhendislii Tanm: okbiimlilik trden bamsz kod paralarn oluturabilmek iin kullanlan bir tekniktir. C# ta okbiimlilik sanal fonksiyonlarla gerekletirilmektedir. Anahtar Notlar: Javada default olarak her fonksiyon zaten sanaldr. Fakat bu durum etkinlii azaltabilmektedir. C#, javay temel almakla birlikte sanal fonksiyon mekanizmasn daha ok C++ a benzetmitir.

SANAL FONKSYONLAR VE OVERRIDE LEMLER Bir snfn (fakat yapnn deil) static olmayan bir fonksiyonu virtual anahtar szc kullanlarak sanal fonksiyon yaplabilir. rnein: class Sample { public virtual void Func() { //... } //... } virtual anahtar szc eriim belirleyici anahtar szc ile ayn syntax grubu ierisindedir. Yer deitirmeli olarak kullanlabilir. (yani rnein public virtual yada virtual public yazlabilir) Taban snftaki bir sanal fonksiyon, tremi snfta ayn eriim belirleyicisi, ayn isim, ayn geri dn deeri ve ayn parametrik yap ile fakat virtual anahtar szc yerine override anahtar szc ile tanmlanrsa bu ilem taban snftaki sanal fonksiyonun tremi snfta override edilmesi denilmektedir. rnein: class A { public virtual void Foo() { //... } //... } 154

class B : A { public override void Foo() { //... } //... } override etme ileminde u kurallara uyulmaldr: Fonksiyon tremi blmde baka bir yerde override edilemez. rnein:

class A { public virtual void Foo() { //... } //... } class B : A { protected override void Foo() error { //... } //... } - Fonksiyonun override edilebilmesi iin geri dn deerlerinin uyumas gerekir. rnein: class A { public virtual void Foo() { //... } //... } class B : A { public virtual int Foo() error { //... } //... } 155

Fonksiyon farkl bir parametrik yap ile override edilmez. rnein:

class A { public virtual void Foo() { //... } //... } class B : A { public virtual void Foo(int a) error { //... } //... } Tremi snfta override edilmi bir fonksiyon, tremi snftan tretilen baka bir snfta yeniden override edilebilir. rnein: class A { public virtual void Func() { //... } //... } class B : A { public override void Func() { //... } //... } class C : B { public override void Func() { //... } //... } Grld gibi fonksiyonun, en yukarda virtual anahtar szc ile sanall balatlr sonra hep override anahtar szc ile devam ettirilir.

156

Sanal fonksiyon terimi hem virtual, hem override hem de abstract fonksiyonlar kapsayacak ekilde kullanlacaktr. phesiz balatlabilir. bir fonksiyonun sanall herhangi bir tremi snftan

Bir fonksiyonun override edilebilmesi iin, o fonksiyonun hemen o snfn dorudan taban snfnda, virtual ya da override eklinde tanmlanmas gerekmez. Fakat phesiz yukarya doru herhangi bir taban snfta override ya da en kt olaslkla virtual biiminde tanmlanm olma zorunluluu vardr. rnein: Class A { public virtual int Foo(int a) { //... } //... } class B :A { //... } class C :B { public override int Foo(int a) { //... } //... } Grld gibi Foo() fonksiyonu B snfnda override edilmemitir. Fakat C snfnda override edilmitir. Bir snf, ayn isimli birok fonksiyona sahip olabilir (function overloading). Fakat bunlarda belirli parametrik yapya sahip olanlar sanal yaplmak istenebilir. rnein:

class A { public void Func() { //... } public virtual void Func(int a) { //... 157

} public void Func(long a) { //... } } Burada A snfnda tane Func() fonksiyonu tanmlanm olmasna karn yalnzca int parametreli Func() fonksiyonu sanaldr. Dolaysyla tremi snflarda yalnz bu fonksiyon override edilebilir. Taban snftaki bir sanal fonksiyon ayn isim, geri dn deeri ve parametrik yap ile fakat override anahtar szc kullanlmadan tremi snfta yeniden tanmlanabilir. Bu durum error ile sonulanmaz. Fakat bir uyar oluur. Bu durum override etme anlam tamamaktadr. rnein: class A { public virtual void Func() { //... } } class B :A { public void Func() error deil { //... } } Benzer biimde taban snftaki virtual fonksiyon tremi snfta yeniden virtual olarak tanmlanabilir. Bu durum da override etme anlamna gelmez. Bu zel durumlar new belirleyicisinin anlatld blmde ele alnacaktr. SANALLIK MEKANZMASI Bir referansla bir fonksiyon arldnda fonksiyon ismi, referansn static trne ilikin snfn faaliyet alannda aranr. Sonra fonksiyonun sanal olup olmadna baklr. Eer fonksiyon sanal deilse bulunan fonksiyon arlr. Eer fonksiyon sanalsa referansn dinamik trne ilikin sanal fonksiyon arlr. rnein: A

class A 158

{ public void Foo() { //... } public virtual void Bar() { //... } //... } class B : A { public override void Bar() { //... } //... } B b = new B(); A a = b; a.Bar(); rnein: A

class A { public void Foo() { //... } public virtual void Bar() { //... } //... } class B : A { public override void Bar() 159

{ //... } //... } class C :B { public override void Bar() { //... } //... } A a; B b = new B(); C c = new C(); a = b; a.Bar(); B snfnn Bar fonksiyonu arlr. a = c; a.Bar(); C snfnn Bar fonksiyonu arlr. b = c; b.Bar(); C snfnn Bar fonksiyonu arlr. Anmsanaca gibi sanal fonksiyonlar override edilmek zorunda deildir. Eer sanal fonksiyon, referansn dinamik trne ilikin snfta override edilmedi ise yukarya doru bu sanal fonksiyonun override edildii, ilk taban snfn sanal fonksiyonu arlr. Yukardaki rnekte eer C snfnda Bar() fonksiyonu override edilmi olmasayd B snfndaki Bar() fonksiyonu arlacakt. Anahtar Notlar Java da static olmayan tm fonksiyonlar default olarak sanal fonksiyon durumundadr. Dolaysyla bu dilde virtual ya da override gibi anahtar szckler yoktur. Taban snftaki bir fonksiyon tremi snfta ayn blm, ayn geri dn deeri tr ve ayn imza ile tanmlanrsa bu durum override etmek anlamna gelmektedir. rnein: class A { public void Func() { //... } //... } class B extends A { public void Func() 160

{ } //...

//...

A a = new B(); a.Func(); Burada adeta Func fonksiyonu A snfnda virtual tanmlanm ve B snfnda override edilmi gibidir. Anahtar Notlar: C++ ta sanallk yine virtual anahtar szc ile balatlr. Fakat override anahtar szc bu dilde yoktur. Tremi snfta eer bir sanal fonksiyon ayn geri dn deeri ve imza ile bildirilirse fonksiyon override edilmi olur. class A { public: virtual void Func() { //... } //... }; class B : public A { public: void Func(); { //... } //... }; object SINIFININ ToString SANAL FONKSYONU En tepedeki object snfnn ToString isminde, bir string nesnesi (referans) ile geri dnen sanal bir fonksiyonu vardr. ToString sanal fonksiyonu tremi fonksiyonlarda override edilebilir. rnein: class Sample { public override string ToString { return This is a test; } //... } object o; 161

o = new Sample(); Console.WriteLine(o.ToString()); Burada Sample snfnn ToString fonksiyonu arlacaktr. using System; namespace CSD { class App { public static void Main() { object o; Sample s = new Sample(); o = s; Console.WriteLine(o.ToString()); } } class Sample { public override string ToString() { return "this is a test"; } } } Object snfnn ToString fonksiyonu, referansn dinamik trne ilikin snf ismini geri dndrmektedir. using System; namespace CSD { class App { public static void Main() { Sample s = new Sample(); Console.WriteLine(s.ToString()); } } class Sample { } } Bir ArrayList collection snf ierisinde, eitli snflara ilikin nesnelerin referanslarn saklayabiliriz. Sonra bu collectionu dolaarak ToString sanal fonksiyonun arrsak, her nesneye ilikin snfn override edilmi kendi ToString fonksiyonlar arlr. rnein: 162

using System; using System.Collections; namespace CSD { class App { public static void Main() { ArrayList al = new ArrayList(); al.Add(new al.Add(new al.Add(new al.Add(new A()); B()); C()); D());

foreach (object o in al) Console.WriteLine(o.ToString()); } } class A { public override string ToString() { return "A.ToString"; } } class B { public override string ToString() { return "B.ToString"; } } class C { public override string ToString() { return "C.ToString"; } } class D { public override string ToString() { return "D.ToString"; } } }

.Netteki snflarn hemen hepsinde ToString fonksiyonlar faydal birtakm iler yapacak biimde override edilmitir. rnein: int, long, double 163

gibi yaplarda ToString fonksiyonlar onlarn tuttuklar deerleri yaz olarak gelecek biimde yazlmtr. rnein: using System; using System.Collections; namespace CSD { class App { public static void Main() { int i = 123; Console.WriteLine("Say : " + i.ToString()); } } } rnein: using System; using System.Collections; namespace CSD { class App { public static void Main() { int i = 123; object o = i; Console.WriteLine(o.ToString()); } } } Toplama ileminde operandlardan biri string fakat dier operand herhangi bir trden ise dier operand zerinde derleyici tarafndan ToString fonksiyonu uygulanr. Elde edilen yaz birletirilir. rnein:

int i = 123; string s = Sayi : + i; Console snfnn object trnden parametreye sahip Write ve WriteLine fonksiyonlar vardr. Biz bu fonksiyonlara herhangi bir snf trnden referans geirdiimizde overload resolution ilemine gre object parametreli Write yada WriteLine fonksiyonu arlr. Bu fonksiyon da 164

parametresine ToString sanal fonksiyonunu uygulayarak elde ettii yazy yazdrr. rnein: using System; using System.Collections; namespace CSD { class App { public static void Main() { Sample s = new Sample(); Console.WriteLine(s); } } class Sample { public override string ToString() { return "A.ToString"; } } } rnein; DateTime yapsnn ToString sanal fonksiyonu yapnn tuttuu tarih ve zaman yaz olarak verir. rnein: namespace CSD { class App { public static void Main() { Console.WriteLine(DateTime.Now); } } } OKBMLLE LKN RNEKLER okbiimlilie ilikin mekanizma yukarda akland. Bu mekanizma bir referansla sanal fonksiyon arldnda, referansn dinamik trne ilikin snfn sanal fonksiyonunun arlmas anlamndadr. Peki bu mekanizmann programcya ne faydas vardr? okbiimlilik trden bamsz kod paralarnn oluturulmas iin kullanlmaktadr. Bir projede deiebilecek eler tespit edilir ve bunlara okbiimli mekanizma ile eriilir. Yani okbiimlilik gerekte farkl olan nesnelerin ayn trdenmi gibi ele alnmasn salamaktadr.

165

Nesne ynelimli bir proje modellemesinde, projedeki tm gerek nesneler ve kavramlar snflarla temsil edilir. Sonra snflar arasnda ilikiler belirlenir. 1-Topla oynanan bir oyun program yazacamz dnelim. Oyundaki top eitli seeneklere gre deiebilecek ekilde yazlmak istenmektedir. rnein top yuvarlak olabilir, dikdrtgen olabilir, zplayan top olabilir, daha pek ok farkl top olabilir. Fakat ne olursa olsun topun baz temel ilevleri vardr. Bu temel ilevler, tema olarak ayn kalmakla beraber toptan topa farkllk gstermektedir. te top bir snfla temsil edilebilir ve topun temel ilevleri sanal fonksiyonlarla belirlenebilir. class Ball { public virtual void Move() { //... } public virtual void Jump() { //... } //... } imdi eitli toplar Ball snfndan tretilen snflar biiminde oluturulur. class CircleBall : Ball { public override void Move() { //... } public override void Jump() { //... } //... } class RectagleBall : Ball { public override void Move() { //... } public override void Jump() { //... } //... } 166

imdi bu topu kullanan bir program paras dnelim. Ball ball = new CircleBall(); ball.Move(); ball.Jump(); Grld gibi burada top kavram, genel bir kavram olarak kodda kullanlmtr. lemler Ball snf trnden referansla gerekletirilmitir. Burada arlan fonksiyonlar aslnda CircleBall snfnn fonksiyonlardr. Oyundaki topu deitirmek iin tek yaplacak ey new CircleBall ifadesi yerine dier bir top snfnn yaratm ifadesini yerletirmektir. nk topu kullanan tm kodlar, taban Ball snfnn sanal fonksiyonlar ile bu ii yapmaktadr. Programa yeni bir top eklemekte olduka kolaydr. Tek yaplacak ey, Ball snfnda yeni bir snf tretip, ilgili sanal fonksiyonlar override etmektir. Bu tr durumlarda eskiden yazlm kodlar geerliliini koruyaca iin bunlarn yeniden test edilmesine gerek kalmayacaktr. 2-Bir tetris program yazmak isteyelim. Oyunun kendisi bir snf ile temsil edilebilir. Bu snfn Run isimli bir fonksiyonu oyunu balatabilir. class Tetris { //... } //... Tetris t = new Tetris(); t.Run(); Biz burada oyundaki ekiller zerinde duracaz. Oyundaki ekiller benzer ilevlere sahiptir fakat kendine zg hareketlere sahiptir. Kodlama yaplrken tm ekiller sanki ayn trdenmi gibi ileme sokulur. Tm ekiller Shape snf ile temsil edilebilir.

class Shape { public virtual { //... } public virtual { //... } public virtual { //... } public virtual

void MoveDown()

void MoveLeft()

void MoveRight()

void Rotate() 167

{ //... } } Tm ekil snflar Shape snfndan tretilen snflarla temsil edilir. Her ekil snfnda Shape snfndaki sanal fonksiyonlar o snfa zg olarak override edilecektir. class BarShape : Shape { public override void { //... } public override void { //... } public override void { //... } public override void { //... } } class LShape : Shape { //... } class ZShape : Shape { //... } class TShape : Shape { //... } imdi artk oyunda den eklin hareket ettirilmesi trden bamsz olarak ifade edilebilecektir.

MoveDown()

MoveLeft()

MoveRight()

Rotate()

using System; namespace CSD { 168

class App { public void Run() { for (; ; ) { Shape shape = GetRandomShape(); for (int i = 0; i < 10; ++i) { ConsoleKeyInfo cki = Console.ReadKey(true); switch (cki.Key) { case ConsoleKey.LeftArrow: shape.MoveLeft(); break; case ConsoleKey.RightArrow: shape.MoveRight(); break; case ConsoleKey.UpArrow: shape.Rotate(); break; case ConsoleKey.Escape: goto EXIT; } shape.MoveDown(); System.Threading.Thread.Sleep(600); } } EXIT: ; } } } Yukardaki kod tetris oyununu simle etmektedir. GetRandomShape rasgele bir ekil elde eder. Bu ekil uygun biimde hareket ettirilir. Grld gibi kod, den eklin ne olduunu bilmeden yazlm olan genel bir koddur. Oyuna yeni bir ekil ekleyecek olsak tek yapacamz ey Shape snfnda yeni bir snf tretip, Shape snfndaki sanal fonksiyonlar override etmektir. Fakat Run fonksiyonunda bir deiiklik yaplmayacaktr. Tetris.cs using System; namespace CSD { class App { public static void Main() { Tetris tetris = new Tetris(); 169

tetris.Run(); } } enum ShapeType { BarShape, LShape, ZShape, TShape, SquareShape, } class Tetris { public void Run() { for (; ; ) { Shape shape = GetRandomShape(); for (int i = 0; i < 10; ++i) { if (Console.KeyAvailable) { ConsoleKeyInfo cki = Console.ReadKey(true); switch (cki.Key) { case ConsoleKey.LeftArrow: shape.MoveLeft(); break; case ConsoleKey.RightArrow: shape.MoveRight(); break; case ConsoleKey.UpArrow: shape.Rotate(); break; case ConsoleKey.Escape: goto EXIT; } } shape.MoveDown(); System.Threading.Thread.Sleep(600); } } EXIT: ; } private Shape GetRandomShape() { Shape shape = null; Random r = new Random(); int val = r.Next(4); 170

switch ((ShapeType)val) { case ShapeType.BarShape: shape = new BarShape(); break; case ShapeType.LShape: shape = new LShape(); break; case ShapeType.SquareShape: shape = new SquareShape(); break; case ShapeType.TShape: shape = new TShape(); break; case ShapeType.ZShape: shape = new ZShape(); break; } return shape; } //... } }

shape.cs using System; namespace CSD { class Shape { public virtual { } public virtual { } public virtual { } public virtual { } //... }

void MoveLeft() void MoveRight() void MoveDown() void Rotate()

class BarShape : Shape { public override void MoveLeft() { Console.WriteLine("BarShape MoveLeft"); } public override void MoveRight() { 171

Console.WriteLine("BarShape MoveRight"); } public override void MoveDown() { Console.WriteLine("BarShape MoveDown"); } public override void Rotate() { Console.WriteLine("BarShape Rotate"); } //... } class LShape : Shape { public override void MoveLeft() { Console.WriteLine("LShape MoveLeft"); } public override void MoveRight() { Console.WriteLine("LShape MoveRight"); } public override void MoveDown() { Console.WriteLine("LShape MoveDown"); } public override void Rotate() { Console.WriteLine("LShape Rotate"); } //... } class ZShape : Shape { public override void MoveLeft() { Console.WriteLine("ZShape MoveLeft"); } public override void MoveRight() { Console.WriteLine("ZShape MoveRight"); } public override void MoveDown() { Console.WriteLine("ZShape MoveDown"); } public override void Rotate() { Console.WriteLine("ZShape Rotate"); } //... } 172

class TShape : Shape { public override void MoveLeft() { Console.WriteLine("TShape MoveLeft"); } public override void MoveRight() { Console.WriteLine("TShape MoveRight"); } public override void MoveDown() { Console.WriteLine("TShape MoveDown"); } public override void Rotate() { Console.WriteLine("TShape Rotate"); } //... } class SquareShape : Shape { public override void MoveLeft() { Console.WriteLine("SquareShape } public override void MoveRight() { Console.WriteLine("SquareShape } public override void MoveDown() { Console.WriteLine("SquareShape } public override void Rotate() { Console.WriteLine("SquareShape } //... } class Shape { public bool { } public void { } public void { } public void { } //... }

MoveLeft");

MoveRight");

MoveDown");

Rotate");

IsInside(int x, int y) Paint(Graphics g) Select(Graphics g) Deselect(Graphics g)

173

3-PowerPoint benzeri bir program yazacak olalm. Bu programda kabaca dikdrtgen gibi, daire gibi, izgi gibi eitli geometrik ekiller izilebilmektedir. Tm bu geometrik ekiller Shape isimli taban bir snftan tretilen snflarla temsil edilebilir. Her ekil snf o eklin koordinatlarn tutabilir. Programda izilen tm ekiller temel nitelik olarak birer ekildir. Fakat okbiimli bir davran gstermektedir. rnein; bir eklin stne tklandnda her eklin seilmesi yani ekilde kk kutucuklar karlmas farkl olmaktadr. O halde bu ii yapacak Shape snfnn Select isimli sanal bir fonksiyonu olabilir. Bu fonksiyon tremi snflarda override edilebilir. Benzer biimde tklanan noktann eklin iinde olup olmad, her ekil iin o ekle zg biimde belirlenmektedir. Bu ilemde okbiimlidir. ekillerin izilmesi yine kendilerine zg bir biimde yaplmaktadr. O halde Shape taban snf aadaki biimde olabilir: class Shape { public {} public {} public {} public {} }

bool IsInside(int x, int y) void Paint(Graphics g) void Select(Graphics g) void Deselect(Graphics g)

okbiimli uygulamalarn ounda bir tretme emas iinde bulunan snflara ilikin nesneler, bir collection ierisinde tutulur. Sonra bu collection dolalarak, okbiimli bir biimde sanal fonksiyonlar arlr. PowerPoint uygulamasnda da, izilen her ekil iin bir snf nesnesi yaratlmal ve bu nesne ArrayList gibi bir collection ierisine yerletirilmeli. Bylece programc izilen her ekli onlar sanki bir Shape nesnesiymi gibi saklar. Bylece fare ile bir yere tklandnda programc tklanan noktann bir ekil ierisinde olup olmadn anlamaya alr. Tklanan noktann bir eklin ierisinde olup olmadnn anlalmas iin tm ekillerin okbiimli bir ekilde dolalmas gerekir. Bunun iin okbiimli IsInside fonksiyonu kullanlr. Baslan noktann eklin iinde olup olmad aadaki gibi sorgulanabilir: foreach (Shape shape in m_shapes) if (shape.IsInside(e.X, e.Y)) { //... }

174

abstract FONKSYONLAR VE SINIFLAR okbiimli uygulamalarn ounda, en tepede bir taban snf bulunur ve bu en tepedeki snf, trden bamsz ilemleri yapmak iin kullanlr. Yani aslnda bu en tepedeki taban snf trnden hi nesne tanmlanmaz. rnein tetris uygulamasnda ya da PowerPoint uygulamasnda en tepedeki Shape snf aslnda okbiimli etki yaratmak iin kullanlmtr. Bir fonksiyonu abstract yapmak iin, abstract anahtar szc kullanlr. Abstrack fonksiyonlarn gvdesi yoktur. Fonksiyon bildirimi ; ile kapatlr. rnein: public abstract void Func(int a, int b); Abstract anahtar szc, eriim belirten anahtar szcklerle ayn syntax grubundandr. Bunlarla yer deitirmeli olarak yazlabilir. Fonksiyonlar hem abstract hem de virtual olamaz. Abstract fonksiyon, gvdesi olmayan virtual fonksiyondur. En az bir abstract elemana sahip snfa abstract snf denir. Bu durumda, vurgulama amac ile snf bildiriminin bana ayrca abstract anahtar szc de yazlmak zorundadr. rnein: abstract class Sample { private int a; //... public Sampe() { //... } public void Test() { //... } public abstract void Func(); } Bir abstract snf, ayrca veri elemanlarna, abstract olmayan fonksiyonlara sahip olabilir. Snfn abstract olabilmesi iin, en az bir elemannn abstract olmas yeterlidir. Abstract snf trnden referanslar tanmlanabilir. Fakat new operatr ile nesne yaratlamaz. Eer new operatr ile nesne yaratlmak istenirse derleme zamannda error oluur. rnein: public static void Main() 175

{ Sample s; geerli s = new Sample() error } Abstract snf trnden nesne, new operatr ile neden yaratlamamaktadr? Eer yaratlabilseydi olmayan bir fonksiyonun arlmas gibi potansiyel bir durum oluurdu. Bir abstract snftan snf tretildiinde, tremi snf taban snfn tm abstract fonksiyonlarn override etmek zorundadr. Aksi halde tremi snfta abstract olur. Tremi snf trnden de new operatr ile nesne yaratlamaz. Tremi snf bildiriminin nne de abstract anahtar szcn yerletirmek gerekir. rnein: abstract class A { public abstract void Foo(); } class B : A { public override void Foo() { //... } } Bu rnekte A snf, abstract snftr. Fakat B snf, abstract snf deildir. nk B snf, taban A snfnn tm abstract fonksiyonlarn override etmitir. B snf trnden new operatr ile yeni bir nesne yaratlabilir. Fakat A snf trnden nesne yaratlamaz. rnein: A a = new B(); a.Foo(); B.Foo fonksiyonu arlacak. phesiz sanal fonksiyonu abstract yapmak yerine virtual yapp bo bir gvde yazmak ilevsel olarak ayn etkiye yol aacaktr. Fakat tetris ve powerpoint rneklerinde olduu gibi eer en tepedeki taban snf trden bamsz ilevler iin kullanlyorsa snfn abstract yaplmas bu kullanm vurgusuna yol aar. Biz bir abstract snf grdmzde, o snf trnden nesne yaratlamayacan, o snfn tamamen trden bamsz ilemler yapmak amacyla kullanlacan anlamalyz. rnein tetris ve powerpoint uygulamalarnda en tepedeki taban snf bu anlamda abstract yaplmaldr. Anahtar Notlar

176

Abstract szc bu balamda soyut anlamna gelmektedir. Soyut snf fiziksel olarak varolmayan fakat kavramsal olarak varolan snf anlamna gelmektedir. Taban snfn pek ok abstract eleman olabilir. Tremi snfta bunlarn hepsi override edilmedi ise tremi snfta abstract olur. A isimli taban abstract snfn, bir grup abstract eleman tremi B snfnda override edilmi olsun. Geri kalan abstract elemanlar da B snfndan tretilmi, C snfnda override edilmi olsun. Bu durumda B abstract snftr. Fakat C snf abstract snf deildir. rnein: abstract class A { public abstract void Foo(); public abstract void Bar(); //... } abstract class B : A { public override void Foo() { //... } } class c : B { public override void Bar() { //... } } Bir snfn hibir abstract eleman olmad halde yine de snf bildiriminin bana abstract anahtar szc getirilerek, snf abstract yaplabilir. Bu durumda da new operatr ile yine snf nesnesi yaratlamaz. Abstract PROPERTY ELEMANLAR Snfn property elemanlar, aslnda get ve set fonksiyonlar olarak deerlendirilebilir. Property elemann abstract olmas, aslnda bu get ve set blmlerin abstract olmas anlamndadr. Bir property eleman abstract yaplrken ana bloun ierisinde get ve set anahtar szckleri noktal virgl ile kapatlr. rnein: abstract public int x { get; set; 177

} Yine tremi snfta bu property elemanlar override edilmelidir. rnein: abstract class A { abstract public int x { get; set; } } class B : A { public override int x { get { //... } set { //... } } }

HOCANIN TAM RNE

using System; using System.Collections; namespace CSD { class App { public static void Main() { A a = new B(); a.X = 10; } } abstract class A { abstract public int X { get; set; } //... 178

} class B : A { public override int X { get { Console.WriteLine("get"); return 0; } set { Console.WriteLine("set"); } } //... } }

ARAYZLER Bir arayz, interface anahtar szc ile arayz ismi belirtilerek oluturulur. rnein: interface IX { //... } Arayz isimleri geleneksel olarak, I harfi ile balanarak isimlendirilir. Bir arayz, adeta tm elemanlar abstract olan ve veri elemanna sahip olmayan snflara benzemektedir. Arayz oluturmann u kstlar vardr: Arayz elemanlarnda eriim belirleyici (public) elemanlar kullanlamaz. Zaten default public durum anlalr. Arayz elemanlarnda virtual, abstract gibi belirteler kullanlmaz. Elemanlar zaten abstract gibi ele alnr. Arayz fonksiyonlar ve propertyleri gvde iermez. Arayzler veri eleman ieremez. rnein: interface IX { void Foo(); int Bar(int a); int X { get; set; } 179

} Arayz trnden referanslar tanmlanabilir. Fakat new operatr ile nesneler yaratlamaz. rnein: IX ix; geerli error

ix = new IX();

Bir arayz bir snfn ya da yapnn taban listesinde belirtilebilir. Bu duruma ilgili snf ya da yapnn ilgili arayz desteklemesi denilmektedir. Bir snf tek bir snftan tretilebilir fakat birden fazla arayz destekleyebilir. rnein: class A : B, IX, IY { //... } Burada A snf, B snfndan tretilmi ve IX ve IY arayzn desteklemektedir. Taban listesinde(:den sonraki yazlanlar) arayzler istenildii srada belirtilebilir. Fakat eer taban listesinde hem taban snf hem de arayzler varsa taban snfn nce belirtilmesi zorunludur. Anmsanaca gibi yaplar tretme ileminde kullanlamamaktadr. Fakat yaplar bir yada birden fazla arayz desteklemektedir. rnein: stract A : IX, IX { //... } Bir snf yada yap bir arayz destekliyorsa o snf yada yapda o arayz elemanlarnn public olarak tanmlanmas zorunludur. Aksi halde ilem error ile sonulanr. rnein: interface IX { void Foo(); } class A : IX { public void Foo() { //... } //... } Burada A snf, Foo() fonksiyonunu tanmlamazsa derleme zamannda error oluur. Tanmlama srasnda override anahtar szc belirtilemez ve tanmlama public olarak yaplmak zorundadr. 180

Arayzler okbiimli etkiye sahiptir. Bir arayz referansna o arayz destekleyen snf referanslar atanabilir. Sonra bu arayz referans ile arayz fonksiyonlar arlrsa, dinamik tre ilikin snf ya da yapnn fonksiyonlar arlr. rnein: IX ix = new A(); ix.Foo(); A.Foo() arlr

HOCANIN TAM RNE

using System; using System.Collections; namespace CSD { class App { public static void Main() { IX ix; ix = new A(); ix.Foo(); IY iy = new A(); iy.Bar(); } } interface IX { void Foo(); } interface IY { void Bar(); } class A : IX, IY { public void Bar() { //... } public void Foo() { //... } } } 181

Her arayzn yine System.Object trnden tretildii varsaylr. B snf, A snfndan tretilmi olsun. A snf da rnein IX isimli bir arayz destekliyor olsun. interface IX { void Foo(); }

class A : IX { public void Foo() { //.. } } class B : A { //... } Burada B snf IX arayzn desteklememektedir. A snf desteklemektedir. Bu durumda Foo(), B snfnda tanmlanmak zorunda deildir. Tremi snf bir arayz desteklemiyor fakat taban snf destekliyorsa yine biz tremi snf trnden bir nesnenin referansn arayz referansna atayabiliriz. Bu arayz referans ile arayz fonksiyonu arlabilir. rnein: IX ix = new B(); ix.Foo(); A.Foo arlr. Arayz konusu oklu tretme kavramn basit bir ekilde olduka kstl lde dile sokmak iin dnlmtr. Yani rnein bir snf birden fazla taban snfa sahip olamaz. Fakat birden fazla arayz destekleyebilir. C++ da arayz konusu yoktur. Bu dilde oklu tretme olduu iin arayz gereksinimi zaten abstract snflarla karlanabilmektedir. IX ve IY gibi iki arayzde ayn isimli ve ayn parametrik yapya sahip fonksiyonlar olabilir. rnein: interface IX { void Foo(); //... } interface IY { void Foo(); 182

//... } Bu iki arayz destekleyen A gibi bir snf tek bir tanmlama ile her iki arayz destekleme gereksinimini de karlar. rnein. class A : IX, IY { public void Foo() { //... } //... } rnein: A a = new A(); IX ix = a; ix.Foo(); A.Foo arlr IY iy = a; y.Foo(); A.Foo arlr. .Nette pek ok standart arayz de tanmlanmtr. Grdmz snflarn ou bu arayzleri desteklemektedir. Bir arayz baka bir arayzden tretilebilir. Fakat bir snf ya da yapdan tretilemez. rnein: interface IX { void Foo(); } nterface IX : IY { void Bar(); } Anahtar Notlar: Destekleme tanmlama zorunluluunu anlatan bir kavramdr. Yani bir snf yada yap bir arayz desteklerse o arayzn fonksiyonlarn tanmlamak zorundadr. Halbuki tretme tremiin taban elemanlarn iermesi anlamna gelmektedir.Bu nedenle arayzn arayz desteklemesi yerine tretmesi szkonusu olmaktadr. Bir snf ya da yap bir tremi arayz destekliyorsa hem tremi arayzn fonksiyonlarn hem de taban arayzn fonksiyonlarn tanmlamak zorundadr. rnein: 183

class A : IY { public void Foo() { //... } public void Bar() { //... } } Burada A snf, hem Foo() hem de Bar() fonksiyonlarn tanmlamak zorundadr. Snf ya da yapnn taban listesinde tremi arayzn yan sra taban arayzde belirtilebilir. Taban arayzn belirtilmesinin hibir gereklilii ve zel anlam yoktur. Bu belirtme geerlidir. Fakat taban arayzn hi belirtilmemesi ile arasnda hibir fark yoktur. rnein:

class A : IY { //... } ile class A : IY, IX { //... } tamamen ayndr. Burada belirtme byk lde dikkat ekmek iin yaplmaktadr. Tremi arayz referans taban arayz referansna atanabilir. Fakat tersi olan durum yalnzca tr dntrme operatr ile yaplr. rnein: IY iy = new A(); IX ix iy; ix.Foo(); A.Foo arlr. Anmsanaca gibi bir arayz fonksiyonu public olarak yazlmak zorundadr. Fakat arayz fonksiyonlarnn normal tanmlamann yansra aka tanmlanmas da mmkndr. Hem normal tanmlama hem de aka tanmlama ayn anda yaplabilir. Aka tanmlamada eriim belirleyici anahtar

184

szckler kullanlmaz tanmlanr. rnein; Interface IX { void Func(); }

ve

arayz

fonksiyonu,

arayz

ismi

belirtilerek

class Sample:IX { public void Func () } void IX.Func() { //.. }

//Normal tanmlama //Aka (explicit) tanmlama

Arayz fonksiyonlar yanlzca normal olarak tanmlanabilir, yanlzca aka tanmlanabilir ya da hem normal hem de aka tanmlanabilir. Aka tanmlanm olan versiyon, yanlzca arayz referansyla arlabilir. Normal versiyon ise hem nesne referansyla hem de arayz referansyla arlabilir. Arayz fonksiyonunun hem normal hem de aka tanmlanm olduunu varsayalm. imdi biz bu fonksiyonu nesne referansyla arrsak (yani aadan arrsak) normal tanmlanm olan versiyon, arayz referansyla arrsak aka tanmlanm versiyon arlr. Arayz fonksiyonu yanlzca aka tanmlanabilir. Bu durumda arayz fonksiyonu aadan yani snf referans kullanlarak arlamaz. Fakat yukardan arlabilir. ARAYZ DNTRMELER Eer bir snf ya da yap, bir arayz destekliyorsa o snf trnden referans ya da yap trnden deiken, o arayz referansna ya da o arayzn taban arayz referanslarna dorudan atanabilir. Eer taban snf bir arayz destekliyorsa tremi snfn da o arayz destekledii kabul edilmektedir. Bu durumda rnein taban snf bir arayz destekliyor olsun fakat tremi snf taban listesinde o arayz belirtmesin. Bu durumda tremi snfn da yine o arayz destekledii kabul edilir ve tremi snf trnden referans, o arayz referansna dorudan atanabilir. interface IX { void Func(); } class A:IX 185

{ //.. } class B:A { //.. } //.. B b=new B(); IX ix=b; //geerli ix.Func(); //Adaki func arlr Taban snf bir arayz destekliyor olsun arayz tremi snfn taban listesinde yeniden belirtilirse tremi snf bu arayz ayrca yeniden destekleyebilir. Fakat bu durumda tremi snf arayz fonksiyonunu yeniden tanmlamaldr. rnein ; interface IX { void Func(); } class A:IX { //.. } class B:A,IX { //.. } //.. B b=new B(); IX ix=b; //geerli ix.Func(); //Bdeki func arlr Arayzlerden snflara yani yukardan aaya doru da tr dntrme operatr ile dntrme yaplabilir. Tabi bu dntrmenin derleme aamasnda kabul edilebilmesi iin dntrlen snfn ya da yapnn o arayz destekliyor olmas gerekir.Tabi ayrca yine denetim alma zaman srasnda dnmn hakl olup olmadn belirlemek iin yaplacaktr. rnein: interface IX { //... 186

} class A :IX { //... } class B : A { //... } B b = new B(); IX ix = b; geerli A a = (A) ix; geerli Bir snf referans tr dntrme operatr ile bir arayze dntrlebilir. Bu dntrme her zaman derleme aamasnda kabul edilir. Fakat programn alma zaman srasnda snf referansnn dinamik trnn, o arayz destekleyip desteklemediine baklr ve bylece denetim uygulanr. Bu tr durumlarla yle bir senaryo biiminde karlalabilir: A isimli snf, IX arayzn destekliyor olsun. Biz A trnden nesne referansn, Object trnden bir referansa atam olalm. imdi bu object referansn, tr dntrme operatr ile IX trne dntrebiliriz. nk object referansnn dinamik tr A dr. A da IX arayzn desteklemektedir. rnein: interface IX { //... } class A : IX { //... } A a = new A(); Object o = a; IX ix = (IX)o geerli zetle bir snf referans bir arayz referansna tr dntrme operatr ile dntrlmek istenirse, bu durum her zaman derleme aamasnda kabul edilir. Fakat alma zaman srasnda, CLR referansn dinamik trne ilikin snfn, bu arayz destekleyip desteklemediine bakar.

DOSYA LEMLER Dosya ilemleri System.IO isim alanndaki eitli snflarla yaplmaktadr. .Net ortamnda dosya gibi ilem gren tm kavramlar, okbiimli bir etki yaratmak iin ortak bir biimde ele alnmtr. Her ne kadar dosya denince 187

akla tipik olarak diskteki dosyalar anlalsa da soketteki bilgiler, bellekteki bilgilerde okbiimli etki yaratmak iin dosya gibi deerlendirilmitir. Dosya ilemlerinde dosyams olan kavramlar Stream snf ile temsil edilmitir. Stream snf abstract bir snftr ve dosya gibi ilem gren farkl kaynaklara ortak taban snflk yapmaktadr. Stream snfndan baz snflar tretilmitir. phesiz bu snflar abstract olmad iin, Stream snfnn abstract fonksiyonlarn override etmitir. Stream

...

NetworkStream

FileStream

MemoryStream

...

FileStream snf, disk tabanl gerek dosyalar temsil etmektedir. NetworkStream snf, bir soketi dosya gibi temsil etmektedir. MemoryStream snf, bellekteki bir bilginin dosya gibi ele alnmasn salamaktadr. Yukardaki tretme emas, okbiimli kullanma olanak vermektedir. Yani biz dosyann ne tabanl bir dosya olduunu bilmeden, onunla ilem yapabiliriz. rnein; bir kaynaktan bilgi okuyarak onlar ayrtran bir Parser snf yazacak olalm. Parser snf, hibir deiiklik yaplmadan disk tabanl dosyay da, bir soketi de, bellekteki bir bilgiyi de kaynak olarak kullanp parse yapabilsin. O halde Parser snf bir Stream referans alarak, Stream snfnn sanal fonksiyonlarn ararak ilemlerini yapmaktadr. class Parser { private Stream m_s; public Parser (Stream s) { m_s = s; } } Biz snf yle kullanabiliriz: FileStream fs = new fileStream(...); Parser p = new Parser(fs); imdi Parser snf bir disk dosyasndaki bilgileri parse edecektir. Ya da rnein: MemoryStream ms = new MemoryStream(...); Parser p = new Parser(ms); 188

DSK TABANLI DOSYALARIN FILESTREAM SINIFI LE KULLANILMASI Bir disk dosyas zerinde ilem yapabilmek iin, ncelikle onu amamz gerekir. Dosyann almas srasnda bir takm ilk ilemler yaplr. FileStream snfnn balang fonksiyonlar dosyay amaktadr. FileStream snfnn birok balang fonksiyonu vardr. Ama a iin en ok kullanlan fonksiyon aadaki gibidir: public FileStream access); Anahtar Notlar Bir dosya herhangi bir srcnn herhangi bir dizininde bulunabilir. Farkl dizinlerde ayn isimli dosyalar bulunabilir. O halde bir dosyay belirtirken onun hangi dizinde olduunu da belirtmemiz gerekebilir. Bir dosyann yerini belirten yazsal ifadeye yol ifadesi(path) denir. Yol ifadesi mutlak ve greli olmak zere 2 ayrlr. Eer yol ifadesinin ilk karakteri \ ile balyorsa mutlak yol ifadesi sz konusudur. Mutlak yol ifadesi kk dizinden itibaren yol belirtir. Eer ilk karakter \ deilse buna greli yol ifadesi denir. Greli yol ifadesi prosesin alma dizininden itibaren yol belirtmektedir. Bu dizin default durumda .exe dosyann bulunduu dizindir. Tek bana bir dosya ismi greli bir yol ifadesidir. O halde bu dosya exe dosyann bulunduu dizinde aranacaktr. Fonksiyonun birinci parametresi, dosyann yol ifadesini belirtmektedir. kinci parametre, dosyann am modunu belirtmek iin kullanlr. FileMode bir enum trdr ve u elemanlara sahiptir: Open: Var olan dosyann almas iin kullanlr. Eer dosya yoksa exception oluur. Create: Dosya yoksa yaratlr ve alr, varsa sfrlanr ve alr. OpenOrCreate: Dosya varsa varolan dosyay aar , yoksa dosyay yaratr ve aar. CreateNew: Dosya yoksa yaratr ve aar, dosya varsa exception oluur dosyay bozmaz. Trancute: olan bir dosyay sfrlayarak amak iin kullanlr. Dosya yoksa exception olumaktadr. Append: olan dosyay aar yoksa dosyay yaratr aar. Dosyann herhangi bir yerinden okuma yaplabilir. Fakat tm yazma ilemleri sona ekleme anlamndadr. Fonksiyonun nc parametresi, FileAccess isimli bir enum trndendir. Bu parametre dosyaya yaplacak operasyonu belirtir. Bu enum trnn eleman vardr: Read: Yalnczca okuma yaplabilir Write: Yalnzca yazma yaplabilir. ReadWrite: Hem okuma hem yazma yaplabilir. 189 (string path, FileMode mode, FileAccess

Eer dosya almazsa ilem exception oluur. Stream SINIFININ NEML ELEMANLARI Snfn Length isimli abstract property eleman, alm olan dosyann uzunluunun verir. Snfn Read isimli abstract fonksiyonu, dosyadan n byte okumaktadr. public abstract int Read (byte[] buffer, int offset, int count) Fonksiyonun birinci parametresi, okunan bytelarn yerletirilecei diziyi belirtir. kinic parametresi, bu dizide bir offset belirtmektedir. Yani okunacak bilgilerin dizinin hangi indexinden itibaren yerletirileceidir. Bu parametre tipik olarak 0 biiminde girilir. Son parametre okunacak byte saysdr. Snfn Write isimli abstract fonksiyonu, ters olarak bir byte dizisi ierisindekileri dosyaya yazar. public abstract void Write(byte[] buffer, int offset, int count) Fonksiyonun birinci parametresi, yazdrlacak olan bilginin bulunduu diziyi, ikinci parametresi dizide bir indexi(yazdrma bu indexten itibaren yaplacaktr) ve son parametresi de yazlacak byte says belirtmektedir. Ayrca Stream snfnn 1 byte yazan ve okuyan ReadByte ve WriteByte fonksiyonlar da vardr: public virtual int ReadByte() public virtual void WriteByte (byte value)

DOSYA GSTERCS KAVRAMI Dosya gstericisi, o anda dosyann hangi offsetinden okuma ya da yazma yaplacan belirten bir saydr. lk byte 0 olmak zere, dosyann her bir bytena bir offset numaras karlk getirilmitir. Okuma ve yazma ilemleri, o offset numarasndan itibaren yaplr. Dosya gstericisinin konumu, otomatik olarak okunan ya da yazlan byte miktar kadar ilerletilmektedir. Dosya gstericisinin, dosyadaki son bytedan bir sonraki byte gstermesi durumuna(yani olmayan byteyi gstermesi durumu) EOF denir. EOF durumunda okuma yaplamaz. Ama yazma yaplabilir(yazma hakkmz varsa). Yazma ekleme anlamna gelir. Dosya gstericisinin konumlandrlmas iin Stream snfnn Position property eleman kullanlabilir. Bu property long trdendir ve Read Write propertydir.

190

using using using using

System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read); fs.Position = 10; byte[] b = new byte[5]; fs.Read(b, 0, 5); string s = Encoding.ASCII.GetString(b); Console.WriteLine(s); } } }

DOSYANIN KAPATILMASI Dosyay kapatmak iin Stream snfnn parametresiz Close fonksiyonu kullanlr. Alan her dosya kapatlmaldr. BYTE DZSNDEN DNTRME YAPAN FONKSYONLAR Elimizde bir byte dizisi varsa onun ierisindeki bilgileri istediimiz tre dntrebiliriz. Bunun iin BitConverter snfnn ToXXX(xxx=int,char vs...) fonksiyonlar kullanlr. Bu fonksiyon parametre olarak byte dizisini alrlar. Geri dn deeri olarak dntrlm deeri verirler. Bu ilemin tam tersi de yaplmak istenebilir. Yani rnein elimizde bir int deer bulunabilir. Biz bunu 4 byte halinde bir byte dizisine yazmak isteyebiliriz. Bunun iin BitConverter snfnn GetBytes fonksiyonlar kullanlmaktadr. Bu fonksiyonlar, parametre olarak bytea dntrlecek tr trnden deer alrlar. Kendi ilerinde bir byte dizisi yaratrlar ve bu byte dizisi ile geri dnerler. Anahtar Notlar Elimizde int trden bir say olsun. Biz bu sayy bir dosyaya yaz olarak yada binary bir biimde 4 byte lik bir dizi olarak yazabiliriz. Yaz olarak yazarsak bir editrle kolay bir biimde grrz. Fakat yaz olarak yazmak tercih 191

edilmeyebilir. Biz onu binary olarak yazarsak her zaman 4 byte olarak yer kaplayacaktr. rnein bir dosyaya bir sayy yazp okuyan program yle yazlabilir: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite); int i = 123456; byte[] b = BitConverter.GetBytes(i);//int ten byte
dntrme

fs.Write(b, 0, 4); // 4 byte yazd fs.Position = 0; //dosya gstericisi tekrar baa alnd byte[] x = new byte[4]; fs.Read(x, 0, 4); // x dizisine 4 byte bilgi okundu int val = BitConverter.ToInt32(x, 0);//byte int te
dntrld

Console.WriteLine(val); fs.Close(); } } } Bir byte dizisini stringe, bir stringi byte dizisine dntrmek iin, yaznn hangi formata ilikin olduunun bilinmesi gerekir. Yaz her bir karakteri 1 byte olan ASCII karakterlerden oluabilir. Unicode UTF8 formatta ya da baka bir formatta da olabilir. O halde konu bir Encoding konusudur. te bu ilem iin Encoding snfnn Encoding trnden ASCII, UTF8 gibi elemanlar kullanlr. Daha sonra dntrme ilemi bu snfn GetBytes ve GetString fonksiyonlar ile yaplr. rnein: using using using using System; System.Collections; System.IO; System.Text; 192

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read); byte[] b = new byte[10]; fs.Read(b, 0, 10); string s = Encoding.ASCII.GetString(b); Console.WriteLine(s); fs.Close(); } } } Grld gibi FileStream snf ile byte dizisi okuyup byte dizisi yazabiliriz. Yani bu snf bize ok rahat bir alma olana sunmaz. DOSYA LEMLERN KOLAYLATIRAN YARDIMCI SINIFLAR Aslnda her trl dosya ilemi byte okuyup yazan Read ve Write fonksiyonlar ile yaplabilir. Fakat programcnn bu fonksiyonlar kullanarak fazlaca kod yazmas gerekir. Halbuki bir takm adaptr snflar bir Stream referans alarak okbiimli bir biimde Read ve Write fonksiyonlarn kullanarak bu ilemleri yapabilmektedir. -StreamReader ve StreamWriter Snflar StreamReader ve StreamWriter snflar, bir Stream nesnesini alarak yetenekli text dzeyinde okuma ve yazma ilemlerini yapar. Bu snflar TextReader ve TextWriter snflarndan tretilmitir.
TextReader TextWriter

StreamReader

StreamWriter

Bir StreamReader nesnesi aadaki balang fonksiyonlar ile oluturulabilir: public StreamReader (Stream stream) Bu durumda nesne yle oluturulabilir: FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read); 193

StreamReader sr = new StreamReader(fs); StreamReader ve StreamWriter snflarnn Close fonksiyonlar, kullandklar gerek Stream kaynan da kapatmaktadr: sr.Close(); Bu ilemle kullanlan FileStream nesnesi de kapatlr. StreamReader snfnn string geri dn deerine sahip ReadLine isimli fonksiyonu dosya gstericisinin gsterdii yerden itibaren bir satrlk bilgiyi okur. Eer dosya sonuna gelinirse fonksiyon null deeri geri dner. Bu durumda bir text dosyay satr satr okuyup ekrana yazdran program yle olabilir: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs); string line; while ((line = sr.ReadLine()) != null) Console.WriteLine(line); sr.Close(); } } } StreamReader snfnn ReadToEnd isimli fonksiyonu dosya gstericisinin gsterdii yerden itibaren dosya sonuna kadar tm karakterleri okur ve bir string biiminde geri verir: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD 194

{ class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs); string s = sr.ReadToEnd(); Console.WriteLine(s); sr.Close(); } } } StreamReader default olarak dosyadaki karaterlerin Unicode UTF8 kodlamasna ilikin olduunu varsaymaktadr. Tabi bir yazdaki karakterler hep ingilizce karakterlerden oluursa Unicode UTF8 kodlamas ile ASCII kodlamas arasnda bir fark kalmaz. stenirse StreamReader ve StreanmWriter snflarnn iki parametreli balang fonksiyonlar ile encoding belirtilebilir: StreamReader sr = new StreamReader(fs, Encoding.ASCII); StreamWriter snf benzer amala kullanlmaktadr. StreamWriter snfnn her trden parametreli Write ve WriteLine fonksiyonlar vardr. Bu fonksiyonlar, saysal deerleri yaz biiminde dosyaya yazar. rnein: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); for (int i = 0; i < 100; ++i) sw.WriteLine(i); sw.Close(); } } } 195

phesiz string parametreli Write ve WriteLine fonksiyonlar da vardr. rnein: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("Ankara"); sw.WriteLine("Izmir"); sw.Close(); } } } BinaryReader ve BinaryWriter SINIFLARI Bu snflar eitli saysal deerleri dosyaya yaz olarak deil binary biimde bir byte dizisi olarak yazp okurlar. Bu snflar da bir Stream referans alarak aslnda Stream snfnn Read ve Write fonksiyonlarn kullanr. Benzer biimde bu fonksiyonlarn Close fonksiyonlar da aldklar string nesnesini kapatmaktadr. rnein; BinaryReader nesnesi yle yaratlabilir: FileStream fs = new FileStream(...); BinaryReader br = new BinaryReader(); BinaryReader snfnn ReadXXX biiminde parametresiz fakat geri dn deeri XXX trnden olan bir grup fonksiyonu vardr. Bu fonksiyonlar dosyadaki byte topluluunu okuyup, onu XXX trne dntrerek vermektedir. Benzer biimde BinaryWriter snfnn da her trden parametre alan Write fonksiyonlar vardr. Bunlar tpk StreamWriter gibi yazma yaparlar. Fakat yazmay yaz olarak deil Binary dzeyde gerekletiriler. rnein: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD 196

{ class App { public static void Main() { FileStream fs = new FileStream("test.dat", FileMode.Open, FileAccess.ReadWrite); BinaryReader br = new BinaryReader(fs); int val = br.ReadInt32(); Console.WriteLine(val); br.Close(); } } } Bazen bir snfn tm elemanlarn dosyaya yazp okumak gerekebilir. Bu ilemi seri hale getirmek dnda, pratik olarak yapmann bir yolu yoktur. Tipik olarak snfn ierisine, Read ve Write gibi iki fonksiyon yerletirilebilir Bu fonksiyonlar okuma ve yazmay yapabilirler. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { FileStream fs = new FileStream("test.dat", FileMode.Create, FileAccess.ReadWrite); BinaryWriter bw = new BinaryWriter(fs); BinaryReader br = new BinaryReader(fs); Person a = new Person("Kaan Aslan", 123); a.Write(bw); fs.Position = 0; Person b = new Person(); b.Read(br); b.Disp(); bw.Close(); br.Close(); } } 197

class Person { private string m_name; private int m_no; public Person() { } public Person(string name, int no) { m_name = name; m_no = no; } public void Disp() { Console.WriteLine("{0} {1}", m_name, m_no); } public void Write(BinaryWriter bw) { bw.Write(m_name); bw.Write(m_no); } public void Read(BinaryReader br) { m_name = br.ReadString(); m_no = br.ReadInt32(); } } } AMADAN YAPILAN DOSYA LEMLER System.IO isim alanndaki File isimli snfn pek ok static fonksiyonu vardr. Bu static fonksiyonlar dosya silme, isim deitirme, tama, kopyalama gibi temel ilemleri yapmaktadr. Ayrca File snfnn static Create, Open gibi fonksiyonlar da vardr. Bunlar FileStream snfn kullanarak dosya yaratm yapmaktadr. Exception LEMLER Exception terimi, beklemedik bir biimde programn alma zaman srasnda bir hata durumu ortaya kmasdr. .Net ortamnda snflarn fonksiyonlar, sorunlarla karlanca exception oluturmaktadr. Eer bu exception ele alnmazsa, programn almasn sonlanr. Exception ilemleri programn eitli yerlerinde oluan hatalarn, belirli yerlerde kontroln salamak iin kullanlr. Yani programc hata nerede km olursa olsun, akn belirli bir noktaya ekilip kontroln orada yaplmasn salayabilir. Exception ilemleri iin try, catch, finally, throw anahtar szckleri kullanlr.

198

Try anahtar szcn, bir blok izlemek zorundadr. Buna try blou denir. Try blounu bir ya da birden fazla catch blou izler. Catch anahtar szcnden sonra parantezler ierisine, catch parametre bildirimi yaplr. Catch parametresi ilikin tr bilgisi yazlmak zorundadr. Fakat catch parametre deikeni yazlmak zorunda deildir. try { //... } catch(<tr>[parametre deikeni]) { //... } catch(<tr>[parametre deikeni]) { //... } Programn ak try blouna girdikten sonra, kana kadar ak bakmndan try blounun ierisindedir. System.Exception snf ya da bu snftan dorudan ya da dolayl olarak tretilen snflara, exception snflar denir. rnein: System.Exception

Exception mekanizmasn tetikleyen, throw anahtar szcdr. Throw anahtar szcnn genel biimi yledir: throw [exception snf referans]; rnein; MyException isimli snf, Exception snfndan tretilmi olsun: throw new MyException(); Programn ak try blouna girdikten sonra, herhangi bir yerde throw ilemi oluursa ak, bir goto ilemi gibi son girilen try blounun uygun catch blouna aktarlr. O catch blou altrldktan sonra, dier catch bloklar 199

atlanarak ak, catch bloklarndan sonra devam eder. Try blou ile catch bloklar arasna baka bir deyim yazlamaz. void Foo() { //... try {

Foo(); } if (someting_going_wrong) catch(<tr>[parametre deikeni]) throw new MyException { //... //... } catch(<tr>[parametre deikeni]) { //... }

Burada Foo() fonksiyonu ierisinde throw ilemi gerekleirse, ak goto ilemi gibi MyException parametreli catch blouna aktarlr. .Net ktphanesindeki snflarn fonksiyonlar sorunla karlaldnda, hep exception snflaryla throw ilemi yaplmaktadr. Bir fonksiyonun hangi durumda hangi snf ile throw yapaca, MSDN dkmanlarnda exception alt balnda listelenmektedir. O halde bir ktphane fonksiyonu arlrken hatay ele alabilmek iin arm try-catch blou ierisinde yapmak gerekir. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { int val; try { val = int.Parse(Console.ReadLine()); Console.WriteLine(val); } catch (ArgumentNullException ane) { Console.WriteLine("Arguman null deerinde!.."); } catch (FormatException fe) { 200

Console.WriteLine("Bilgi saysal karakterlerden olumuyor!.."); } catch (OverflowException of) { Console.WriteLine("Say snr dnda!.."); } } } class MyException : Exception { //... } class YourException : Exception { //... } }

Oluan bir exception iin uygun bir catch bulunamazsa thread sonlandrlr. Bu durum tek threadl programlarda, programn sonlandrlaca anlamna gelir. Programn ak i ie birden fazla try blouna girmi olsun. bloklarda bir throw ilemi olursa, iten da doru uygun catch bloklar taranr. Yani nce en iteki try blounun catch bloklarna baklr. Orada uygun catch blou bulunamazsa bir nce girilen try blounun catch bloklarna baklr. Bu biimde en yukarya kadar klr. Nihayet en dta da uygun catch blou da bulunamazsa thread sonlandrlr. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { Foo(); //... } catch (OverflowException of) { 201

Console.WriteLine("Say snr dnda!.."); } } public static void Foo() { try { int val = int.Parse(Console.ReadLine()); Console.WriteLine(val); } catch (ArgumentNullException ane) { Console.WriteLine("Arguman null deerinde!.."); } catch (FormatException fe) { Console.WriteLine("Bilgi saysal karakterlerden olumuyor!.."); } } } class MyException : Exception { //... } class YourException : Exception { //... } } Nasl tremi snf referans, taban snf referansna atanabiliyorsa, tremi snf trnden throw ilemi yapldnda, bu throw ilemi taban snf trnden bir catch blou ile yakalanabilir. Yani rnein biz oluacak tm exceptionlar aslnda, exception parametreli bir catch blou ile yakalayabiliriz. .Net ktphanesindeki Exception snflar, bir tretme aacna sahiptir. rnein; dosya ilemleri srasnda frlatlan tm Exception snflar System.IO snfndan tretilmitir. System.IO snf da dolayl olarak System. Exception snfndan tretilmitir. Taban snf ve tremi snfa ait catch bloklar bir arada kullanlabilir. Bu durumda tremi snf trnden exception frlatldnda, bunu tremi snf catch blou yakalayacaktr. Fakat derleyici, catch bloklarn srasyla tarad iin ve ilk uygun catch blou bulunduunda ilemi sonlandrd iin sralama nemlidir. Tremi snfa ilikin catch blounun taban snfa ait catch blounun daha yukarsnda oluturulmas zorunludur. Aksi durumda derleme zamannda error oluur. 202

Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { int val = int.Parse(Console.ReadLine()); string s = null; int n = s.Length; Console.WriteLine(val); } catch (ArgumentNullException ane) { Console.WriteLine("Arguman null deerinde!.."); } catch (FormatException fe) { Console.WriteLine("Bilgi saysal karakterlerden olumuyor!.."); } catch (OverflowException of) { Console.WriteLine("Say snr dnda!.."); } catch (Exception e) { Console.WriteLine("dier..."); } } } class MyException : Exception { //... } class YourException : Exception { //... } }

203

SIK KARILAILAN exception SINIFLARI Bir referansa, henz deer atamadan referans kullanlamaz. Fakat referansa null deer atayp referans kullanlrsa, program baarl olarak derlenir. ancak alma zaman srasnda, ak kullanm noktasna geldiinde NullReferanceException oluur. Anmsanaca gibi aralarnda tretme ilikisi olmayan snflar arasnda, tr dntrme operatr ile bile dntrme yaplamaz. Fakat tretme ilikisi olduu durumda derleme aamas baarl bir biimde sonlanr. Fakat programn alma zaman srasnda hakllk kontrol yaplr. te dntrme haksz ise InvalidCastException isimli exception frlatlmaktadr. rnein: Object

object o = new A(); B b = (B)o; InvalidCastException

finally BLOU finally blou parametre iermez. nein: finally { //... } finally blou kullanlacaksa, catch bloklarnn sonunda olmak zorundadr. rnein: try { //... } catch(Exception e) { //... } finally { //... 204

} try bloundan sonra, hi catch blou bulunmadan finally blou bulunabilir. rnein: try { //... } finally { //... } finally blou her zaman altrlr. Akn try blouna girdiini dnelim. Fakat hi exception olumam olsun. Bu durumda finally blou altrldktan sonra ak devam eder. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { Console.WriteLine("try block"); } catch (Exception e) { Console.WriteLine("dier..."); } finally { Console.WriteLine("finally"); } Console.WriteLine("ends..."); } } class MyException : Exception { //... } class YourException : Exception 205

{ //... } } Try blouna girdikten sonra bir exception olusun ve oluan exceptionun bir catch blou tarafndan yakalandn dnelim. Catch blou altrldktan sonra finally blou da altrlr. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { int.Parse("ggjhgj"); } catch (Exception e) { Console.WriteLine("dier..."); } finally { Console.WriteLine("finally"); } Console.WriteLine("ends..."); } } class MyException : Exception { //... } class YourException : Exception { //... } } finally blmn catch blmlerinden sonra yazlanlardan ne fark vardr? Yani madem ki finally blou her zaman altrlacaktr burada yaplacaklar catch bloklarndan sonraya yerletiremez miyiz? try blounda bir exception olumu olsun. Fakat bu exception i try blounun catch 206

bloklar tarafndan yakalanmam olsun. te bu durumda d try bloklarnn catch bloklar taranmadan nce i try blounun finally blou altrlr. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { Func(); } catch (Exception e) { Console.WriteLine("D catch"); } Console.WriteLine("ends..."); } public static void Func() { try { int.Parse("ggjhgj"); } finally { Console.WriteLine("i finally"); } } } class MyException : Exception { //... } class YourException : Exception { //... } }

207

Finally blm tipik olarak exception olutuunda, bir takm ilemleri geri almak iin gerekletirilir. rnein bir dosyann kapatlmas ilemi tipik olarak finally blmnde yaplmaldr. using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { FileStream fs = null; try { fs = new FileStream("test.dat", FileAccess.Read); //.. } catch (Exception e) { //... } finally { if (fs != null) fs.Close(); } } } } FileMode.Open,

Burada try blounun ierisinde bir exceptoion olusa ak, d catch bloklarna gitse bile finally blou altrlaca iin dosya kapatlr. Tabi exception balang fonksiyonu ierisinde de oluabilirdi. Bu durumda, fsnin ierisinde null deeri olduu iin almam doya kapatlamayacaktr. Anmsanaca gibi bir deikene deer atanmadan kullanlamaz. Aadaki durumda derleme zamannda error oluur: using using using using System; System.Collections; System.IO; System.Text; deiken

namespace CSD { class App { 208

public static void Main() { FileStream fs; try { fs = new FileStream("test.dat", FileAccess.Read); //.. } catch (Exception e) { //... } finally { fs.Close(); } } } } FileMode.Open,

Burada FileStream snfnn balang fonksiyonu ierisinde exception olutuunu varsayalm. Bu durunda fs deer almam olacaktr. Bu da error ile sonulanacaktr. zetle finally blmne, exception olusa da olumasa da her zaman yaplmas gereken eyler yerletirilmelidir. Try blounda goto, return gibi ak baka bir blgeye aktaran deyimler kullanlsa bile yine finally blm altrlr. Hocann rnei: using System; using System.Collections; using System.IO; using System.Text; namespace CSD { class App { public static void Main() { try { int val = int.Parse(Console.ReadLine()); if (val < 0) return; } finally { Console.WriteLine("finally"); } 209

EXIT: Console.WriteLine("The end..."); } } }

PARAMETRESZ catch BLOU Parametresi olmayan zel bir catch blou ancak dier catch bloklarnn en sonuna fakat finally bloundan nce yerletirilebilir. rnein: try { //... } catch(Exception e) { //.. } catch { //... } finally { //... } Parametresiz catch blou tm exceptionlar yakalar. Peki exception parametreli catch blou da tm exceptionlar yakalayamaz m? Exception snflarnn System.exception snflarndan tretilme zorunluluu .Net geneline zg deil, yalnzca C#a zgdr. rnein biz C++.Nette herhangi bir snf ile throw ilemi yapabiliriz. te biz C++.Nette yazlm ve byle bir snf ile throw eden bir fonksiyonu C#tan ardmzda bu exception, exception parametreli catch blou tarafndan yakalanamaz. Ancak parametresiz catch blou tarafndan yakalanr. Yani parametresiz catch blou, exception parametreli catch blounu kapsamaktadr. YENDEN throw LEM Oluan bir exceptionu catch blounda yakalam olalm. Eer yakalamam olsaydk, srasyla d try bloklarnn catch bloklar da taranacaktr. te bazen bir exceptionu ksmen ileyip sanki onu hi yakalamam gibi bir durum oluturmak isteriz. Yani exceptionu ayn ekilde yeniden frlatp, d catch bloklarnn ilemesini salamak isteyebilir. Bunun iin throw anahtar szcnn yanna hibir ifade yazlmadan ; ile kapatlr.

210

rnein: try { Foo(); } catch(MyException e) { //... throw; } Bu durumda yine finally blou altrlacaktr.

System.Exception SINIFI Anmsanaca gibi btn exception snflar System.Exception snfndan tretilmitir. Bu snfn en nemli eleman Message isimli property elemandr: public virtual string Message {get;} Grld gibi bu property virtual bir propertydir. Tremi snflarda bu Message propertyleri kendi mesajlarn dndrecek ekilde override edilmitir. Bu durumda biz bir exceptionu, exception snf ile yakalarsak ok biimli bir biimde exceptionu oluturan mesaj elde edebiliriz. rnein: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { try { int val = int.Parse("xxxx"); // FormatException //... } catch (Exception e) { Console.WriteLine(e.Message); // Format.Exception.Message arlr } } 211

} }

sealed SINIFLAR Bir snf bildiriminin nne sealed anahtar szc getirilebilir. rnein: public sealed class Sample { //... } sealed snflarda tretme yaplamaz. Programc tretmenin anlaml olmad durumlarda snf sealed yaparak okunabilirlii arttrabilir. Static SINIFLAR Bir snf, static anahtar szc getirilerek static yaplabilir. rnein: Static class Sample { //... } Static bir snf, yalnzca static elemanlara sahip olabilir. rnein System.Math snfnn tm elemanlar statictir. phesiz static snf trnden nesne new operatr ile yaratlamaz. sealed override FONKSYONLAR sealed anahtar szc, fonksiyonlar iin de kullanlabilir. Ancak bu durumda fonksiyonun override bir fonksiyon olmas gerekir. sealed anahtar szc static, virtula ya da abstract fonksiyonlarla kullanlamaz. rnein: class A { public virtual void Func() { //... } //... } class B : A { public sealed override void Func() { //... } } 212

sealed override bir fonksiyon, ilikin olduu snftan bir snf tretilse bile override edilemez. rnein: using using using using System; System.Collections; System.IO; System.Text;

namespace CSD { class App { public static void Main() { try { int val = int.Parse("xxxx"); // FormatException //... } catch (Exception e) { Console.WriteLine(e.Message); // Format.Exception.Message arlr } } } class A { public virtual void Func() { //... } //... } class B : A { public sealed override void Func() { //... } } class C : B { public override void Func() { //... } } } 213

New belirleyicisi Taban ve tremi snflarda, ayn isimli elemanlarn bulunmas yasaklanmamtr. Bu durumda tremi snf ierisinden ya da tremi snf referans ile yaplan eriimlerde, tremi snftaki isim taban snftaki ismi gizler. te bu tr durumlarda, derleyici bir uyar mesajyla durumu bildirmektedir. rnein: class A { public int m_x; //... } class B : A { public int m_x; //... }

//uyar!

phesiz taban snftaki elemann gizlenmesi ancak taban snftaki eleman public ya da protected ise sz konusudur. rnein: class A { private int m_x; //... } class B : A { public int m_x; //... }

//uyar yok !

Bdeki elemann Adakini gizlemesi sz konusu olmad iin bu durumda uyar verilmeyecektir. Gizleme iin taban snftaki elemann public ya da protected blmde olmas gerekir. new belirleyicisi, eriim belirleyicisi anahtar szckle ve abstract , virtual ve static belirleyicilerle ayn syntax grubundadr. new belirleyicisi gizleme durumunda, uyary kesmek iin kullanlr. rnein: class A { public int m_x; //... } class B : A { 214

public new int m_x; //uyar yok! //... } Bir gizleme durumu sz konusu deilse, new belirleyicisinin kullanm da uyarya yol aar. Taban snfla tremi snfta ayn isimli fonksiyonlarn bulunmas, her zaman gizleme oluturmaz. nk farkl parametrik yaplara ilikin, ayn isimli fonksiyonlar bulunabilir. rnein: class A { public void Func(string a) { //... } } class B : A { public void Func(int a) //uyar yok { //... } } Fakat taban snfta ve tremi snfta ayn isimli ve ayn parametrik yapya ilikin fonksiyonlar varsa, burada bir gizleme sz konusudur. new belirleyicisi ile uyary kesebiliriz. rnein: class A { public void Func(int a) { //... } } class B : A { public new void Func(int a) { //... } }

//uyar yok

Taban snftaki virtual bir fonksiyon, tremi snfta normal ya da virtual olarak bildirilirse, bu durum override etmek anlamna gelmez. Bu durumda tremi snfta yeniden bir sanallk balatlm olur. rnein: class A { public virtual void Func(string a) 215

{ //... } } class B : A { public virtual void Func(int a) { //... } } Ya da rnein: class A { public virtual void Func(string a) { //... } } class B : A { public void Func(int a) //uyar var { //... } } rnein: A a = new B(); a.Func(); A daki Func arlr.

//uyar var

216

You might also like