You are on page 1of 486

Derleme: TD Software

Her Ynyle ilk C# Programmz

C# dili ortaya kal daha hi birey yapmayan varsa ya da bireyler yapp da ne


yaptndan emin olmayan varsa ite bu yaz tam size gre. Bu yazmzda klasik Merhaba
Dnya programmz yazacaz.Ama programmz yazarken her eyi adm adm
reneceiz. Unutmayn amacmz burada Merhaba Dnya yazmak deil. :) O halde
aadaki program iyice inceleyin nce, yle bir szn program yukardan aaya,
fazla detaylara inmeden yazmz okumaya devam edin;

//dosya ad : Merhaba.cs

using System;

namespace MerhabaDunya

{
class Snf1
{
static void Main(string args[])
{
Console.WriteLine("Merhaba Dnya");
}
}
}

Yukardaki ilk programmz incelediinize gre aklamalarmza geebiliriz. Eer nceden


C++ ve Java ile ilgilenmi arkadalar varsa yukardaki kodlar tandk gelebilir. Nitekim,
her ne kadar Microsoft firmas ilk balarda bunu kabul etmese de C# dili Java ve C++
dillerinin harmanlanmasndan olumu bir dildir. Bugn bunu kabul etmeyen yoktur
sanrm.

Yukardaki ilk programmzn kodunu ben Notepad ile yazdm. Ama kodu derleyip
altrmak iin bir C# derleyicisine ihtiyacmz olacak. C# derleyicisi Visual Studio.NET ile
kurulabilecei gibi www.microsoft.com web sitesinden .NET Framework yazlmn
indirerek de kurulabilir. Eer Visual Studio ortamnda alyorsanz yukardaki kodlar
Visual Studio .NET ' in sunduu hazr proje ablonlarndan rahatlkla oluturabilirsiniz.
Visual Studio programn altrdktan sonra Project->New mensnden dil olarak Visual
C# ve proje ablonu olarak da "Console Application" seerseniz, main ilevi iindeki
kodlar dndaki yap otomatikmen oluturulacaktr.Eer .NET Framework yapsn
kurduysanz Console Ekranndan C# derleyicisini altrmalsnz. Komut ekrann <csc
Merhaba.cs> yazarak kaynak kodumuzu derleyebilirsiniz.

imdi kodlarmz inceleyelim. lk satrdaki <using System;> ifadesi System adl bir isim
alannn kullanlacan belirtiyor.Peki nedir bu isim alan(Namespace). simalan kavram
son yllarda program modllerinin ok sayda artmasndan dolay popler hale gelmitir.
Kolay ve hzl programlama yapmamz salayan bir takm hazr ktphaneler her ne
kadar iimizi kolaylatrsa da eer isimalanlar olmasayd kullanacamz her ktphane
bizim iin iin iinden klmaz bir hale gelebilirdi. Dnn ki iki ayr firma iki ayr snf
ktphaneleri oluturdu ve bu ktphanelerin iinde ayn isimli birden ok snf yaps var.
Eer biz programc olarak iki firmann da ktphanesini kullanmak istiyorsak her ikisini
ayn kod iinde kullanamayz. nk ayn isimli snflar derleme aamasnda hata
verecektir. Bu durumda yaplmas gereken tek ey ya da en etkili yntem isimalanlarn
kullanmaktr. Yani bir snfa(class) ulaabilmek iin onun isim alanyla armak. sim
alanlar hiyerarik yapda olabilir. Mesela System isim alannn altnda baka bir isim alan
onun altnda bakalar vs. te .NET isimalan(namespace) hiyerarisinin en tepesinde
bulunan isim alan System adl isimalandr. En temel ilemlerimiz iin bile bu isim alann
kullanmalyz. Aksi halde programmz almayacaktr. simalanlarn kullanmak iin
isimalannn bana using szc getirilir.

Soru: System isim alannn iinde Data isimalannda bulunan bir cs adl snf
kullanabilmek iin kaynak kodumuza ne eklememiz gerekir.

Cevap : Kaynak kodumuzun en bana aadaki ifadeyi yazmamz gerekir.

using System.Data;

Bildiiniz gibi C# dili %100 nesne tabanl bir dildir. Yaptmz herey bir snf nesnesidir
C# dilinde. Nesne olmayan hibirey yoktur. C++ dilindeki main ilevini hatrlarsnz
ounuz. Programmz c++ dilinde main ilevinden balar ama main ilevi hi bir zaman
bir snf iinde olmamtr.C# dilinde herey snflarla temsil edildii iin main ilevi de
bizim belirlediimiz bir snfn ilevi olmak zorundadr. Yukardaki programmzda <class
Snf1> ifadesi ile programmzda bir snf nesnesi oluturuyoruz. Snf1 snfnn bir ilevi
olan main'in elbette eskiden de olduu gibi zel bir anlam vardr. Biliyorsunuz ki
derleyiciler programn nerden alacan bilmek isterler, aksi halde derleme ileminden
sonra "programnz iin balama noktas bulunamad" hatas alrz. Bu yzden main ilevi
bizim iin eskiden de olduu gibi programmzn balang noktasdr. Yani biz programda
yapmak istediklerimizi main ilevi iinde gerekletireceiz. Snf tanmlamalarmz ise
istediimiz noktada yapabiliriz. Daha ncede dediimiz gibi isimalanlar birok snfn veya
tek bir snfn oluturduu kmedir. Bizim ana programmz da bir snf olduuna gre
Class1 snfn istediimiz isimli bir isimalanna sokabiliriz. Yukarda <namespace
MerhabaDunya> yazarak isimalann balatyoruz.

imdi main ilevinin iine bakalm, System isimalannda bulunan Console snfnn bir
metodu olan WriteLine() ile ekrana bir string ifadesi yazdryoruz. Biz burda iki trnak
ifadesi iinde yazmz belirtmemize ramen fonksiyonun kullanm bununla snrl deildir.
C# dilindeki fonksiyon ar ykleme (function overloading)kullanlarak fonksiyonu birok
parametrik yapda kullanabilmemiz salanmtr. Fonksiyon ar ykleme konusuna
bundan sonraki yazlarmzda deineceimizi belirtelim. WriteLine() ilevinin adndan da
anlalaca gibi ekrana basmak istediimiz yazdan sonra satr atlama ilemi yapar.Bunu
test etmek iin bir tane "Merhaba Dnya" da siz yazdrn. Greceksiniz ki siz
belirtmemenize ramen alt alta iki tane "Merhaba Dnya" yazs kacak.

Eer bu program yazp derlediyeseniz ne mutlu size ki C# dnyasna gzel bir adm
attnz.
Visual C# ile Windows Menleri Hazrlama

Merhaba, bu makalemizde, hemen hemen tm Windows uygulamalarnn temel yap ta


olan Windows menlerinin nasl hazrlandn ve basit bir uygulamasn adm adm
greceiz. Bildiiniz gibi Windows menlerini imdiye kadar Visual Basic ortamnda ok
basit bir ekilde yapmak mmknd. Ama artk Visual C# ile men hazrlamak hem daha
kolay hem de daha elenceli. Bu makalede yapacamz uygulamadaki amacmz, File ve
Edit blmnden oluan Windows mensn tek bir Windows butonuyla aktif ya da pasif
duruma getirmek.

imdi uygulamamzn ilk adm olan yeni proje oluturma sayfasn aalm.
File->New -> Project mensn kullanarak aadaki gibi yeni bir proje oluturalm.
Proje tipi olarak Visual C# Project, template olarak da Windows Application setikten
sonra projemize uygun isim verip OK butonuna tklayalm.

Projemizi oluturduumuzda Visual C# IDE 'sinin bizim iin bir balang formu
oluturduunu grrz. Bu form doal olarak u anda botur. Toolbox mensn
kullanarak Form zerine istediimiz kontrolleri srkle brak yntemiyle yerletirebiliriz.
Ya da istediimiz kontrol ift tklayarak da ayn ilevi gerekletirebiliriz. Eer toolbox
mensn gremiyorsanz ekrann sol alt kesinde bulunan
ToolBox ikonuna tklayn. imdi formumuza basit bir MainMenu kontrolu ekleyelim. Yine
ToolBox mensnden aadaki ikona ekline benzeyen ksma ift tklayn. Eer ilem
baarlysa formunuzun en st ksmnda edit edilmek zere bir men oluacaktr.

MainMenu zerine fare ile gelerek istediiniz men elemanlarn ekleyin.Ben nce File
elemann sonra Edit elemann ve Edit elemannn iinde de Copy ve Paste men
elemanlarn aadaki gibi oluturdum.

imdi men elemanlarmza Properties penceresinden isim verelim. Aada grdnz


pencereden form design penceresinden setiiniz elemanla ilgili zelliklere
ulaabilirsiniz.imdi Edit men elamanna tklayarak Properties ekranndaki name
zelliine "menuEdit" yazalm. Burda menu elemanna verdiimiz ismi daha sonra kod
yazarken kullanacamz iin aklmzda kalacak bir isim vermemiz dzenli kod yazmak iin
nemli bir sebeptir. Men elemanlaryla iimiz bittiine gre sra meny kontrol
edeceimiz butonu yerletirmeye geldi. ToolBox penceresinden "Buton" a ift tklayarak
forma bir buton yerletirelim .Daha sonra butona tklayp Properties penceresinden buton
ismi (Name) olarak "BizimButon " yazalm. BizimButon ' un text zelliine ise "MENU
PASF ET" yazsn yazalm. Bu yazy yazmamzn sebebi ise udur: Mene elemanlar
varsaylan olarak aktif durumdadrlar. Bu yzden meny pasif hale getirmek iin bu
yazy setik.
Evet,Form tasarm ilemi bitti. imdi sra geldi BizimButon ile menye aktif ve pasif
durumlar arasnda gei yaptrmak. Tabi asl ite imdi balyor.
Form zerindeki butona ift tklayarak kod yazma ekranna gelelim.

Grdnz gibi Visual C# bizim iin bir takm kodlar oluturdu. Biraz bu hazr kodlar
ana hatlaryla inceleyelim.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

Yukardaki kodlarla programmzn kullanaca bir takm sistemler derleyiciye bildiriliyor.

public class Form1 : System.Windows.Forms.Form

System.Windows.Froms.Form snfndan yeni bir Form1(bizim form) snf tretilerek bu


form iindeki elemanlar tanmlanyor.

private System.Windows.Forms.MainMenu mainMenu1;


private System.Windows.Forms.MenuItem menuFile;
private System.Windows.Forms.MenuItem menuEdit;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.Button BizimButon;
private System.ComponentModel.Container components = null;

private void InitializeComponent() ilevi ile Form1 snf iindeki elemanlarla ilgili ilk
ilemler yaplyor. Elemanlarn form zerindeki yeri ve elemanlara ait Properties
penceresinden tanmladmz btn zellikleri bu ilev ile yerine getirilir.

static void Main()


{
Application.Run(new Form1());
}
Uygulamamzn Form1 zerinden gerekletirileceini belirtir.

te bu da bizim kodumuz :

private void BizimButon_Click(object sender, System.EventArgs e)


{
if (menuEdit.Enabled)
{
menuEdit.Enabled=false;
BizimButon.Text="MENU AKTIF ET";
}
else
{
menuEdit.Enabled=true;
BizimButon.Text="MENU PASIF ET";
}
}

Bu kodu yazabilmek iin form design penceresinden BizimButon ift tklayarak


BizimButon_click() ilevinin iine geelim. Yukardaki kodda eer menuEdit aktifse pasif
duruma getiriyoruz ve BizimButon 'a da "MENU AKTIF ET" yazyoruz. Eer menuEdit
zaten pasifse Menuyu aktif hale getirip BizimButon yazsn da "MENU PASIF ET"
yapyoruz. Aada her iki durum iin programmzn kts mevcuttur.
C ve C++ bak asyla C# dili

Bildiimiz gibi bilgisayarlar programlamak iin programlama dillerine ihtiya duyulur.Bu


dillerden en poplerleri Basic,C,C++,Pascal,Java ve Assembler 'dr.Makina dili ise
donanm kontrol etmek iin donanm reten firma tarafndan tanmlanan komutlar
kmesidir. Baz programlama dilleri derleyicilere ihtiya duymasna karn bazlar ise
yorumlayclara ihtiya duyarlar, mesela bir c++ programn altrabilmek iin C++
derleyicisine ihtiyacmz varken, Perl ile yazlm bir CGI scripti iin komut yorumlaycsna
ihtiyacmz vardr. Derleyiciler program altrmadan nce kodlar makina komutlarna
evirirler fakat yorumlayclar bir grup kodu satr satr ya da bloklar halinde yorumlayarak
altrrlar.

Aslnda derleyiciler de, komut yorumlayclar da birer bilgisayar programndan baka


birey deildirler.Yani c ve c++ dilleri bir giri bekleyen ve k veren birer bilgisayar
programlar gibi dnlebilir.Giri olarak kaynak kodu veren bu programlar k olarak
ise makina kodu retirler.

C ve C++ dillerine ksa bir bak:

C dili en popler yapsal programlama dilidir.C dili Dennis Ritchie tarafndan, Martin
Richards ve Ken Thompson tarafndan gelitirilen BCBL ve B dillerinin temelleri zerine
kuruldu.

C dili "The C Programming Language by Brian Kernighan and Dennis Ritchie" kitabyla
bymtr.C dili iin, 1983 ylnn byk nemi vardr.nk 1983 ylnda ANSI
standartlar komitesi C standartlar iin toplanmtr.Bu standartlama sreci tam 6 yl
srmtr.Ve tabi ki u anki standartlarn oluumuna katkda bulunan ANSI 99
standartlar da dier nemli bir gelimedir.

C programclar tarafndan herhangi bir tr program gelitirmek iin yazlm genel amal
bir dildir. C ile bir dk seviyeli sistem iin program yazabileceimiz gibi, yksek seviyeli
bir GUI(Grafik Arabirimi) tasarlamamz da mmkndr.Ve elbette kendi ktphanemizi
de C ile oluturabiliriz.C dilinin ortaya kmasndan bunca yl gemesine ramen
poplaritesini hibir zaman kaybetmemitir. Gnmz programclar eitli amalar iin
programlarn gelitirirken C dili ile yazlm kaynak kodlarn kullanrlar.

Bjarne Stroustrup 1980 yllnda C++ dilini ortaya karmtr. C++ dili C temelli ve C nin
bir st kmesi olarak dnlebilir. C++ en popler nesne temelli programlama dilidir.
C++ dilinin ilk ismi "C with Classes"(C ile snflar) idi. C++ dili C diline nazaran daha etkili
ve gldr.Ve en nemli zelli ise C 'den farkl olarak nesne temelli bir dildir.u anda
C++ dili ANSI ve ISO kurulular tarafndan standartlatrlmtr. Bu standartlarn son
versiyonu 1997 ylnda yaynlanmtr.

C# diline ksa bir bak:

C#, gl, modern, nesne tabanl ve ayn zaman type-safe(tip-gvenli) bir programlama
dilidir.Ayn zamanda C#, C++ dilinin glln ve Visual Basic' in ise kolayln
salar.Byk olaslkla C# dilinin kmas Java dilinin kmasndan bu yana programclk
adna yaplan en byk gelimedir. C#, C++ 'n gcnden , Visual Basic 'in kolaylndan
ve Java 'nn da zelliklerinden faydalanarak tasarlanm bir dildir. Fakat unu da
sylemeliyiz ki, Delphi ve C++ Builder 'daki baz zellikler imdi C# 'da var. Ama Delphi
ya da C++ Builder hibir zaman Visual C++ ya da Visual Basic 'in poplaritesini
yakalayamamtr.

C ve C++ programclar iin en byk sorun, sanrm hzl gelitirememedir. nk C ve


C++ programclar ok alt seviye ile ilgilenirler.st seviyeye kmak istediklerinde ise
zorlanrlar.Ama C# ile artk byle bir dert kalmad.Ayn ortamda ister alt seviyede
isterseniz de yksek seviyede program gelitirebilirsiniz.C# dili Microsoft tarafndan
gelitirilen .NET paltformunun en temel ve resmi dili olarak lanse edilmitir.C# dili Turbo
Pascal derleyicisini ve Delphi 'yi oluturan takmn lideri olan Anders Heljsberg ve
Microsoft'da Visual J++ takmnda alan Scott Wiltamuth tarafndan gelitirilmitir.

.NET framework'nde bulunan CLR (Common Language Runtime), JVM (Java Virtual
Machine)' ye, garbage collection, gvenilirlik ve JIT (Just in Time Compilation)
bakmndan ok benzer.

CLR, .NET Framework yapsnn servis salama ve alma zamannn kod organizasyonu
yapan ortamdr. CLR, ECMA standartlarn destekler.

Ksacas C# kullanmak iin CLR ve .NET Framework snf ktphanesine ihtiyacmz vardr.
Bu da demek oluyor ki C#, JAVA, VB ya da C++ deildir. C,C++ ve JAVA 'nn gzel
zelliklerini barndran yeni bir programlama dilidir. Sonu olarak C# ile kod yazmak hem
daha avantajl hem daha kolay hem de etkileyicidir.

Bir baka yazda bulumak midiyle ...


C#'da fadeler, Tipler ve Deikenler

Bu derste C# dilindeki ifadeler,tipler ve deikenler anlatlacaktr.

Dersimizin hedefleri :

Deiken kavramnn anlalmas.


C# dilinde bulunan basit tiplerin renilmesi.
C# dilindeki ifadelerin temel olarak anlalmas.
String veri tipinin renilmesi.

Deikenleri en sabit ekilde verilerin depoland yerler olarak tanmlayabiliriz.


Deikenlerin iine verilerimizi koyabilirirz veya deikenlerimizin iindeki verileri C#
programndaki ilemlerimiz iin kullanabilliriz. Deikelerin tipini belirleyen faktr,
onlarn ierdikleri verilerin eitleridir.

C# dilinde kullanacamz her deikenin bir tipi olmak zorundadr ( Vbscript ve


JavaScript gibi dillerde deiken tanmlarken onun tipini de ayrca belirtmeye gerek
yoktur.) Bir deiken zerinde yaplan tm ilemler de onun hangi tipte bir deiken
olduu gz nne alnarak yaplr. Bylece programda btnlk ve gvenlik korunmu
olur.

Boolean ( doru/yanl ), ve saysal veri tipi; integer( tamsay ), floating point


(ondalkl say ) ve decimal( muhasebe ve finansal ilemler iin) C# dilinin en basit veri
tipleri olarak saylabilir.

Kod 1 : Boolean deerlerin grntlenmesi : Boolean.cs

using System;

class Booleans

public static void Main()


{

bool content = true;

bool noContent = false;

Console.WriteLine("It is {0} that C# Station provides C# programming language


content.", content);

Console.WriteLine("The statement above is not {0}.", noContent);

Yukardaki Kod 1de de grlecei gibi boolean deikenler ya true(doru) veya


false(yanl) deerlerini alabilirler. Programn kts yle olacaktr.

>It is True that C# Station provides C# programming language content.


>The statement above is not False.

Aadaki tablo tamsay tiplerini, boyutlarn ve alabilecekleri deer aralklarn


gstermektedir.

Type Size (in bits)


Range (aralk)
( Tip ) (boyut )
sbyte 8 -128 to 127
byte 87 0 to 255
short 16 -32768 to 32767
ushort 16 0 to 65535
int 32 -2147483648 to 2147483647
uint 32 0 to 4294967295
long 64 -9223372036854775808 to 9223372036854775807
ulong 64 0 to 18446744073709551615
char 16 0 to 65535

Tamsay tipleri ksuratsz ilemler iin ok elverilidirler. Fakat char( karakter) tipi
Unicode standartlarna uygun olarak bir karakteri temsil eder. Yukardaki tablodan da
greceiniz gibi elimizde ok sayda tamsay tipimiz vardr. Bunlardan istedikleriminizi
ihitiyalarmza gre rahata kullanabiliriz.

Bir sonraki tablo ise ondalk (floating point ) ve decimal veri tiplerini,boyutlarn,
hassasiyetlerini ve geerli olduklar aralklar listeler.

Type Size (in bits)


Precision Range
( Tip ) (boyut )
float 32 7 digits 1.5 x 10-45 to 3.4 x 1038
Double 64 15-16 digits 5.0 x 10-324 to 1.7 x 10308
Decimal 128 28-29 decimal places 1.0 x 10-28 to 7.9 x 1028

Ondalkl saylar ksuratl ilemlerde kullanmak iyi olur. Bunun yannda muhasebe ve
finansal ilemler iin decimal veri tipi daha uygun olacak ekilde tasarlanmtr.

Bilgisayar programlar ilemleri yaparken ifadeleri kullanrlar ve sonu ortaya kartrlar.


Programlarda yer alan ifadeler deikenler ve ilelerden ( operatr) oluurular. Bir
sonraki tabloda ileleri, ilelerin ilem sralarn ve ileme ynlerini grebilirsiniz.

Category Associativity(ieme
Operator(s) (ile/ileler)
( kategori) yn)
(x) x.y f(x) a[x] x++ x-- new typeof sizeof
Primary left
checked unchecked left Unary + - ! ~ ++x --x (T)x
Multiplicative * / % left
Additive +- left
Shift << >> left
Relational < > <= >= is left
Equality == != right
Logical AND & left
Logical XOR ^ left
Logical OR | left
Conditional
&& left
AND
Conditional
|| left
OR
Conditional ?: right
Assignment = *= /= %= += -= <<= >>= &= ^= |= right

Sol ileme yn demek ilemlerin soldan saa doru yaplddr. Sa ileme yn


demek ilemlerin sadan sola doru yaplddr. Mesala atama ilelerinin hepsinde
nce sa tarafn sonucu bulunur ve bu sonu sol tarafa aktarlr.

Kod 2 : Unary Operators: Unary.cs

using System;

class Unary
{
public static void Main()
{
int unary = 0;
int preIncrement;
int preDecrement;
int postIncrement;
int postDecrement;
int positive;
int negative;
sbyte bitNot;
bool logNot;
preIncrement = ++unary;
Console.WriteLine("Pre-Increment: {0}", preIncrement);

preDecrement = --unary;
Console.WriteLine("Pre-Decrement: {0}", preDecrement);

postDecrement = unary--;
Console.WriteLine("Post-Decrement: {0}", postDecrement);

postIncrement = unary++;
Console.WriteLine("Post-Increment: {0}", postIncrement);
Console.WriteLine("Final Value of Unary: {0}", unary);

positive = -postIncrement;
Console.WriteLine("Positive: {0}", positive);

negative = +postIncrement;
Console.WriteLine("Negative: {0}", negative);

logNot = false;
logNot = !logNot;
Console.WriteLine("Logical Not: {0}", logNot);

fadeler ilemler yaplrken arka-artrma ve arka-azaltma ileleri nce deikenin


deerini dndrr sonra deiken zerinde artrma veya azaltma ilemini yapar. Dier
taraftan, n-artrma ve n-azaltma ileleri nce deiken zerinde artrma veya
azaltma ilemini yapar sonra deikenin son halini dndrr.

Kod 2de unary (tek) deiken nce sfr olarak atanyor. n-artrma (pre-increment)
ileci uygulandnda, unary deikenin deeri 1e kyor ve preIncrement
deikenine atanyor. Hemen arkasnda n-azaltma(pred-decrement) ileci sayesinde
unary deikenimiz tekrar sfr deerini alyor preDecrement deikenine bu deer
atanyor.

Arka-azaltma (post-decrement) ileci unary deikenimize uygularsak bu


deikenimizin deeri deiiyor ama nce deikenin ilk deeri postDecrement
deikenine atanyor. Sonra ise arka-artrma (post-increment) ilecini uygularsak unary
deikenimizin deeri azalyor fakat postIncrement deikenin deeri unary
deikenimizin ilk deeri olarak kalyor.

Mantksal deil iareti, doru ifadeyi yanl, yanl ifadeyi ise doru olarak deitirir.
Kod 2inin kts yle olacaktr :

>Pre-Increment: 1
>Pre-Decrement 0
>Post-Decrement: 0
>Post-Increment -1
>Final Value of Unary: 0
>Positive: 1
>Negative: -1
>Logical Not: True

Kod 3. Binary Operators: Binary.cs

using System;

class Binary
{

public static void Main()


{
int x, y, result;
float floatResult;

x = 7; y = 5;

result = x+y;
Console.WriteLine("x+y: {0}", result);

result = x-y;
Console.WriteLine("x-y: {0}", result);

result = x*y;
Console.WriteLine("x*y: {0}", result);

result = x/y;
Console.WriteLine("x/y: {0}", result);

floatResult = (float)x/(float)y;
Console.WriteLine("x/y: {0}", floatResult);

result = x%y;
Console.WriteLine("x%y: {0}", result);

result += x;
Console.WriteLine("result+=x: {0}", result);

Kod 3: te birok aritmetik ilemler yaplyor. Bu ilemlerin sonucunu da sizler tahmin


edebilirsiniz...

floatResult deikenin tipi ondalkl say tipi olduu ve x ve y deikenlerimiz


tamsay tiplerinde olduklar onlar ak biimde ondalkl say tipine evirdik ( explicitly
cast ) ve bu ekilde ilem yaptk.
Yukardaki kod parasnda bir de kalan (remainder % ) ilecinin kullanlna dair rnek
verdik. Bu ile, iki saynn blmnnden kalan sayy sonu olarak dndrr.

Son olarak yazdmz ifadede yeralan atama ileci de (+=) C/C++ ve C#


programclarnn sklkla kullandklar bir atama ve ilem yapma trdr. Bu ifade
aslnda u ifadenin ksa yoludur : result = result + x.

imdiye kadar burada ska grdnz dier veri tipi ise string ( karakter dizisi veya
karakter katar)dir. String veri tipi Unicode karakter tiplerinin bir listesini ierirler ve
tek ift trnak iaretleri arasnda yazlrlar.

C# Kontrol yaplar ve seme ilemleri


Bu derste C# dilindeki ifadeler,tipler ve deikenler anlatlacaktr. C# dilinde kullanlan
seme veya kontrol ifadelerini reneceksiniz.

Dersimizin hedefleri :

"f" (eer) ifadesinin kullanm "


"switch" (oktan-se) ifadesini kullanm "
"break" ifadesinin "switch" ifadesi ierisinde nasl kullanld
" "goto" ifadesinin yerinde ve etkili kullanlmas

nceki derslerimizde, her program belirli ifadeleri srasyla altrp bitiyordu. Program
iinde inputlara veya program iinde yaplan hesaplara gre deiik ilemler
yaplmyordu. Bu derste rendiklerimiz de programlarmzn belirli artlara gre deiik
ekillerde almasn salayacaktr. lk seme ifademiz "if". "if" kontrol yapsnn 3
temel formu vardr.

Kod 1 : IF yapsnn deiik formlarda kullanm : IfSelection.cs

using System;

class IfSelect

{
public static void Main()
{
string myInput;
int myInt;

Console.Write("Please enter a number: ");


myInput = Console.ReadLine();
myInt = Int32.Parse(myInput);

// Single Decision and Action with brackets


if (myInt > 0)
{
Console.WriteLine("Your number {0} is greater than zero.", myInt);
}

// Single Decision and Action without brackets


if (myInt < 0)
Console.WriteLine("Your number {0} is less than zero.", myInt);

// Either/Or Decision
if (myInt != 0)
{
Console.WriteLine("Your number {0} is not equal to zero.", myInt);
}
else
{
Console.WriteLine("Your number {0} is equal to zero.", myInt);
}

// Multiple Case Decision


if (myInt < 0 || myInt == 0)
{
Console.WriteLine("Your number {0} is less than or equal to zero.",
myInt);
}

else if (myInt > 0 && myInt < = 10)


{
Console.WriteLine("Your number {0} is between 1 and 10.", myInt);
}

else if (myInt > 10 && myInt < = 20)


{
Console.WriteLine("Your number {0} is between 11 and 20.", myInt);
}

else if (myInt > 20 && myInt < = 30)


{
Console.WriteLine("Your number {0} is between 21 and 30.", myInt);
}

else
{
Console.WriteLine("Your number {0} is greater than 30.", myInt);
}

Kod 1'de tm program boyunca tek bir deikeni kullanyoruz, "myInt". Kullancdan
etkileimli olarak veri almak iin nce "Ltfen bir say giriniz :" iletisini konsula
yazdryoruz. "Console.Readline()" ifadesi ile program kullancdan bir deer girmesini
bekler. Bir rakam yazlnca ve enter tuuna baslnca program yazlan deeri nce string
tipinde olan myInput deikenine atanyor. String olarak alnan veriyi program tamsay
tipinde bir deiken olarak kullanmak istedii iin "myInput" tamsay tipine
dntrlmeli. Bu dnm iin "Int32.Parse(myInput)" komutunu kullandk ( tip
dnmleri ve Int32 gibi veri tipleri ileriki derslerde incelenecektir.) Daha sonra,
dnmn sonucu "myInt" isimli deikene aktarlyor.

Artk istediimiz tipte bir veriye sahibiz ve bunu "if" ifadesi iinde ileyebiliriz. "if" ifade
blounun ilk formu u ekildedir : if(mantksal ifade) { "mantksal ifade"nin doru olas
durumunda yaplmas gerekenler }. ncelikle "if" anahtar kelimesi ile balamalyz.
Sonras parantezler arasndaki mantksal ifade. Bu mantksal ifadenin doru veya yanl
olmas bulunur. Biz programmzda kullancdan aldmz saynn sfrdan byk olup
olmadn kontrol ediyoruz">0" ile. Eer say sfrdan bykse, mantksal ifadenin
sonucu dorudur ve { } parantezleri arasndaki kod blou altrlr. Eer mantksal
ifade yanl bir sonu retirse { } arasndaki kon blou altrlmadan bloktan sonraki
ifadelere geer.

kinci "if" ifadesi aslnda birincisi ile ayndr, ikincisi sadece blok iinde deildir. Eer
boolean ifade doru sonu retirse, bu ifadeden hemen sonraki alr. Boolena ifadenin
yanl olmas durumunda ise bu ifadeden hemen sonraki ifade altrlmadan bir
sonraki ifadeye geilir ve o ifade altrlr. Bu ekildeki "if" yapsn, boolean ifadenin
doru olmasnda sadece bir tane ifade altrlacaksa yeterlidir. Buna karn "if"
ifadesinin sonucuna gre birden fazla ifade ileme konulacaksa blok olarak { }
parentezleri arasnda yazlr. Benim kiisel nerim "if" den sonra altrlacak ifade
saysna bakmadan, bu ifade(leri) her durumda blok olarak yazmaktr. leride yeni
programn okunmasnda ve yeni ilevler eklenmesinde size hatalardan kamanza
yardm eder.

Birok zaman size eer/deilse trnde alacak bir "if" yaps gerekebilir. nc tip
"if" ifadesi eer doru deer retirse unlar yap, doru deilse "else" anahtar
szcnden sonraki kodlar altr trnde bir yaps olarak yazlmaldr.

Birden fazla mantksal ifadeyi ilememiz gerektiinde ise, if/else if/else tipinde bir "if"
yapsn kullanmak gerekir. Drdnc rneimizde bu tip bir if yapsn grebilirsiniz. Bu
tip yap yine "if" ve boolean ifadesi ile balar. Boolean ifade doru ise hemen alttaki
bloktaki kodlar altrlr. Bunun yannda, boolean ifadenin deiik durumlarna gre
"else if" i yaps kullanlr. "else if" de ayn if gibi bir boolean ifadeyi alr ve sonucu
doru hemen sonraki bloktaki kodlar altrr.

Boolean ifadenin alabilecei tm ihtimallere gre bu ekilde "else if" ifadeleri


sralanabilir fakat en sonda bir "else" ile yukardaki tm artlarn yanl olmas
durumunda altrlacak kodlar belirleriz. Bu drdnc "if" yapsnda da yine sadece bir
tane if/else blok yaps altrlr.

"switch" yaps da "if/else if/else" yapsna ok benzer.

Kod 2 : Switch ifadeleri : SwitchSelection.cs

using System;

class SwitchSelect
{
public static void Main()
{
tring myInput;
int myInt;

begin:

Console.Write("Please enter a number between 1 and 3: ");


myInput = Console.ReadLine();
myInt = Int32.Parse(myInput);

// switch with integer type


switch (myInt)
{
case 1:
Console.WriteLine("Your number is {0}.", myInt);
break;
case 2:
Console.WriteLine("Your number is {0}.", myInt);
break;
case 3:
Console.WriteLine("Your number is {0}.", myInt);
break;
default:
Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);
break;
}

decide:

Console.Write("Type \"continue\" to go on or \"quit\" to stop: ");


myInput = Console.ReadLine();

// switch with string type


switch (myInput)
{
case "continue":
goto begin;
case "quit": Console.WriteLine("Bye."); break;

default:
Console.WriteLine("Your input {0} is incorrect.", myInput);
goto decide;
}

Kod 2'de birka tane "switch" yaps rneimiz var. "switch" yaps yine "switch" anahtar
kelimesi ile balar ve snanacak deikeni parantez iinde belirtiriz. Switch yapsnn
almas iin u veri tiplerinden bir tanesini kullanmak gerekir : sbyte,short,ushort,int,
long, ulong, char, string, or enum ( enum daha sonraki bir derste ilenecektir.)

Birinci rneimizdeki "switch" yaps int tipinde bir deer almaktadr. Tamsay
deikenimizin alabilecei deerlere gre deiik ilemler yapabiliriz. "myInt"
deikenimizin herbir ihtimalini deerlendirirken "case" anahtar kelimesini, muhtemel
deerini ve iki nokta st ste ":" yapsnda bir snama yapyoruz. rneimizde, "case
1 :", "case 2: ", ve "case 3:" eklinde yazdk. Snama sonularndan uygun olann
hemen altnda kod bloku yer alr. Bu kod blokundan sonra ise "break" veya "goto"
ifadelerini kullanmamz gerekir.

sterseniz "default" seeneini de "switch" ifadesi ile birlikte kullanabilirsiniz. "default"


ifadesinin altndaki kod bloku, "defult"'tan nceki "case"'lerin hibiri snamay
geemedii zaman alr ve tm "case"'lerden sonra gelir.

Her "case" 'den sonra "break" ifadesinin zorunlu olduunu tekrar hatrlatalm. "break"
ifadesi "switch" yapsndan dar kmay ve alttaki kodlara gememizi salar. "default"
anahtar kelimesinin kod blokundan hemen sonra "break" koymak programcnn isteine
kalmtr. Switch ifadesinde iki tane dikkat edilmesi gereken husus vardr.

Birincisi, farkl durumlar (case'leri) ard arda aralarna hi kod yazmadan sralamaktr.
Aslnda burada yaplan i, deikenimizin birden fazla deeri iin tek bir "case" kod
bloku oluturmaktr. Bir case ve hemen arkasna baka bir case yazdmzda program
otomatik olarak bir sonraki "case" 'e geer. Aadaki kodu incelediimizde, "myInt"
deikeni 1,2, veya 3 deerlerinden herhangi birini alrsa kendi deerini ekrana
yazdryoruz. Dier durumda ise deikenimizin deerinin 1 ve 3 arasnda olmadn
ekrana yazdryoruz.

switch (myInt)
{
case 1:
case 2:
case 3:
Console.WriteLine("Your number is {0}.", myInt);
break;
default:
Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);
break;
}

Kod 2'de yer alan ikinci "switch" yaps ise "goto" ifadesinin nasl kullanlacan
gstermek amacyla yazlmtr. "goto" , programn belirli bir ksmnda yer alan, zel
etiket (label) ile belirtilmi ksmna atlamasna ve oradan itibaren almaya devam
etmesine yarar. Programmzda kullanc "continue" yazarsa "begin" olarak belirlenmi
etikete gider ve oradan almaya devam eder. Aslnda bu ekilde "goto" kullanmak
etkili bir dng olur. Eer kullanc "end" yazarsa program "bye" yazar ve dngden
programmz kar.

Aka grlyor ki "goto" kelimesini kullanmak bize programda belirli artlar altnda
g kazandrr. Yine de "goto" ifadesini programda sk bir ekilde kullanmak "sipagetti"
kod olarak adlandrlan programlamaya yol aabilir ki, bu tr kodlama program hem
okurken hem de hatalar ayklarken byk sorunlara sebep olabilir.
C# ile Temel Windows Formlar Oluturma

Bu yazmzda Windows programlamann temel elemanlarndan olan windows formlarnn


nasl oluturulduunu ve nasl kullanldn greceiz, windows formlarn aklarken basit
bir drt ilem yapan hesap makinas oluturacaz.Windows formlar derken neyi
kastediyoruz? Textbox, label, button gibi nemli elemanlarn hepsi birer windows
formudur. Bu windows formlarna ulamak iin System.Windows.Forms isimalann
kullanyoruz. Ve tabi ki programmzn aktif bir windows uygulamas olarak almas iin
de aadaki isimalanlarn projemize ekliyoruz.

using System.Drawing;
using System.Collections;
using System.ComponentModel;

Programmz yazmaya balamadan nce programmzn kodlarn ierecek bir isim alan
oluturalm. Ben buna CsHesapMakinasi adi verdim.(Makaleyi okurken kaynak kodu
incelemenizi tavsiye ederim) Siz istediiniz baka bir isim kullanabilirsiniz.

Daha nceki makalelerimizde belirttiimiz gibi programmzn almas iin derleyiciye


programn balang noktasn bildirmemiz gerekirdi.Bu balang noktas da genelde
main() fonksiyonu oluyordu. Kodumuzu yle ayarlayacaz ki main() fonksiyonu icra
edildiinde altrmak istediimiz windows formu ekranda grnsn. Bunun iin main
iine aadaki kodu yazyoruz.

Application.Run(new Form1()); // Yeni bir Form1 nesnesi oluturularak uygulama olarak


balatlyor.

u an iin Form1 hakknda en ufak bir bilgiye sahip deiliz.Peki bu Form1 nasl
oluturulacak. Yukarda da bahsettiimiz gibi Form1 snfndan bir nesne oluturmak iin
System.Windows.Forms isimalann kullanmalyz. Bu yzden bu isim alannn altnda
bulunan Form snfndan yeni bir Form1 snf tretmemiz gerekecek, bu tretme ilemi
aadaki gibidir. Form1 snfn trettikten sonra Form1' iinde bulunacak elemanlar
tanmlyoruz.4 ilemi yapmak iin 4 buton, ileme giren deerler iin 2 textbox ve 2 tane
de label formu tanmlyoruz.Tanmlama ilemi aadaki gibidir.
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox deger1;
private System.Windows.Forms.TextBox deger2;
private System.Windows.Forms.TextBox sonuc;
private System.Windows.Forms.Label isaret;
}

imdi bu windows formunun ekrana nasl basldn inceleyelim.Main() ilevi iinde yeni
bir Form1 nesnesi yaratldnda Form1 nesnesine ait kurucu ilev olan Form1() ilevi
arlr.(Kaynak kodu inceleyin). Form1() kurucu ilevinde ise InitializeComponent(); adl
bir fonksiyon arlarak Form1 nesnesine ait olan ye elemanlarla (button,label,textbox
vs) ilgili ilk ilemler yaplr.From1 ald zaman Form1 iinde bulunan elemanlarla iligili
yapmak istediimiz ilk zellikleri InitializeComponent() fonksiyonu iinde yapyoruz.

private void InitializeComponent()


{
// form1 iinde yer alacak elemanlar yaratlyor(kaynak kodu inceleyin)

this.deger2 = new System.Windows.Forms.TextBox();


this.sonuc = new System.Windows.Forms.TextBox();
this.button2 = new System.Windows.Forms.Button();
this.isaret = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// elemanlarla ilgili balang zellikleri veriliyor.
//
this.deger1.Location = new System.Drawing.Point(16, 8); //deger1 adl textbox
iin yer bildirimi
this.deger1.Name = "deger1";
this.deger1.TabIndex = 0;
this.deger1.Text = "0";

this.name="Form1"; //Form1 nesnesinin kendisi iin this anahtar szcn


kullanyoruz
this.text = "Hesap Makinas ";
this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)),
((System.Byte)(128)), ((System.Byte)(0)));
this.ClientSize = new System.Drawing.Size(400, 149);

}
imdi sra elemanlarla ilgili olaylarn birbirleri ile ilikisine.Mesela bir buton formunun click
olaynn form tarafndan yakalanabilmesi iin aadaki satrlar yazmalyz.

this.button4.Click += new System.EventHandler(this.button4_Click);


private void button4_Click(object sender, System.EventArgs e)
{
isaret.Text="/";
sonuc.Text=System.Convert.ToString(System.Convert.ToInt32(deger1.Text)/
System.Convert.ToInt32(deger2.Text));
}
buton4_Click() ilevinde, alma zamannda bir nesnenin zelliklerinin nasl
deitirildiini gryoruz.button4 blme ilemi yaptndan isaret.Text="/"; yazdk. sonuc
adl textbox formunun Text zellii bir string ifadesi olduu iin ilemlerimizi yaptktan
sonra sonuc.text ifadesine atama yapabilmek iin System.Convert isimalannda bulunan
ToString ilevini kullanarak ifadeyi String trne dntryoruz. Ayn ekilde String
olarak aldmz trler iin aritmetik ilem yapabilmek iin yine ayn isimalannda bulunan
ToInt32 ilevi ile String trn int32 formatna dntryoruz. Btn bu ilemleri 4
butonumuz iin yaptmzda drt ilem yapabilen basit ve bol bol bug ieren (unutmayn
amacmz sadece formlarn kullanmn renmek) bir hesap makinamz olacak.

.NET Teknolojilerine Giri

Gnmzde bilgisayar dnyasnda internet olmazsa olmaz derecede nemli bir yer
edinmeye balad. Artk insanlar ev ve iyerlerinde kullandklar uygulamalarna da
internet zerinden eriip kullanmak istiyorlar. Bu internetin getirdii zgrln
kanlmaz bir sonucudur.Peki yazlm dnyas buna hazrmyd? Gelitirilen her program
kolayca internet ormannda da altrabilirmiydik? Bu sorularn cevaplar bir sene
ncesine kadar hayr, olamaz veya u andaki sistemler bu denli zgrl bize
salamyor trndendi.

Microsoft'un ASP'si ile veya PHP ile yaplan uygulamalar tam olarak insanlarn isteklerine
cevap veremiyordu. Her ne kadar iyi ve gelimi web uygulamalarn bir yere kadar
yapabiliyorduksa da belirli bir noktadan sonra C++,Delphi veya VB ile gelitirdiimiz
modlleri web uygulamamza ekleyerek sorunlarmz halletmeye alyorduk. Tabi bu tr
yntemler programn gelime sresini uzatyordu. Zamann giderek nem kazand bir
devirde haliyle programlarmz da hzl bir ekilde gelitirmemiz gerekiyor(du). Hzl
uygulama gelitirme(Rapid Application Development- RAD) geleneksel programlama
aralaryla ve prgramcnn yetenekleriyle zm bulunacak bir mesele deil. Artk
programlama dilleri, dille birlikte gelen ktphaneler ve bunlar hakkndaki
dokmantasyonlar ile birlikte deerlendiriliyor.

.NET ile birlikte programcnn hizmetine sunulan 3400'den fazla snf, modern anlamda
ok gzel bir gelitirme ortam sunuyor. Bu sayede programlamlar daha hzl bir ekilde
gelitirme imkanna sahip bulunuyoruz. .NET kullanarak yazdmz ASP.NET, Windows
Forms veya mobil cihazlar iin gelitirdiimiz bir uygulamay birinden dierine
dntrmek ii ok kolay bir ekilde yaplabiliniyor. Bu sayede ayn anda hem windows
hem de web uygulamalar gelitirmek ok hounuza gidecektir :-).

.NET framework'unun bize sunduu dier gzel bir zellik ise platform bamszldr.
Artk yazdnz Windows uygulamalar sadece Windows ykl sistemlerde deil, .NET
framework'unun kurulu olduu tm platformlarda alabilecektir. Her ne kadar imdilik
bu alt yapnn sadece Windows versiyonuna sahip olsak da Linux gruplar tarafndan bu
alt yapnn Linux versiyonunu kartma ynndeki abalar uzun bir sredir devam
etmektedir.
Peki bunca ho zellikleri bize salayan .NET alt yapsnda program yazarken hangi dili
veya dilleri kullanmak zorundayz? Bu konuda Microsoft ok radikal bir karar alarak
gelecek iin hazrlanm yeni alt yapda Common Language Runtime (CLR) ile uyumlu her
.NET dilini kullanmamza olanak salyor. .NET ile gelen SDK'da C#,VB.NET ve Js.NET
kullanarak program yazabiliyoruz. Dier taraftan 30'un zerinde programlama diliyle .NET
uygulamas gelitirebilirsiniz.

CLR denen ey tam olarak nedir? .NET altyapsnda programlarn almasn kontrol eden
ve iletim sistemi ile programmz arasnda yer alan arabirimdir. Normalde yazdmz
programlar derlenirken makine diline evrilirdi ve program bu ekilde iletim sistemi ile
direkt balant kurarak alrd. Fakat platform bamsz bir gelitirme ve yrtme ortam
istiyorsanz ne olacak? te tam bu anda CLR devreye girer ve .NET programlarn farkl
platformlarda makineye ve iletim sistemine gre programmz altrr. Normalde bir
Windows, Linux veya MACOS kurulu sistemler ayn programn kodunu altramazlar. Bu
platformlar iin programn ayr ayr yazlp, onlara gre hazrlanm derleyicilerde
derlenmesi gerekir. Dnyada ok sayda yaygn platform olduunu dnrsek, bunlarn
herbiri iin ayr ayr derleme ilemini tek bir iletim sisteminde yapmamz imkansz
gibidir. Bu durumda zm , ortak bir aradil kullanmak ve herbir platform iin bu aradile
evrilmi programn kodunu altracak altyaplar hazrlamaktr.

imdi u soruya sra geldi: "yi de .NET hangi aradili kullanyor?" Sorumuzun cevab
MSIL(Microsoft intermediate Language) .NET platfomunda hangi dili kullanrsak
kullanalm yazdmz programn kodu direkt olarak makine diline deil de MSIL'e evrilir.
Bu sadece program altrdmz sistemde kurulu olan CLR alma annda MSIL
kodlarn evirerek programmz altrr, alma annda derleme ilemini ise JIT
derleyicileri (Just in Time compilers) stlenir.

Gelecek makalemizde JIT'ler, MSIL language, CTS (Common Type System) gibi daha
teknik konular detayl olarak ele almay dnyorum. Sizlere kolaylklar dilerim.
.NET'in CLR, CTS ve JIT derleyicileri

nceki yazmzda "dot NET" platformu konusuna giri yapmtk.(Yazy okumak iin
tklayn) Burada ise daha detayl olarak .NET kavramlarn inceleyeceiz ve .NET'le
Java'nn karlatrld bir testin sonularna yer vereceiz.

.NET platformunda istediimiz programlama dili ile program yazabileceimizi nceki


yazmzda sylemitik. Bunun iin tek art, kullandmz dilin .NET iin yazlm olan bir
derleyicisine ihtiyacmz olduudur. .NET uyumlu programlama dili olutururken belirli
standartlara uyulmas gerekir. Bu standartlar CLS (Common Language Specifications -
Dillerin ortak zellikleri) ile belirlenmitir. CTS(Common Type System) ise veri tipleri,
nesneler, arayzler ve programlama dillerine ait zellikleri tanmlar ve CLS'in bir paras
olarak karmza kar. CLS'de tanmlanm kurallara uymak art ile istersek kendi
programlama dilimizi dahi gelitirebiliriz veya herhangi bir dili .NET platformunda
uygulama gelitirmek zere deitirebiliriz.

CLR ,programlarmz deiik ekilde derleyebilir. Varsaylan derleme tr JIT(Just IN


TIME- alam annda derleme) 'dr. Program alrken daha nce derlenmemi bir
parasna gelince hemen o ksm da derler ve bunu hafzda chach'e koyar. Tekrar ayn
program parasn altrmak gerekirse buray hafzadan altrr. Eer RAM 'imizi yeteri
kadar bykse, programn tamam derlenmi ve hafzada depolanm durumda olabilir.
Bu durumda programmz ok hzl alr.

Hafzamzn yeteri kadar byk olmad durumlarda EconoJIT (Ekonomik JIT)


derleyicisini kullanabiliriz. Bu derleyici ile programn derlenmi ksmlar hafzada
depolanmaz ve her seferinde ayn program paras derlenir. Tabi ki bu derleyici normal
JIT'e gre programlarmz daha yava altrr. Ama RAM 'imizi ok daha az kullanr.

CLR ile gelen nc derleyicimiz PreJIT(n JIT derleyicisi) ise derleme iini program
almadan nce yapar ve tm makine kodlarn bir yerde saklar. alma annda ok hzl
olan programmz dier JIT derleyicileriyle derlenmi olanlara nazaran ok hzl alr.

Kolayca grebileceimiz birka noktaya da parmak basmak istiyorum. .NET ile yazdnz
programlar dierlerine gre yava alr. nk iki defa derleme aamasndan geerler,
program kodu MSIL'ye, MSIL ise makine koduna evrilir. Dier taraftan .NET ile
programlarmz platform bamsz olacak, .NET uyumlu herhangi bir dil ile program
gelitirebileceiz ve programmz CLR altnda daha gvenli bir ekilde alacaktr.

.NET perfromans testi linkindeki sonulara gre : Genelde C# Java'dan 3.30 kat daha
hzl. C# Visual C++ 6.0'dan ise 3.11 kat daha hzl alyor. Hatta VB.NET kodu VB 6.0'a
nazaran 46.45 kat daha hzl alyor. :-)

Visual C# ile Programlamaya Giri

Visual C#, Visual Studio ailesinin yeni yesidir, bu yeni dil c ve c++ temelleri zerine
kurulmasna ramen komponent temelli programlama tekniini gelitirmek iin birtakm
yeni zellikler eklenmitir. C# dilinin sentaks C ve C++ programclarna ok tandk
gelecektir. Bundan pheniz olmasn.

Genel Aklamalar

Bu yazda greceimiz basit uygulamada QuickSort algoritmasn kullanarak nasl basit bir
C# projesinin oluturulduunu greceiz. Bu uygulamada bir c# programnda en sk
kullanlan yaplardan olan dosyaya ve console ekranna okuma/yazma, fonksiyon
oluturma ve basit dizilerin kullanm aklanacaktr.

Bu yaz kesinlikle C# dilinin tm zelliklerinin anlatld yaz deildir. Bu yaz C# dilini


renmek iin sizlere bir balang noktas sunar.

nerilen Kaynaklar

Visual Studio.NET (Beta 2 veya sonras) rnek kaynak kodu derlemeniz iin gereklidir.
C/C++ bilgisi size bu yazy anlamanzda yardmc olabilir ama gerekli deildir.

Adm 1. Projeye Balama

Visual Studio ile program gelitirme organizasyonu solution(zm) alma alanlar


zerindendir. Solution dediimiz ortam bir veya daha fazla projeyi ierebilir. Bu makale
iin tek bir C# projesi ieren bir solution oluturacaz.

Yeni bir proje oluturmak

1. Visual Studio.NET ortamndan, File | New | Project menlerini sein.


2. Soldan(Project Types) Visual C#, sadan(Templates) ise Console Application
butonlarn sein.

3. Projenizin adn belirleyin ve projenizin hangi klasrde saklanacan belirleyin.Bu


klasr Visual Studio tarafndan otomatik oluturulur.Proje ad olarak ben quicksort
yazyorum.Siz istediiniz ad verebilirsiniz.

4. OK tuuna basalm ve yola koyulalm.

"Visual C# Solution" ortammz

Visual Studio.NET iinde bir Visual C# projesi bulunan bir solution oluturdu. Proje
assemblyinfo.cs ve class1.cs adl iki tane dosya iermektedir.

Bundan sonraki admlarda projemizi nasl derleyeceimizi ve bu iki dosya hakknda


detayl bilgiyi reneceiz.

Adm 2. Hello, World!

Kusura bakmayn ama gelenei bozmadan ilk defa C programlama dili ile yazlm olan
"Hello, World!" programn c# ile yazacaz. Bu bir gelenektir ve her yeni bir dili
renmeye baladnzda bunu siz de greceksiniz.

Kaynak Kodu Deitirme

1. Solution Explorer 'da bulunan 'class1.cs'dosyasna ift tklayn. Solution Explorer '
gremiyorsanz, view mensn kullanarak grnr hale getirebilirsiniz.
2. ablonla oluturulmu koda aada krmz ile yazlm ksm ekleyin (class1.cs).

using System;

namespace quicksort
{
///
/// Summary description for Class1.
///
class Class1
{
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Console.WriteLine ("Hello, C#.NET World!");
}
}
}

3. Dikkat edin siz kodunuzu yazdka Visual Studio size snflar ve fonksiyon adlar
hakknda bilgi verir, nk .NET Framework tip bilgisini yaynlamaktadr.

Uygulamamz Derleyelim

1. Programmzda deiiklik yaptmza gre artk Build mensnden Build ' seerek
programmz derleyebiliriz.

2. Hata ve mesajlar en altta bulunan "Output Window" denilen pencerede grnr.


Eer herhangi bir hata yoksa uygulamamz Debug mens altnda bulunan 'Start
without Debugging' mensne tklayarak altrabiliriz.

Programmzn kts

Aada programmzn Visual C# iinden altrlarak oluturulmu ktsnn ekran


grnts mevcuttur.
Deiiklikleri Anlamak

System.Console snfna ait WriteLine() fonksiyonu kendisine argman olarak gnderilen


dizgeyi sonuna satr sonu karakteri de ekleyerek ekrana yazar.
Bu fonksiyon integer ve floating-point gibi dier veri tiplerini de argman olarak alabilir.

Program bellee yklendiinde programn kontrolu Main() fonksiyonuna gelir.WriteLine()


fonksiyonunu oraya yazmamzn sebebi budur.

Adm 3. Programn Yaps

imdi basit bir Hello World uygulamas gelitirmi olduk, imdi de bir Visual C#
uygulamasnn basit componentlerini inceleyelim.

Kaynak Kod Yorumlar

// karakterlerinden sonra gelen ve satrn sonuna kadar olan szckler yorum satrlardr
ve C# derleyicisi tarafndan grnmezler. Ayn zamanda birden fazla satra yorum
eklemek istiyorsak /* */ karakterleri arasna yorum yazarz.

// Bu satr derleyici tarafndan grlmez


/* Ayn zamanda bu blok da
derleyici tarafndan grnmez*/

Using Komutu

.NET Framework gelitiricilere yzlerce yararl snflar sunar. Mesela, Console snf,
console ekranna ait girdi ve ktlar iler. Bu snflar hiyerarik bir aa iinde organize
edilmitir. Aslnda Console snfnn tam ismi System.Console ' dur. Dier snflar ise
System.IO.FileStream ve System.Collections.Queue. iindedirler.

using komutu bize snfn ismini namespace(isim alan) kullanmadan kullanabilmemizi


salar.
Aada krmz ile yazlan yazlar using komutunun uygulamasnn sonucudur.

using System;
class Class1
{
static void Main(string[] args)
{
System.Console.WriteLine ("Hello, C#.NET World!");
Console.WriteLine ("Hello, C#.NET World!");
}
}

Snf Bildirimi
C++ ve Visual Basic 'den farkl olarak C# 'da btn fonksiyonlar bir snf ierisinde
olmaldr. C# 'da bir snf tanmlamak iin class anahtar szc kullanlr.Bu durumda
bizim uygulamamzda, Class1 snf Main() adnda bir fonksiyon ierir. Eer snf bildirimini
bir isim alan bloklar iine alrsak snflarmz CSharp.QuickSortApp eklinde bir hiyerari
iine alabiliriz.

Snflar hakknda ok derin bir bilgi vermeyi dnmyorum.Fakat bizim rneimizin


neden bir paras olduunu aklamakta fayda grdm.

Main() Fonksiyonu

Program bellee yklendiinde Main() fonksiyonu programn kontroln eline alr, bu


yzden balang kodlarmz daima Main() fonksiyonu iinde yazmalyz. Komut satr
argmanlar ise bir string dizisi olan args dizisine aktarlr.(mesela: delete x ) Burada
programmzn ad delete ise x bir komut satr argmandr.

Adm 4. Console Girii

imdi ilemlerimize bir QuickSrot uygulamas gelitirerek devam edelim. lk yapmamz


gereken kullancya hedef ve kaynak dosyasnn isimlerini sormak olacaktr.

Source Code Modifications

1. class1.cs dosyasna aada krmz ile yazlanlar yazn. Burada snf ismi ve
isimalan ismi bizim iin ok nemli deildir.

// namespaces ekleme
using System;

// namespace tanmlama
namespace MsdnAA
{
// uygulama snf tanmlama
class QuickSortApp
{
// uygulama oluturma
static void Main (string[] szArgs)
{
// Programn hakknda
Console.WriteLine ("QuickSort C#.NET Sample Application\n");

// kullancdan bilgi alma


Console.Write ("Source: ");
string szSrcFile = Console.ReadLine ();
Console.Write ("Output: ");
string szDestFile = Console.ReadLine ();
}
}
}

Console'dan Okuma

Console snfnn ReadLine() metodu kullancya bir giri ekran sunar ve geriye
kullancnn girdii dizgeyi(string) geri dndrr.Bu metod bellek tahsisatn otomatik
olarak kendi iinde yapmaktadr ve .NET garbage collector mekanizmas sayesinde iade
etmeniz gereken herhangi bir alan yoktur.
Program kts

Program Debug | Start Without Debugging menlerini kullanarak altrn.


Aada programmzn son halinin ktsn gryorsunuz.

Adm 5. Dizilerin Kullanm

Programmz sralama yapmadan nce giriten satrlar alarak bir dizi iinde saklamas
gerekir. imdi .NET temel snflarndan olan ArrayList snfn inceleyeceiz.

Kaynak Kod Deiiklii

1. class1.cs dosyas iinde aada krmz ile gsterilen yerleri ekleyin.

// isim alan ekleme


using System;
using System.Collections;

// isimalan tanmlama
namespace c#nedircom
{
// uygulama snf tanmlama
class QuickSortApp
{
// uygulama balangc
static void Main (string[] szArgs)
{

Console.WriteLine ("QuickSort C#.NET Sample Application\n");

// Dosya isimlerini almak iin komut yaz


Console.Write ("Source: ");
string szSrcFile = Console.ReadLine ();
Console.Write ("Output: ");
string szDestFile = Console.ReadLine ();

// TODO: Read contents of source file


ArrayList szContents = new ArrayList ();
}
}
}

ArrayList snfnn kullanm

ArrayList snfna direkt ulaabilmek iin System.Collections isimalann projemize using


komutuyla ekliyoruz. Bu snf dinamik olarak byyp klebilen nesne dizileri iin
kullanlr. Yeni bir eleman eklemek iin basit bir ekilde Add() metodunu kullanabilirsiniz.
Bu diziye eklenen yeni eleman orijinal nesne iin referans olarak kullanlr, ve garbage
collector alan iadesi iin hazr olacaktr.

string szElement = "insert-me";


ArrayList szArray = new ArrayList ();
szArray.Add (szElement);

Dizinin var olan bir elemanna ulaabilmek iin, diziye ait Item() metoduna ulamak
istediimiz elemann sra(index) numarasn geebiliriz.Ksaca [] operatrlerini kullanarak
da istediimiz elemana Item() metodunu kullanmadan da ulaabiliriz.

Console.WriteLine (szArray[2]);
Console.WriteLine (szArray.Item (2));

ArrayList snfnn daha birok metodu vardr, ancak biz bu uygulamada sadece ekleme ve
okuma yapacaz. ArrayList snfna ait tm metod ve zellikleri renmek iin MSDN
kitaplna bavurabilirsiniz.

Adm 6. File Girdi/kt(Input/Output)

imdi isterseniz dosyadan okuma ve dosyaya yazma ilemlerini gerekletirelim.


Dosyadaki her satr okuyup, bir string dizisinin her elemann bir satr gelecek ekilde
ekleyeceiz.Sonraki aamada ise QuickSort algoritmasn kullanarak diziyi sral bir ekilde
yazacaz.

Kaynak Kod Deiiklii

1. class1.cs dosyasna aada krmz ile yazlanlar yazn. Burada snf ismi ve
isimalan ismi bizim iin ok nemli deildir.

// isimalan ekleme
using System;
using System.Collections;
using System.IO;

namespace MsdnAA
{

class QuickSortApp
{

static void Main (string[] szArgs)


{
string szSrcLine;
ArrayList szContents = new ArrayList ();
FileStream fsInput = new FileStream (szSrcFile,
FileMode.Open,FileAccess.Read);
StreamReader srInput = new StreamReader (fsInput);
while ((szSrcLine = srInput.ReadLine ()) != null)
{
// dizinin sonuna ekleme
szContents.Add (szSrcLine);
}
srInput.Close ();
fsInput.Close ();
// TODO: Buraya QuickSort fonksiyonu gelecek

// sralar satrlar yazma


FileStream fsOutput = new FileStream (szDestFile,FileMode.Create,
FileAccess.Write);
StreamWriter srOutput = new StreamWriter (fsOutput);
for (int nIndex = 0; nIndex < szContents.Count; nIndex++)
{
// hedef dosyaya satr yazma
srOutput.WriteLine (szContents[nIndex]);
}
srOutput.Close ();
fsOutput.Close ();

// baary kullancya bildirme


Console.WriteLine ("\nThe sorted lines have been written.\n\n");
}
}
}

Kaynak Dosyadan Okuma

Kaynak dosyay amak iin FileStream snfn ve StreamReader snfn kullanarak


ReadLine() metodu ile dosyay okuyoruz. ReadLine() metodunu dosyann sonunu ifade
eden NULL deerine geri dnene kadar aryoruz.Dng iinde okunan satrlar dizinin
iine ekliyoruz ve sonrada tm nesneleri kapatyoruz.

Hedef Dosyaya Yazma

Dosyaya yazarken dizinin sralanm olduunu varsaydk ve yle devam ettik. Ayn
eklide FileStream nesnesini ve StreamWriter snfn kullanarak hedef dosyaya yazma
ilemini yaptk.
Adm 7. Fonksiyon Yaratma

Son aamada diziyi QuickSort algoritmas ile sralayan fonksiyonu yazmaya geldi. Bu
fonksiyonu uygulamamzn ana snfnn iine koyacaz.

Kaynak Kod Deiiklii

1. class1.cs dosyasna aada krmz ile yazlanlar yazn. Burada snf ismi ve
isimalan ismi bizim iin ok nemli deildir.

// isim alan ekleme


using System;
using System.Collections;
using System.IO;

namespace c#nedircom
{

class QuickSortApp
{

static void Main (string[] szArgs)


{
... ... ...

// QuickSort fonksiyonuna parametrelerin geii


QuickSort (szContents, 0, szContents.Count - 1);

... ... ...


}

// QuickSort fonksiyonu
static void QuickSort (ArrayList szArray, int nLower, int nUpper)
{

if (nLower < nUpper)


{
// Ayrma ve sralama ilemi
int nSplit = Partition (szArray, nLower, nUpper);
QuickSort (szArray, nLower, nSplit - 1);
QuickSort (szArray, nSplit + 1, nUpper);
}
}

// QuickSort blmelere ayrma


static int Partition (ArrayList szArray, int nLower, int nUpper)
{
// lk eleman bulma
int nLeft = nLower + 1;
string szPivot = (string) szArray[nLower];
int nRight = nUpper;

// Dizi elemanlarn blme


string szSwap;
while (nLeft <= nRight)
{
while (nLeft <= nRight)
{
if (((string) szArray[nLeft]).CompareTo (szPivot) > 0)
break;
nLeft = nLeft + 1;
}
while (nLeft <= nRight)
{
if (((string) szArray[nRight]).CompareTo (szPivot) <= 0)
break;
nRight = nRight - 1;
}

// Eer uygunsa yer deitirme ilemi yap


if (nLeft < nRight)
{
szSwap = (string) szArray[nLeft];
szArray[nLeft] = szArray[nRight];
szArray[nRight] = szSwap;
nLeft = nLeft + 1;
nRight = nRight - 1;
}
}

szSwap = (string) szArray[nLower];


szArray[nLower] = szArray[nRight];
szArray[nRight] = szSwap;
return nRight;
}
}
}

QuickSort() Fonksiyonu

Bu fonksiyon alt snr, st snr ve bir dizi olmak zere 3 tane parametre almaktadr.
QuickSort fonksiyonu Partition() fonksiyonunu ararak diziyi iki paraya ayrr. Bu
paralarn birinde belirlenen bir diziden nceki ,dier parasnda ise sonraki elemanlar
bulunur. Sonra fonksiyon tekrar kendini ararak bu iki parann sralanmasn salar.

Yukardaki kodlarda yeni grdmz metod CompareTo() metodudur. Bu metod iki


string ifadesini karlatrr.

QuickSort Uygulamasn altrma

Bu adm uygulamamzn son adm olacaktr.imdi programmz derleyip altrabiliriz.


Programmzn almas iin bir text dosyas oluturmamz sralama yapabilmek iin
gerekecek. Exe dosyasnn bulunduu dizini text dosyasn oluturup program altralm.
Programn kts

Aada programmz altrdktan sonraki ekran kts mevcuttur. Yukardaki ekranda


ise output.txt dosyasnda meydana gelen deiiklikleri grebilirsiniz.

Adm 8. Debugger Kullanmak

Debugger arac programmzn problemlerini zmek iin nemli ve gerekli bir aratr. yi
bir balang yaptmza gre son aamada programmz iinde nasl dolaacamza ve
QuickWatch' nasl kullanacamza bakalm.

Breakpoint' leri Ayarlama

Program Debugger iinde alrken eer breakpoint olan bir noktaya gelinirse program
sonlandrlr ve debugger control ' bizim elimize geer. Herhangi bir satra breakpoint
koymak iin ilgili satra sa tklayp aadaki gibi Insert BreakPoint mensne tklayn.

BreakPoint bulunan satrlar krmz ile gsterilir. BreakPoint ' i kaldrmak iin ilgili satra
sa tklayp Remove BreakPoint mensn sein.

Program iinde Adm Adm ilerlemek


Aadaki ekilde grld gibi bir breakpoint oluturduktan sonra debugger ile
programmz altralm. Debug mensnden daha nceden de yaptmz gibi Start
Without Debugging yerine Start mensne tklayn. Bu ekilde program altrdmzda
program debugger ile almaya balayacaktr, ve breakpoint 'ler aktif olmaya
balayacaktr.

Program breakpoint 'in olduu noktaya geldiinde, debugger programn kontroln alr.
Aadaki ekilde grld gibi sar okla programn geldii nokta gsterilir.

Kod iinde adm adm ilerlemek iin men ubuundan Debug | Step Over ' seerek sar
okun hareketini izleyin. Debug | Step Into komutu gitmek istediimiz fonksiyona
gitmemizi salar. Aada iki defa Step Over mensn setikten sonra kaynak
kodumuzun grnts mevcuttur.

Eer programmzn dier bir sonlandrc nedene (yeni bir breakpoint, exception , exit,
debug) gelene kadar devam etmesini istiyorsanz Debug | Continue menlerini sein.

Deiken Deerlerini Takip Etme

Debugger 'n kontrol bizde iken farenin imlecini kaynak kodda istediimiz deiken
zerine gtrerek deikenin o anki deerini renebiliriz.

Ayn zamanda bir deikene sa tklayarak QuickWatch mensn aabilirsiniz.


QuickWatch ile deiken hakknda daha detayl bilgiler elde edebilirsiniz. Mesela diziler
hakknda aadaki ekilde grld gibi bilgiler elde edilebilir.
Dier Debugger Aralar

Visual Studio yukarda bahsettiimiz aralar dnda farkl aralarda barndrr. Mesela
Call Stack Wiever arac ile o an hangi fonksiyonun
arld ile ilgili bilgiyi elde edebilirsiniz. Bellekteki
deerleri ve bir prosesteki thread 'leri de ayn anda
grebileceimiz aralar mevcuttur.

Son Sz & Sonu

Bu yaznn amac sizlere Visual Studio ile nasl basit bir uygulamann yaplacan adm
adm gstermekti. Dier .NET ve C# kaynaklarn aratrmak iin sizi
cesaretlendirebildiysek ne mutlu bize. Bu yazy buraya kadar okuduunuza gre en
azndan u aamada alan bir projeniz var, istediiniz gibi zerinde deiiklikler yapp
sonucu grebilirsiniz.
C# ile Client/Server ve Socket programlamaya giri

Bu makalemizde TCP protokolyle basit bir Client/Server program yapacaz, C# ile


socket programlama yapabilmek iin System.Net.Sockets isimalan altnda bulunan
snflar kullanacaz. Yapacamz programda server bir console uygulamas, client ise
windows formlarn kullanarak yapacamz windows uygulamas olacak.Amacmz basit
bir Client/Server atisi kurmak olduu iin uygulamamz ok basit olacaktr. Siz yaznn
tamamn dikkatlice incelediinizde ve yaratclnz kullandnzda ok daha gelimi
uygulamalar yapabilirsiniz. Belki bir sunucu tabanl script dili bile gelitirebilirsiniz :).

imdi yazacamz programda kullanc Windows uygulamas vastas ile server olan
programmza balanacak. Form zerinde bulunan butona tkladmzda yine form
zerinde bulunan textbox giriindeki yazy server programmz alacak ve yazda ka
karakter olduunu client programna gnderecek.Client program ise bir mesaj kutusu ile
kullancya bildirecek.ncelikle client olan kullancdan mesajn geldiini dnrek Server
programmz yazalm. Server programmz yazmaya balamadan nce programda Soket
programlama iin kullandmz snflara ve onlarn ye fonksiyonlarna kullandmz
kadaryla bir gz atalm.

:::: TcpListener Snf(System.Net.Sockets) ::::

TcpListener snf TCP protokol ile alan servislere balanmamz salar. Mesela HTTP
ve FTP protokolleri TCP servislerini kullanrlar. TcpListener snfnn kurucu fonksiyonunu 3
deiik ekilde arabiliriz.

1- )IPEndPoint snfn kullanarak IP numaras ve port numaras ieren bir bilgiyi kullanma
yolu ile
2- )IP adresi ve port numarasn geerek arma
3- )Sadece Port numaras ile arma.Bu durumda varsaylan a arayznz TCP
servislerini salayacaktr.

Biz bu programda 3. ktaki gibi bir kullanm tercih ettik.

public void Start();

TcpListener snfna ait bu metod network servislerinden ilgili port'u dinleyerek verileri
almaya balamamz salar.
public Socket AcceptSocket();

TcpListener snfna ait bu metod veri transferi iin geri dn deeri olarak bir Socket
nesnesi dndrr.Bu geri dnen socket ilgili makinann IP adresi ve port numaras ile
kurulur.(kurucu ilev ile)

:::: Socket Snf(System.Net.Sockets) ::::

Socket Snf ile ilgili aadaki rnei inceleyelim

Socket s = new Socket(AddressFamily.InterNetwork,


SocketType.Stream,ProtocolType.Tcp );

Socket snfnn bu kurucu ilevi parametre olarak AdressFamily dedigimiz adresleme


semasi Soket tipi ve kullanacagimiz protokol tipini alir. Bu 3 paremtere de .NET
Framework class ktphanesinde Enum sabitleri olarak tanimlanmistir.

Programimizda yazdigimiz "Socket IstemciSoketi = TcpDinleyicisi.AcceptSocket();" satiri


ile geri dnen soket nesnesinde bu 3 parametrede tanimlanmistir.

public bool Connected();

Bu metod ile Soketin baglanip baglanmadigini geri dnen bool degeri ile anliyoruz.Eger
soket hedef kaynaga bagliysa true degilse false degerine geri dner.

:::: NetworkStream Sinifi(System.Net.Sockets) ::::

NetworkStream sinifi kurucularindan olan "void NetworkStream(Socket x);" fonksiyonu


ilgili kendisine gnderilen soket nesnesine ait datalari NetworkStream trnden nesnede
tutar.bu programda kullandigimiz soket tipi stream oldugu iin bu sinifi kullaniyoruz.
NetworkStream sinifi iinde islem yapabilmemeiz iin ise System.IO isiamalaninda
bulunan StreamReader ve StreamWriter siniflarini kullanacagiz.

n bilgileri aldmza gre server programmz yazalm. Aadaki ilk kaynak kod
server.cs dir. Satr aralarna size yardmc olabilecek yorumlar ekledim.Kaynak dosyay
zellikle makaleme dosya olarak eklemiyorumki siz aadaki kodlar tek tek yazp daha
iyi renin.

:::: TcpClient Sinifi(System.Net.Sockets) ::::

Tcp servislerine balant salamak iin TcPClient snf kullanlr. Istemci programmzda
TcpClient snfnn <public TcpClient(string, int);> kurucu ilevini kullanyoruz. lk
parametre bilgisayar ad ikincisi ise port numarasdr.

public NetworkStream GetStream();

Bu metod ile belirtilen port tan gelen veriler bir NetworkStream nesnesine aktarlr.
GetStream metodunun geri dn deeri NetworkStream olduu iin atama ilemini
NetworkStream trnden bir nesneye yapmamz gerekir.

Not: Yeil ile yazlan satrlar yorum satrlardr.Html formatnda bir alt satra inmi olan
yorum satrlarn copy&paste ile programnza aktarrken o satrlar tekrar tek satr haline
getirmeyi unutmayn, aksi halde programnz derlenemez.
//Server.cs

using System; // bunu her zaman eklememiz lazim


using System.IO ; //StreamReader ve StreamWriter siniflari iin
using System.Net.Sockets; // Socket, TcpListener ve NetworkStrem siniflari iin

public class Server


{

public static void Main()


{

//Bilgi alisverisi iin bilgi almak istedigimiz port numarasini TcpListener sinifi ile
gereklestiriyoruz

TcpListener TcpDinleyicisi = new TcpListener(1234);


TcpDinleyicisi.Start();

Console.WriteLine("Sunucu baslatildi...") ;

//Soket baglantimizi yapiyoruz.Bunu TcpListener sinifinin AcceptSocket metodu ile


yaptigimiza dikkat edin
Socket IstemciSoketi = TcpDinleyicisi.AcceptSocket();

// Baglantnn olup olmadn kontrol ediyoruz


if (!IstemciSoketi.Connected)
{
Console.WriteLine("Sunucu baslatilamiyor...") ;
}
else
{
//Sonsuz dng sayesinde AgAkimini srekli okuyoruz
while(true)
{
Console.WriteLine("Istemci baglantisi saglandi...");

//IstemciSoketi verilerini NetworkStream sinifi trnden nesneye aktariyoruz.


NetworkStream AgAkimi = new NetworkStream(IstemciSoketi);

//Soketteki bilgilerle islem yapabilmek iin StreamReader ve StreamWriter


siniflarini kullaniyoruz
StreamWriter AkimYazici = new StreamWriter(AgAkimi);
StreamReader AkimOkuyucu = new StreamReader(AgAkimi);

//StreamReader ile String veri tipine aktarma islemi nceden bir hata olursa bunu
handle etmek gerek
try
{
string IstemciString = AkimOkuyucu.ReadLine();

Console.WriteLine("Gelen Bilgi:" + IstemciString);


//Istemciden gelen bilginin uzunlugu hesaplaniyor
int uzunluk = IstemciString.Length;

//AgAkimina, AkimYazn ile IstemciString inin uzunluunu yazyoruz


AkimYazici.WriteLine(uzunluk.ToString());

AkimYazici.Flush() ;
}

catch
{
Console.WriteLine("Sunucu kapatiliyor...");
return ;
}
}
}

IstemciSoketi.Close();
Console.WriteLine("Sunucu Kapatiliyor...");
}
}

te buda Istemci programmz. ncelikle unu belirtiyimki aadaki kodlarn ounu


Visual C# kendiliinden hazrlad, o yzden size Tavsiyem Visual C# kullanmanz.
ncelikle aadaki ekilde grdnz form yapsn benzer bir form hazrlayn.Sonra da
buton_click metodunu form_kapatma metodunu ve using ifadelerini ekleyin. Yada
zamannz oksa aadaki kodlar teker teker yazn. (steyene kaynak kodu da
gnderebilirim)

//client.cs

using System;
using System.Net.Sockets;
using System.IO ;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class Form1 : System.Windows.Forms.Form


{
//Burda server da tanmladklarmzdan farkl olarak TcpClient snf ile serverdan gelen
bilgileri alyoruz
public TcpClient Istemci;
private NetworkStream AgAkimi;
private StreamReader AkimOkuyucu;
private StreamWriter AkimYazici;

private System.Windows.Forms.Button buton;


private System.Windows.Forms.TextBox textbox;

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )


{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()


{
//Bu satrlar Visual C# oluturdu.
this.buton = new System.Windows.Forms.Button();
this.textbox = new System.Windows.Forms.TextBox();
this.SuspendLayout();

this.buton.Location = new System.Drawing.Point(8, 40);


this.buton.Name = "buton";
this.buton.Size = new System.Drawing.Size(248, 23);
this.buton.TabIndex = 0;
this.buton.Text = "Sunucuya Baglan";
this.buton.Click += new System.EventHandler(this.buton_Click);

this.textbox.Location = new System.Drawing.Point(8, 8);


this.textbox.Name = "textbox";
this.textbox.Size = new System.Drawing.Size(248, 20);
this.textbox.TabIndex = 1;
this.textbox.Text = "Buraya Sunucuya gndereceginiz yaziyi yazin";

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);


this.ClientSize = new System.Drawing.Size(264, 69);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textbox,
this.buton});
this.MaximizeBox = false;
this.Name = "Form1";
this.Text = "C#nedir?com";
this.Closing += new
System.ComponentModel.CancelEventHandler(this.form1_kapatma);
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
//giri noktamz olan mainde yeni bir form1 nesnesini altryoruz
static void Main()
{
Application.Run(new Form1());
}

//From1 yklendiinde TcpClient nesnesi oluturup AgAkmndan(NetworkStream) verileri


okuyoruz
private void Form1_Load(object sender, System.EventArgs e)
{
try
{
Istemci = new TcpClient("localhost", 1234);
}
catch
{
Console.WriteLine("Baglanamadi");
return;
}
//Server programnda yaptklarmz burda da yapyoruz.
AgAkimi = Istemci.GetStream();
AkimOkuyucu = new StreamReader(AgAkimi);
AkimYazici = new StreamWriter(AgAkimi);
}
}

private void buton_Click(object sender, System.EventArgs e)


{

//Kullanc butona her tkladnda textbox'ta yaz yoksa uyar veriyoruz


//Sonra AkimYazici vastas ile AgAkmna veriyi gnderip sunucudan gelen
//cevab AkimOkuyucu ile alp Mesaj la kullancya gsteriyoruz
//Tabi olas hatalara kar, Sunucuya balanmada hata olutu mesaj veriyoruz.
try
{
if (textbox.Text=="")
{
MessageBox.Show("Ltfen bir yazi giriniz","Uyari");
textbox.Focus();
return ;
}

string yazi;
AkimYazici.WriteLine(textbox.Text);
AkimYazici.Flush();
yazi = AkimOkuyucu.ReadLine();
MessageBox.Show(yazi,"Sunucudan Mesaj var");
}

catch
{
MessageBox.Show("Sunucuya baglanmada hata oldu...");
}
}

//TVe btn oluturduumuz nesneleri form kapatldnda kapatyoruz.


public void form1_kapatma(object o , CancelEventArgs ec)
{
try
{
AkimYazici.Close();
AkimOkuyucu.Close();
AgAkimi.Close();
}

catch
{
MessageBox.Show("Dzgn kapatilamiyor");
}
}

Aadaki server ve client programlarmzn ayn anda altklar srada alnm ekran
grntleri mevcuttur.

Yaz hakknda sorularnz bana sorabilirsiniz. Kaynak kodlar zel bir istek geldiinde
buraya koyabilirim.
C#'ta Temel Metin Dosyas lemleri

Micssoft NET ile programclarn hizmetine sunulan hazr snf ktuphaneleri sayesinde
dier dillerde programclar uratran birok konu zerinde program yazmak artk bir
zevk haline geldi. Girdi/kt (I/O) ilemleri de byle zevkli hale gelen konulardan biridir.
Biz bu yazmda metin dosyas (text file) ile ilgli temel birka ilem zerinde duracaz.

Metin dosylarn oluturmak, yazmak, ieriklerini okumak iin System isimuzaynda


bulunan Text alt uzayndaki snflar kullanyoruz. Aadaki programmzda 3 tane
metodumuz var. Birincisi, DosyayaYaz() metin dosyasn oluturup bu dosya ya birka
ey yazdryor. Bu metod nce StreamWriter snfndan dosya isimli bir obje oluturuyor.
Daha sonra StreamWriter snfnda bulunan WriteLine() metodu ile 2 satr yazyoruz
dosyamza. Son olarak dosyamz dosya.Close() ile kapatyoruz.

kinci metodumuz, DosyadanOku(), ise bir metin dosyasnn ieriini ekrana yazdryor.
Bunun iin nce StreamReader snfna ait dosyaOku nesnemizi oluturuyoruz. Sonra
dosyamz dosyaOku=File.OpenText(dosyaIsmi); komutu ile ayoruz. Dosyamzn ilk
satrnda bulunan yazy "yazi" isimli deikenimize yazi=dosyaOku.ReadLine(); ile
aktaryoruz. Bundan sonra ise eer okuduumuz satrda yaz varsa (yani dosyann sonu
deilse) o satr ekrana yazdrp bir sonraki satr okuyoruz. Okuma ve ekrana yazdrma
ilemlerini dosyann sonuna kadar (yada okuduumu satrn ieriinin null olana kadar )
devam ediyoruz. Son olarak ise dosyaOku.Close() ile dosyamz kapatyoruz.

nc ve son fonksiyonumuz ise metin dosyamzn sonuna bireyler ekleyen


DosyayaEkle()'dir. Yine StreamWriter snfndan dosya isimini verdimiz bir nesne
oluturuyoruz. Dosyamz File.AppenText() metodu ile ayoruz ki bu metod sayesinde
dosyann sonuna istedimiz veriyi kolayca ekleyebiliriz. dosya.WriteLine("Bu da en son
Append ile eklediimiz satr..."); komutu ile trnaklar arasnda metni dosyamzn sonuna
ekliyoruz. Her zamanki gibi atmz dosyay iimiz bitince hemen dosya.Close(); ile
kapatyoruz.

Aadaki program sisteminizde deerkeyi altrmanz ve hatta kod ile oynayp


deiiklikleri incelemenizde yarar olduunu dnyorum. Herkese baarlar...

using System;
using System.IO;
using System.Text;
class TextFile
{
public static void Main(string[] args)
{
// Metin dosyamza bireyler yazan fonksiyon..
DosyayaYaz();

// Metin dosyamz okuyan ve ekrana yazan fonksiyon


DosyadanOku("c:\\Deneme.txt");

// Metin dosyamzn sonuna bireyler ekleyen fonksiyon


DosyayaEkle("c:\\Deneme.txt");

Console.ReadLine();
}

static void DosyayaYaz()


{
//StreamWriter classndan dosya isimli bir nesne oluturalm
StreamWriter dosya = new StreamWriter("c:\\Deneme.txt");

//Dosyamza birinci satr yazalm


dosya.WriteLine("Metin dosyamzn ilk satr");

//Buda dosyamza yazdmz ikinci satr


dosya.WriteLine("kinci satr...");

//Dosyamzn kapatlm..
dosya.Close();

//Yazma ilemini baar ile tamamladmz kullancya bildirelim..


Console.WriteLine("Dosya yazm Baar ile tamamland...");

static void DosyadanOku(string dosyaIsmi)


{
// Text dosyasndan okuyan StreamReader snfna ait bir
// dosyaOku nesnesini oluturuyoruz
StreamReader dosyaOku;

// dosyadan okuyacamz yazy string olarak depolamak iin


// yaz nesnemizi oluturuyoruz.
string yazi;

//Dosyamz okumak iin ayoruz..


dosyaOku=File.OpenText(dosyaIsmi);

//Dosyamz okumak iin ayoruz ve ilk satrn okuyoruz..


yazi=dosyaOku.ReadLine();

/* okuduumuz satr ekrana bastrp bir sonraki satra geiyoruz


* Eer sonraki satrda da yaz varsa onu da okuyup ekrana bastryoruz.
* Bu ilemleri dosyann sonuna kadar devam ettiriyoruz.. */

while(yazi!=null)
{
Console.WriteLine(yazi);
yazi=dosyaOku.ReadLine();
}

// dosyamz kapatyoruz..
dosyaOku.Close();
}

static void DosyayaEkle(string dosyaIsmi)


{
//StreamWriter classndan dosya isimli bir nesne oluturalm
StreamWriter dosya;

// dosyamzn sonuna bireyler eklememek iin ayoruz..


dosya=File.AppendText(dosyaIsmi);

// dosyann sonuna birey ekliyoruz..


dosya.WriteLine("Bu da en son Append ile eklediimiz satr...");

// Dosyamz kapatyoruz..
dosya.Close();

Console.WriteLine("Dosyann sonuna baar ile ekledik...");


}

}
C# Dilinde Yaplandrclara Ar Yklenmesi

C# dilinde bulunan ve nesne ynelimli programlama kavram iinde yeralan gzel bir
zellii yaplandrclara ar yklenme konusunu bu yazmzda inceleyelim. Bazen bir
nesneyi olutururken bu ii birden farkl ekillerde yapmak zorunda kalrz.

Mesela elimizde bir programc snf var ve bu snftan oluturduumuz her programc
nesnesinin tm zelliklerini olutururken veremeyebiliriz. Programc nesnelerimizi
olutururken bir ksm bilgileri sonradan elde etmek durumda kalabiliriz. Veya baka bir
programda herhangi bir snfn bir rneini olutururken bu nesneye ait olan n tane
zelliin bir ksmna ihitiya duymadan girilmeyen parametrelere varsaylan deerler
atayarak iimizi halletme ansmz da var.

Aadaki programmzda, Programci snfmzn yasi, adi, soyadi ve kullandigiDil


olmak zere 4 tane zellii bulunmakta. Snfmzn 4 tane yaplandrcs var. Bunlarn
isimleri ayn (zaten yaplandrcnn ismi snf ismi ile ayn olur). Farkl olan ise aldklar
parametre saylar ve tipleri olabilir.

Srasyla, birinci yaplandrc hi bir deer almyor. kinci yaplandrcmz iki tane
deiken alyor. Bunlardan yas ve adi deerleridir. ncs ise yas, adi ve soyadi
parametrelerini alarak nesnemizi oluturuyor. Son yaplandrcmz ise yas, adi, soyadi
ve kullandigiDil deikenleridir. lk yaplandrc alnmayan yas deikenine 0
dierlerine null deerleri atyor.

Snfmzn beinci ve son metodu ise bu snftan rettiimiz bir nesnenin zelliklerini
ekrana yazdryor. Eer nesnenin bir zelliinin deeri varsa onu yazdryor, yoksa bu
zellik hakknda bir malumatmz yok gibisinden bir uyar yazyor ekrana.

Pogrammzn Main() fonksiyonu iinde nce 4 tane (a, b, c, ve d) programc nesnesi


oluturuyoruz. Bunlarn herbirini ayr yaplandrclar ile oluturuyoruz. showOzellik()
metodumuz ile bunlarn herbirinin zelliklerini ekrana yazdryoruz.

using System;

class OverLoadedFunctions
{
static void Main(string[] args)
{
Programci a = new Programci();
Programci b = new Programci(23,"Ziya");
Programci c = new Programci(27,"Kamuran","Kamilolu");
Programci d= new Programci(30,"Hayrettin","Ktk","C#");

a.showOzellikler();
b.showOzellikler();
c.showOzellikler();
d.showOzellikler();

Console.ReadLine();
}
}

class Programci
{
int yasi;
string adi;
string soyadi;
string kullandigiDil;

// Hic parametre almayan bir yaplandrc..


public Programci()
{
this.adi=null;
this.yasi=0;
this.soyadi=null;
this.kullandigiDil=null;
}

// smini ve yasini alan bir yaplandrc..


public Programci(int yasi, string adi)
{
this.adi=adi;
this.yasi=yasi;

this.soyadi=null;
this.kullandigiDil=null;
}

// smini, soyismini ve yasini alan bir yaplandrc..


public Programci(int yasi, string adi, string soyadi)
{
this.adi=adi;
this.yasi=yasi;
this.soyadi=soyadi;

this.kullandigiDil=null;
}

// smini, soyismini kulland dili ve yasini alan bir yaplandrc..


public Programci(int yasi, string adi, string soyadi, string kullandigiDil)
{
this.adi=adi;
this.yasi=yasi;
this.soyadi=soyadi;
this.kullandigiDil=kullandigiDil;
}

public void showOzellikler()


{
Console.WriteLine("***************************************************************

if(this.yasi!=0)
Console.WriteLine("Yasi : "+this.yasi);
else Console.WriteLine("Yasi bilgisi elimizde yok u anda...");

if(this.adi!=null)
Console.WriteLine("Ad : "+this.adi);
else Console.WriteLine("Adi bilgisi elimizde yok u anda...");

if(this.soyadi!=null)
Console.WriteLine("Soyad : "+this.soyadi);
else Console.WriteLine("Soyad bilgisi elimizde yok u anda...");

if(this.kullandigiDil!=null)
Console.WriteLine("Kulland Programlama dili : "+this.kullandigiDil);
else Console.WriteLine("Hangi Dili kullann bilmiyoruz be... :-(\n");

Console.WriteLine("\n***************************************************************

}
C# sim uzaylar (namespace) Hakknda

Bu yazmzda C# dilindeki namespace ler hakknda geni bir bilgi edineceiz. Bildiiniz
gibi programlama dillerinde, programclarn ilerini kolaylatrmak iin bir takm hazr
ktphaneler mevcuttur, bu ktphanelerden bazlar standart olmakla birlikte bazlar
programclar tarafndan sonradan gelitirlmi ve kullanclarn hizmetine sunulmutur.
Mesela MFC ve ATL gibi kthanelerin kendilerine has amalar vardr, MFC ktphanesi
ile bir takm hazr C++ snflarna ulaarak temelde zor olan bir takm Windows
platformuna zg ilemleri (forms, dialog box vs.) yapabiliriz. Bu da MFC programclarna
alr bir uygulama yapmak iin daha az zaman harcatr. Bu tr ktphaneler Visul Basic
te ve Java dilinde de vardr. Fakat bu dillerin aksine C# dili ile gelen hazr bir takm snf
ktphaneleri bulunmamaktadr, ksacas standart bir C# ktphanesi mevcut deildir.
Bu demek deildir C# ile iimiz daha zor olacak, aslnda daha kolay, .NET Framework
dediimiz altyapnn bize veya dier programlama dillerini kullanan programclara
sunduu bir takm temel trler ve snflar mevcuttur. Btn bu snflar ve trleri binary
dzeyde iyi organize edebilmek iin .NET, namespace kavramn sklkla kullanmaktadr.
Demekki .NET teki snf ktphaneleri bir dilden bamsz bir yapdadr. MFC gibi sadece
C++ iin yada baka bir dil iin gelitirilmemitir. ok normal olarak Visual Basic.NET
kullancs ile C# kullancs ayn ktphaneden faydalanrlar.

Namespace ler .NET Framework snf ktphanesindeki veri trlerini ve snflar


kullanabilmemiz iin C# dilinde using anahtar szc ile birlikte kullanlr ve derleyiciye
bildirilir. Dier dillerde ise bu isimalanlar farkl ekilde derleyiciye bildirilir, ama temelde
yaplan i .NET Framework snf ktphaneslerini kullanma hakk almaktr. Aada C#,
Visual Basic ve Managed C++ ile yazlm 3 farkl ama ayn ii yapan 3 program
gryorsunuz. Programlar dikkatlice incelediinizde namespace lerin sadece eklenme
biimi ve namespace lerde ki snflarn sentaks olarak kullanm farkl. Bize sunudu
arayzler ise zel durumlar dnda tamamen ayndr.

[C#]

using System;

public class C#nedir


{
public static void Main()
{
Console.WriteLine ("Merhaba, beni C# ile yazdlar.")
}
}

[VB.NET]

Imports System

Public Module C#nedir

sub Main()

Console.WriteLine ("Merhaba, beni VB.NET ile yazdlar.")

End Sub

[Managed C++]

using namespace System;

public static void Main()


{
Console::WriteLine ("Merhaba, beni managed C++ ile yazdlar.")
}

Yukardaki programlarda grdnz gibi .NET platformunu destekleyen btn diller ayn
snf kullanarak ekrana yaz yazdryorlar.Bu snf System isimalan iinde bulunan
Console snfna ait bir fonksiyonla gerekletirilmektedir.

Namespace leri kendi yazdmz kodlarn organizasyonu iinde kullanabiliriz. Hem byle
tr isimlerinin karmasnda nlemi oluruz, zira bir tr ismi yada snf ancak kendi
isimalan iinde grnrle(visibility) sahiptir. Mesela System isimalann eklemeden
Console snfn kullanamayz. Ayn ekilde kendi yazdmz snflar iin de isimalanlar
tanmlayarak, kaynak kodumuzu istediimiz bir ekilde organize edebiliriz. .NET
Framework snf ktphanesi hiyerarik bir yapya sahip olduu iin ieie isimalanlar
tanmlanmtr.

simalanlarnn kullanmna bir rnek verecek olursak : Diyelimki 2D (iki boyutlu)


grafikleri ieren bir snf ktphanesi gelitiriyoruz, ve bu snf ktphanesi iinde "Nokta"
adl bir snfmz var. Bu isimalann tanmlamak iin namespace anahtar scnn
aadaki gibi bir kullanm vardr.

namespace 2DGraph
{
public class Nokta
{
......
}
}

Yukardaki Nokta snfn kullanabilmek iin programmza using deyimi ile isimalann
eklememiz gerekir.Bu ilem aadaki gibi yaplr.

using 2DGraph;
Nihayet 2DGraph isimli snf ktphanesini oluturduk ve bakalarnn kullanmna
sunduk. Bi sre sonra da 3DGraph isimalan ad altnda 3 boyutlu grafik ilemleri yapan
yeni bir snf ktphanesi gelitirdik ve te tekrar programclarn hizmetine sunduk. Yine
ayn ekilde 3 boyutlu noktay temsil etmek iin Nokta snfmz olsun

namespace 3DGraph
{
public class Nokta
{
......
}
}

imdi 2DGrap ve 3DGraph snf ktphanelerinin herikisini birden kullanmak isteyen bir
programc using ile isimalnlarn ekledilten sonra Nokta trnden bir nesne oluturmak
istediinde derleyici bunun 2D Nokta m yoksa 3D Nokta m olduunu nerden bilecek.
Bunu zmenin iki yolu vardr. Birincisi veri tipi belirlerken aadaki ekildeki bir kullanm
tercih edilir.

Veri trlerinin bu ekilde belirtilmesi pek tercih edilmeyen bir yntemdir. nk iie bir
ok isimalannn tanmland durumlarda kaynak kodumuz gereksiz yere isimalanlarn
yazmakla uzamaktadr. Bu hem okunabilirlii bozmakta hemde programcya zaman
kaybettirmektedir.

using System;
using 3DGraph;
using 2DGraph;

public class C#nedir


{
public static void Main()
{
3DGraph.Nokta 3dnokta = new 3DGraph.Nokta();
2DGraph.Nokta 2dnokta = new 2DGraph.Nokta();
}
}

kinci bir yntem ise isimalanlarnda bulunan snflar iin takma isim (alias)
kullanmaktr.Bu sayede isimalanlarn bir kez eklediketen sonra o isim alannda bulunan
snflara dorudan eriebiliriz. Bir isim alanndaki snfa takma ad aadaki ekilde verilir.

using System;
using 3DGraph;
using 2DGraph;

public class C#nedir


{

using Nokta2D= 2DGraph.Nokta;


using Nokta3D = 3DGraph.Nokta;

public static void Main()


{

Nokta2D 2dnokta = new Nokta2d();


Nokta3D 3dnokta = new Nokta3d();
}
}

Yukarda mavi yaz ile berlirtilen yerlerde takma isimler tanmlanmtr. Takma isimler
ancak ve ancak tanmlanadklar blok iinde geerlidir. Baka bloklarda takma adlar
kullanmak derleme zamannda hataya yol aar.

Sonu : simalanlar component(program parac) yazmann en nemli parasdr. Bir


"Merhaba Dnya" program iin isimalan belitmek sizde takdir edersinizki pek anlam
tamamaktadr. simalanlar daha ok kodumuzun tekrar kulllabilirliini artrmak iin
gelitirilen snf ktphanelerinde kullanlrlar.

C# Dilindeki Temel Veri Trleri

Her dilde olduu gibi C# dilinde de nceden tanmlanm ve dillerin temelini oluturan
veri saklamak iin kullanlan bir takm veri tipleri vardr. Bu makalemizde C# dilinde
kullanlan veri trlerine deineceiz. C# dilinde temel olarak veri tipleri ikiye ayrlr,
bunlar nceden tanmlanm veri trleri ve kullanc tarafndan tanmlanm veri trleridir.
nceden tanmlanm veri trleri de kendi arasnda referans tipi(reference types) ve
deer tipi(value type) olmak zere ikiye ayrlr. Bu detayl bilgileri vermeden nce veri
tipleri nasl tanmlanr, veri trlerine nasl ilk deer verilir ve veri trlerinin faaliyet alan
gibi temel konulardan bahsetmek istiyorum.

Deiken Kavram

Deikenler bir programlama dilinde temel verileri saklamak ve bu verileri sonradan


kullanmak iin kullanlan bellek blgeleridir. C# dilinde genel olarak bir deiken
tanmlamas aadaki gibi olmaktadr.

Veritipi veriad ;

rnein C# dilinde iaretsiz ve 32 bitlik veriyi temsil eden "a" isimli bir deiken
aadaki gibi tanmlanr.

int a ;

Fakat yukardaki tanmlamada bir sorun var. "a" adl deikende herhangi bir deer
tutulmaktadr.Bu yzden C# derleyicisi imdilik "a" deikenini kullanmamza msade
etmez, nk "a" da neyin olduu henz belli deildir.Bu yzden deikenlere =(eittir)
operatryle ilk deerler atarz, ya da deiken tanmlamasndan sonra, deikene bir
deer atarz. Bir deikene bir deer atamak iin iki farkl yntem kullanlr. Aada bu
iki ynteme ait rnek bulunmaktadr.
int a = 10 ; //deiken tanmlanrken bellekteki deer 10 olarak dzenleniyor.

--------------------

int b;
b = 10 ; /*deiken tanmlandktan sonra deikene deer atanyor.levsel olarak bu
iki kullanm asndan bir fark yoktur.*/

--------------------

int a=10, b;
b = 10 ; /*eer bir satrda birden fazla deieken tanmlamas yapmak istiyorsak bu
yapy kulanrz.Bu durumda a ve b int trden deikenlerdir denir.*/

nemli Not: C# dilinde bir deikene herhangi bir deer atamadan onu kullanmak
yasaktr. Yani derleme ilemi gereklemez, rnein aadaki gibi bir kullanm derleme
zamannda hata verecektir. Bu yzden eer bir deikeni kullanmak istiyorsak yukarda
akladmz gibi deikenlere bir deer vermek zorundayz. Bu kural nceden
tanmlanm referans tipleri iin de deer tipleri iin de geerlidir.

int a ;
Console.WriteLine(a); //Bu ifadeleri ieren bir kod derlenemez.

Deikenlerin Faaliyet Alanlar (Scope)

C# dilinde programn genel ak alan ve kapanan parantezler ierisinde yazlr. Bu


alan ve kapanan parantezler arasndaki blgeye blok denir. Tanmlanan bir deikene,
ancak tanmland blok ierisinde ulalabilir. rnein aadaki ksa rnekte tanmlanan
rnekte her iki "a" deikeni birbirinden bamszdr ve bellekte ayr blgelerde
saklanrlar.

public class deneme


{
public static void Main()
{
{ //Birinci blok
int a=20 ;
}
{//kinci blok
int a=20 ;
}
}
}

Yukardaki rnekte birinci ve ikinci blokta tanmlanan "a" isimli deikenler Main blou
iinde geersizdir. Birinci a deikeninin faaliyet alan 1.Blok ,ikinci a deikenin faaliyet
alan ise 2. Bloktur. Bu durumda Main() blounda Console.WriteLine(a); gibi bir ifade
hataldr, nk Main blou iinde tanmlanan bir a deikeni yoktur. Unutmamalyz ki
daha sonraki makalelerde detayl olarak greceimiz for ve dier dngler de birer blok
olduu iin bu bloklarda tanmlanan deikenler dng blounun dnda geersiz
olacaktr. Dier bir nemli nokta ise faaliyet alan devam eden bir deikenin bir daha
tanmlanmasnn hataya yol amasdr. rnein aadaki gibi bir durum derleme
zamannda hata verecektir. nk bir deikenin faaliyet alan bitmeden ayn isimli
deiken tekrar tanmlanyor.
public class C#nedir?com
{
public static void Main()
{
int a;
{
int a=20 ;
}
}
}

Grdnz gibi Main blounda tanmlanan a deikeninin faaliyet alan alan blokta
devam etmektedir.Bu yzden yukardaki gibi ifadeler geersidir.st seviyede alan
bloklar alt seviyedeki bloklar kapsad iin, birinci tanmlanan a deikeni sonradan
alan blok iinde hala geerlidir.

Yukarda anlatlan duruma ters dyor gibi grnse de aadaki gibi bir kullanm son
derece legal bir durumdur. Bu konuyu daha sonraki makalelerimizde detayl bir ekilde
inceleyeceiz.

public class C#nedir?com


{
static int a = 10;
public static void Main()
{
int a;
{
int a = 10 ;
}
}
}

Bu konu snflarla ilgili bir konu olduu iin detaylarna girmeyeceiz ama imdilik byle
bir kullanmn geerli olduunu bilmenizde fayda var.

Sabitler

Bir program boyunca deerinin deimeyeceini dndmz verileri sabit veriler


olarak tanmlarz. Sabit veriler tanmlamak iin tanmlama satrnda const anahtar
szcn kullanrz. const olarak tanmlanm deikenlerin en byk avantaj program
iinde ska kullandmz deerleri aniden deitirmek gerektiinde grlr.Mesela
matematiksel ilemler yapan bir programda pi saysn const olarak tanmlayp istediimiz
zaman pi saysn deitirebiliriz. Tabi bu ilemi const deilde normal bir deikenle de
yapabilirdik, ama u da bir gerek ki ok uzun programlarda sabit olmasn istediimiz
deikeni yanllkla deitirebiliriz. Fakat const olarak tanmladmz bir deikenin
deerini deitirmeye altmzda c# derleyicisi derleme aamasnda hata verecektir.
Bu da gzden kaan baz hata durumlarn minimuma indirmek demektir. Sabit
ifadeleriyle ilgili bilmemiz gereken 3 nemli kural vardr. Bunlar unlardr :

1-) Sabitler tanmlandklarnda deerleri atanmaladr. lk deer verilmeyen deikenler


const yani sabit olamazlar.
2-) Sabit ifadelere ancak sabit ifadelerle ilk deer atanabilir yani u ekildeki bir kullanm
hataldr. const int = a + b ;
3-) Sabit ifadeleri isel tasarm olarak zaten statik olduklar iin, ayrca statik olarak
belirtmek hataldr ve kullanlamaz.(statik deikenler ileriki yazlarda detayl olarak
anlatlacaktr.)
Basit bir sabit tanmlamas aadaki gibi yaplmaktadr.

const double pi = 3.14 ; // double, kesirli saylar tutmak iin tanmlanm bir veri
trdr.

Deer(value) ve referans(reference) tipleri

C# dilinde nceden tanmlanm(c# dilinde varolan tipler) veri tipleri deer tipleri ve
referans tipleri olmak zere ikiye ayrlr. Bu iki veri tipi arasndaki fark ok iyi kavramak
gerekir. Daha nce dediimiz gibi deikenler bellekte bulunan verilerdir. Aslnda bir
deikeni kullanrken o deikenin bellekte bulunduu adresteki veriye ulayoruz. Deer
tipleri deikenin deerini direkt bellek blgesinden alrlar. Referans tipleri ise baka bir
nesneye referans olarak kullanlrlar. Yani referans tipleri aslnda bir eit bellek blgesi
olan heap alannda yaratlan veri trlerinin (bunlara ksaca nesne de diyebiliriz)
adreslerini saklarlar. Deer tipleri yaratldklarnda stack dediimiz bellek blgelerinde
oluturulurlar, referans tipleri ise kullanm biraz daha snrl olan heap dediimiz bellek
blgesinde saklanrlar. C ve C++ dillerine aina olan arkadalarn da tahmin ettii gibi
gsterici kavram ile referans veri tipleri arasnda ok fazla fark yoktur. Fakat C# dilinde
kullancnn direkt olarak kullanabilecei bir gsterici veri tr tanmlamak yoktur. Bunun
yerine baz deikenler deer tip bazlar ise referans tipi olarak ilem grrler. Peki
bunlar nelerdir? Temel veri tipleri olan int,double, float ve yap nesneleri gibi veri trleri
deer tipler, herhangi bir snf tr ise referans trdr. ki deer tipi nesnesini birbirine
eitlerken deikenlerde saklanan deerler kopyalanarak eitlenir ve bu durumda iki yeni
bamsz nesne elde edilmi olur yani birinin deerini deitirmek dierini etkilemez,
ancak iki referans tipini birbirlerine eitlediimizde bu nesnelerde tutulan veriler
kopyalanmaz, ilem yaplan nesnelerin heap blgesindeki adresleridir, yani iki nesne de
aslnda heap bellek blgesinde ayn adresi gsterecekleri iin birinde yaplan deiiklik
dierini de etkileyecektir. Referans tiplerini tanmlarken herhangi bir adresi
gstermediini belirtmek iin null deere atanrlar.(Mesela: y = null ;)

CTS (Common Type System) Tipleri

.NET bir yazlm gelitirme platformudur. Aslnda btn veri tipleri CTS dediimiz bir
sistem ile tannrlar. Yani C# dilinde ki veri trleri aslnda CTS 'deki veri trleri iin birer
arayz gibidirler. CTS sayesinde .NET platformu iin gelitirilen btn diller ayn veri
tiplerini kullanrlar, tek deien veri trleni tanmlama yntemi ve sentaksdr. Bu yzden
bizim C# dili ile tanmlayacamz her veri tipinin CTS 'de bir karl mevcuttur. Bu veri
trleri ve CTS karlklar aada tablolar halinde mevcuttur.

C# dilinde tanmladmz btn basit veri tipleri aslnda CTS 'de bulunan bir yap
nesnesidir.C# dilindeki nceden tanmlanm temel veri tipleri on be tanedir. Bunlardan
on deer tipi ikisi de deer tipidir.

nceden Tanmlanm Value Veri Tipleri

Aada temel value tiplerin C# dilindeki ad, CTS karl, aklamas ve kullanm aral
bulunmaktadr.

C# taki
CTS Karl Aklama Max ve Min aralk yada deeri
ad
8 bit iaretli
sbyte System.Byte -128 : 127
tamsay
short System.Int16 16 bit iaretli -32.768 : 32.767
tamsay
32 bit iaretli
int System.Int32 -2.147.483.648 : 2.147.483.647
tamsay
64 bit iaretli -9.223.372.036.854.775.808 :
long System.Int64
tamsay -9.223.372.036.854.775.807
8 bit iaretsiz
byte System.Byte 0 : 255
tamsay
16 bit iaretsiz
ushort System.UInt16 0 : 65.535
tamsay
32 bit iaretsiz
uint System.UInt32 0 : 4.294.967.295
tamsay
64 bit iaretsiz
ulong System.UInt64 0 : 18.446.744.073.709.551.615
tamsay
32 bit tek kayan
float System.Single +yada - 1,5*10-45 : + ya da - 3,4*1038
say
64 bit ift kayan
double Sytem.Double +yada - 5*10-324 : + ya da - 1,7*10308
say
128 bit ondalkl
decimal System.Decimal +yada - 1,5*10-28 : + ya da - 7,9*1028
say
bool System.Boolean true ya da false
Karakterleri
char System.Char 16 Unicode karakterleri
temsil eder

imdi tabloda verilen veri trleri ile ilgili tanmlamalara rnekler verelim :

long a = 0xEF20 ; // 0x neki saylar hexadecimal olarak yazmamz salar.


ulong ul = 5698UL ; // Saynn sonuna UL koyarak UnsignedLong olduunu belirtiyoruz.

float fl = 3.14f ;

decimal d = 65.25M;

bool b = false ;

char ch1 = 'a' , ch2 = '\\' , ' \" ' , 'm' ;

nceden Tanmlanm Reference Veri Tipleri

C# dilinde nceden tanmlanm iki tane referans tipi vardr. Bunlar string ve object
trleridir. Object tr C# dilinde btn trlerin tredii bir snf yapsdr. Kullanc
tarafndan sonradan tanmlanacak btn veri tipleri de aslnda Object trnden tremi
olacaktr. Bu da object trnden bir nesneye herhangi bir veri trnden nesneyi
atayabileceimiz anlamna gelir. nk C# dilinde btn nesneler bir object'dir. object
'ler zellitirilerek farkl amalar iin kullanlr. Herhangi bir nesneyi object tr ile
eletirme kavram boxing olarak adlandrlr. Boxing ve bunun tersi ilemi olan unboxing
kavramlarn daha sonraki makalelerimizde detayl olarak inceleyeceiz.

Dier bir referans tipi ise string trdr. C ve C++ gibi dillerde string ilemleri
yapabilmek iin karakter dizileri tanmlanr ve bunlar string olarak ileme alnrlar ancak
C# dilinde karakter dizileri tanmlamak yerine string ad ile yeni bir tr mevcuttur.
String veri tr birtakm yararl iler daha kolay bir ekilde yaplmaktadr. Mesela aada
iki string' in + operatryle arka arkaya nasl eklendii gsterilmektedir. + operatr
burada string snf iin yklenmitir(overload). Overloading kavram bal bana bir
makale konusu olduu iin burada deinmeyeceim.

string s1 = "Hello " ;


string s2 = ".NET" ;
string s3 = s1 + s2;

Bir dilin sentaks asndan zel anlamlar ifade eden karakterleri kullanmak istiyorsak
bunlar \ (escape) ifadesiyle belirtmek gerekir. Mesela bir dizin bilgisini ieren bir string
nesnesini aadaki gibi tanmlarz.

string yol = "C:\\docs\\xxx\\" ;// Bu tr kullanma escape sequence kullanm denir.

Escape sequence 'leri kullanmak yerine string iinde grnen ifadenin ayns belirtmek
iin string ifadesinin nne @ iareti kullanlr.Mesela ;

string esc = @"C:\docs\xxx\" // byle bir kullanmda escape karakterini kullanmay


kaldrm oluyoruz.

C# taki ad CTS Karl Aklama


Btn veri trlerinin tredii kk
object System.Object
eleman
string System.String Unicode karakterlerinden oluan string

Yukarda C# dilindeki temel referans veri trleri tablo halinde gsterilmitir.

Bir sonraki makalemizde C# temel kontrol yaplarn greceiz.


C# ile Windows Registry lemleri(Microsoft.Win32)

Hemen hemen her profesyonel uygulamada grdmz Registry'ye yazma ve ordan


okuma ilemlerinin nasl yapldn basit bir uygulama ile anlatacaz. Dnnki bir
uygulama gelitirdik ve uygulama her altnda kullancy selamlamak istiyoruz ve
uygulamay kanc defa altrdn sylemek istiyoruz ona. Bunun bir ok yolu olmasna
ramen en gzel ve en gvenilir yolu ilgili bilgileri Windows un registry dediimiz
blgesinde tutmaktr. registry dediimiz yerler olmasayd pek ala bu ii dosyaya yazma
ve okumayla da yapabilirdik. Regsitery blgesini okuma ve yazma amal .NET framework
snf ktphanalerinden faydalanacaz. Bu snflar Microsft.Win32 isimalannn altnda
bulunmaktadr. Bu snflarn en ok kullanlan metodlarn ve zelliklerini anlatmaya
balamadan nce programzn yapsn ksaca anlataym.

Bir console uygulamas oluturacaz. Program ilk altnda bize bundan sonraki
allarnda bizi selamlamas iin admz soracak.Daha sonra program altrdmzda
"Hogeldin Sefer. Program 3. defa altryorsunuz." diyecek. Programn ka defa
altn anlamak iin ise program ilk aldnda registry blgesine "1" deerini
yazacaz ve programn her altnda o deeri bir artracaz. Bylece programn ka
defa altn renmi olacaz. Tabi eer Windows un <regedit> aracyla daha
nceden uratysanz bizim programlama yoluyla deitirdiimiz deerleri kendi
ellerinizle gidip deitirebilirsiniz. Demek istediim burda ifre ve kullanc ad gibi baz
kiiye zel bilgilerin saklanmas pek gvenli deildir.

Eer u ana kadar registry hakknda bir bilginiz yoksa Start->Run ' menusune gelip
regedit yazarak registry hakknda biraz bilgi edinebilirsiniz. Bu programla rastgele
deerler silerseniz baz programlarnz zarar grebilecei iin tavsiyem her hangi bir silme
ilemi yapmayan ve sadece neler olup
bittiine bakn.

imdi C# n byk bir kolaylk salad registry yazma ve okuma iin gelitirilmi
RegistryKey snfnn ilevlerini grelim.

:::: RegistryKey Snf(Microsoft.Win32) ::::.

Bildiiniz gibi windowsun register yaps aa eklindeki klasrlere benzer. Her yeni
anahtar altnda bir alt anahtar aabildiimiz gibi anahtarlar altnda yeni "string" yada "int"
gibi deerler oluturup programla ilgili istediimiz deerleri saklayabiliriz. Bu ise
klasrlerde oluturduumuz dosyalara benzer. Daha ncede dediimiz gibi buraya regedit
le kolayca ulaabildiimiz iin gvenlik amal bilgileri (ifre vs) veya programmzla ilgili
kritik bilgileri(serial number vs) burada saklamamamz gerekir. Biz bu programdaki
bilgilerimizi HKEY_LOCAL_MACHINE\Software altnda csnedir isimli bir alt anahtar
oluturarak kaydedeceiz.

RegisteryKey snf trnden bir nesne oluturmak iin ya RegiteryKey snfnn static ye
fonksiyonu olan OpenSubKey() metodunu yada yada Register snfnn static yelerini
kullanrz. Ada detayl olarak bu metodlar hakknda bilgi bulabilirsiniz.

:: CreateSubKey() Metodu ::

Geriye RegistryKey trnden bir nesne ddren bu fonksiyon yeni bir alt anahtar
oluturur yada var olan bir anahtar okumak iin aar.Fonksiyonun prototipi aadaki
gibidir. Unutmayn bu metodu kullanabilmek iin ilgili kullancnn register blgesine
eriim hakknn olmas gerekir. Aksi halde SecurityException hatas oluur.

public RegistryKey CreateSubKey(string subkey);

:: OpenSubKey() Metodu ::

Bu metod iki ekilde kullanlabilir, overload edilmi iki metod aadaki gibidir.

public RegistryKey OpenSubKey(string);//Bu metod anahtar okumak amcyla kullanlr ve


geriye RegisteryKey dndrr.

public RegistryKey OpenSubKey(string,bool);//Bu metod ilk metod ile ayndr fakat eer
alacak anahtara yazmada yapacaksak ikinci parametreyi true olarak girmemiz gerekir.
Varsayaln olarak ReadOnly alr.

:: DeleteSubKey() Metodu ::

Bu metod iki ekilde kullanlabilir, overload edilmi iki metod aadaki gibidir.

public void DeletSubKey(string);//Parametre olarak gnderilen alt anahtar siler.

public void DeletSubKey(string,bool);//Parametre olarak gnderilen alt anahtar


siler.kinci parametre ise belirtilen alt anahtarn olmamas durumunda
"ArgumentNullException" hatasnn yakalnp yakalanmayacan gsterir.Eer true ise bu
hata yakalanr, false ise herhangi birey olmaz.

:: DeleteSubKeyTree() Metodu ::

Bu metod iki belirtilen anahtardaki btn anahtarlar siler.Bir dosyay sildiinide iindeki
tm dosyalar sildiiniz gibi.Prototipi aadaki gibidir.
public void DeletSubKeyTree(string);

:: DeleteValue() Metodu ::

ki ekilde kullanlabilir.Parametre olarak belirtilen deeri anahtardan siler.kinci


parametre ise DeleteSubKey() metodunda olduu gibi hata yakalanp yakalanmayacan
belirtir.

:: Flush() Metodu ::

Registry 'de yaptmz deiiklikleri diske kaydetmek iin bu metodun arlmas gerekir.
:: GetSubKeyNames() Metodu ::

Be metod geriye dndrd string dizisine ilgili anahtardaki alt anahtar isimlerini
doldurur.Prototipi aadaki gibidir.

public string[] GetSubKeyNames()

:: GetValue() Metodu ::

lgili anahtardaki deerin ieriini object tr olarak geri dnderir.ki ekilde kullanlabilir.
Parametrik yaps aadaki gibidir.

public object GetValue(string)


public object GetValue(string,object) //eer deer yoksa varsaylan olarak parametre
olarak verilen object geriye dner.

:: GetValueNames() Metodu ::

lgili anahtardaki btn deerleri bir string dizine aktarr.Parametrik yaps aadaki
gibidir

public string[] GetValueNames()

:: SetValue() Metodu ::

Birinci parametresi ile belirtilen anahtara ikinci parametresi ile belirtilen bilgi
aktarlr.Parametrik yaps aadaki gibidir.

public void SetValue(string,object)

:: Name zellii ::

Taban anahtardan itibaren(mesela HKEY_LOCAL_MACHINE) ilgili anahtarn tam yolunu


verir.

:: ValueCount zellii ::

Anahtarda bulunan deerlerin saysn verir.

RegistryKey snfnn ye elmanlar ve oluturduu exception snflar ile ilgili detayl bilgiyi
MSDN Online' dan yada .NET Framework SDK Documentation ' dan edinebilirsiniz.

imdi yazmzn banda bahsettiimiz rnek uygulamamza gz atalm.Aada bulunan


kaynak kodda satr aralarna size yardmc olacak yorumlar ekledim.

//registry.cs

using System;
using System.Win32
//RegistryKey snfn kaynakkodda direkt kullanabilmek iin bu isimalann ekledik.

class CsReg
{
public static void Main()
{
RegistryKey register;
register = Registry.LocalMachine.OpenSubKey(@"Software\csnedir",true);
//HKEY_LOCAL_MACHINE/Software/csnedir anahtarn oluturup anahtara yazma
modunda ayoruz.

if (register.GetValue("ad") == null)
{
/*Bu if blounda programn ilk defa almas durumu ile ilgili ilemler
yaplyor.Programn ilk defa altn register.GetValue("ad") ==null ifadesi ile anlyoruz.
Kullancdan isim alnp registry de "ad" isimli anahtara yazlyor ve tabili "Oturum"
adnda program bir defa altrdn belirten 1 deeri yazlyor*/
Console.WriteLine("Ltfen adinizi yaziniz");
string ad = Console.ReadLine();
register.SetValue("ad",(string)ad);
register.SetValue("oturum",1);
Console.WriteLine("Tesekkrler...");
}
else
{
/*Bu blokta ise programn sonraki almalar ile ilgili ilemler yaplyor. Oturum says
registry den okunup aritmetik iem yapabilmek iin ilgili formata dntrdkten sonra
tekrar yeni deeri ile registry ye yazlyor.Ayn ekilde registry den "ad" deeri alnarak
kullanc selamlanyor.*/
string ad = (string)register.GetValue("ad");

int oturum_sayisi=Convert.ToInt32(register.GetValue("oturum"))+ 1;
register.SetValue("oturum",oturum_sayisi);
Console.WriteLine("Hosgeldin " + ad);
Console.WriteLine("Programi " + oturum_sayisi + " kez atiniz");
Registry.LocalMachine.Flush();
}
}
}
Assembly, ILDASM.exe ve GACUTIL.exe Hakknda

Bu makalede kavram olarak en ok kartrlan ve anlalmas dier konulara gre zor


olan Assembly kavramn ve Visual Studio ile birlikte gelen GACUTIL ve ILDASM gibi
nemli aralar inceleyecegiz.

Asembly Nedir?

Hemen ilk bata belirtelim ki bu makalede bahsedeceimiz Assembly'nin alt seviye bir
programlama dili olan Assembly ile yakndan uzaktan hibir alakas yoktur. Sadece bir
isim benzerlii vardr. .NET platformunda yazdmz kodlar sonucunda oluturduumuz
btn .exe uzantl dosyalara ve .dll uzantl dosyalara genel olarak Assembly
denilmektedir. Projemize ait derlenmi kodlar ve metadata dediimiz bir takm
zniteleyici kodlar Assembly'ler ierisinde bulunur. Assembly'lerin kabaca zellikleri
aadaki gibi sralanabilir.

1-) Assembly'lerde metadata denilen veriler, Assembly'deki tr bilgileri ve baka


kaynaklarla olan balantlar saklanr.

2-) Assembly'de(dll yada exe) kendilerine ait versiyon bilgisi tutulur. Hatrlarsanz klasik
dll ve exe tipi dosyalarda versiyon bilgisi saklanmad iin eitli uyumsuzluklar
yaanabilmekteydi. Mesela farkl iki firmann hazrlad dll 'ler ayn isimli olduunda
sonradan register edilen dll halihazrda bulunan dll 'in zerinde yazld iin sistemde
bulunan baz uygulamalarda sorun kyordu. Dll 'ler bu tr sorunlara yol at iin DLL
Hell (Dll cehennemi) kavram ortaya kmt. Aslnda COM dll 'leri ile bu sorun bir nebze
ortadan kalkmsa da asl zm Assembly'ler ile gelmitir.

3-) Assembly'lerde versiyon bilgisi sakland iin bir uygulama ierisinde farkl
versiyonlara sahip Assembly'leri kullanabiliriz.

4-) Program kurma ilemi, Assembly 'ye ilikin dosyay direkt kopyalayarak yaplabilir.
Eski sistemde DLL 'lerin register edilmesi gerekiyordu.

Assembly'lerin en nemli zelliklerinden birisi de Application Domain dediimiz


kavramdr. Application Domain sayesinde bir proses iinde birden fazla birbirinden
bamsz alan Assembly 'yi altrma imkanna kavuuruz. Bu konuya aklayc bir
rnek olmas asndan aadaki rnei inceleyebilirsiniz.
Bu rnekte iki tane Console uygulamas yapacaz. Bu iki uygulamaya ait alr
durumdaki dosyalara artk Assembly diyebilirsiniz. Aadaki ilk rnekte Main ilevi
ierisinde ekrana bir yaz yazdryoruz.
//assembly1.cs

using System;
namespace assembly1
{

class csnedir1
{

static void Main(string[] args)


{
Console.WriteLine("Beni disardan yklediler.");
}
}
}

Bu program notepad 'da yazp derledikten sonra komut satrnda "csc assembly1.cs"
yazp assmbly1.exe dosyasn oluturun. Ayn klasr iine imdi aadaki assembly2.cs
dosyasn oluturun ve derleyerek assembly2.exe 'nin olumasn salayn.

//assembly2.cs

using System;
namespace assembly2
{

class csnedir2
{

static void Main(string[] args)


{
AppDomain apd2 = AppDomain.CreateDomain("Csnedir");
apd2.ExecuteAssembly("assembly1.exe");
}
}
}

Yukarda da bahsettiim gibi Application Domain sayesinde bir uygulama ierisine deiik
assembly'ler yklenebilir ve altrlabilir. Application Domian kavramn System isim
alannda bulunan AppDomain snf temsil eder. Yeni bir Application Domain'i oluturmak
iin AppDomain snfnn overload (ar yklenmi)edilmi CreateDomain statik ye
fonksiyonlar kullanlr. AppDomain snfnn ExecuteAssembly fonksiyonuyla dardan
yeni bir Assembly yklenir ve o satrdan itibaren yklenen assembly altrlr.
(Yukardaki rnekte iki Assembly'nin de ayn klasrde olmasna dikkat edin.)

Assembly hakknda bu geni giri bilgisini verdikten sonra Assembly'nin fiziksel


yapsndan bahsedelim biraz. Bir Assembly belgesinde Assembly metadata, tr(type)
metadata, kaynaklar ve IL(Intermadiate Language) kodu bulunur. Btn bu yaplar bir
Assembly dosyasnda bulunabilecei gibi Assembly metadata'lar sayesinde dardaki
kaynaklara referans da verilebilir. Assembly'lerin en nemli yaps Manifest dediimiz
parasdr. Manifest assembly metadata'lar bulunur. Peki nedir bu Assembly
metadata'lar? Bir Asembly ad, versiyonu gibi kimlik bilgileri, ilgili Assembly ile ilgili olan
dier dosyalar, baka Assembly'lere olan referanslar gibi bilgilerin tamamna Assembly
metadata denir. te bu bilgilerin oluturduu kmeye Manifest denilmektedir.
Assembly'lerin Manifest blmnde bulunan elemanlar temel olarak aadaki tabloda
verilmitir.

zellik Anlam
AssemblyCompany Assembly'nin firma bilgisi
AssemblyCopyright Copyright bilgisi
AssemblyCulture lgili Assembly'ye ait kltr
bilgisi(Almanya,ngiltere,Trkiye
vs..)
AssemblyDelaySign Gecikmeli imzann olup
olmayaca (True ya da False)
AssemblyDescription Assembly ile ilgili ksa aklama
AssemblyFileVersion Win32 sistemindeki dosya
versiyonu
AssemblyInformationalVersion CLR tarafndan kullanlmayan ve
okunabilirlii yksek olan
versiyon bilgisi
AssemblyKeyFile Assembly'nin kayt edilmesi iin
gereken anahtarn bulunduu
dosya
AssemblyKeyName Kayt iin gereken anahtar
szck
AssemblyProduct rn ad
AssemblyTitle Assembly'nin ad
AssemblyTrademark Trademark bilgisi
AssemblyVersion String eklindeki Version
numaras
Bu tablo MSDN kitaplndan alnmtr

Assembly'ler private ve shared olmak zere ikiye ayrlr. Bunlar detayl olarak aklamaya
balamadan nce Assembly'leri grntlemek iin kullanlan ILDASM.exe aracn
inceleyelim. ILDASM.exe MSIL kodu ieren assembly dosyalarn okur ve kullanl bir
arayz ile kullancya sunar. ILDASM.exe programn altrmak iin komut satrna
ILDASM.exe yazmamz yeterlidir. Alacak pencereden File->Open mensn kullanarak
grntlemek istediiniz Assembly dosyasn sein.(Aada grdnz ekran
grntleri Assembly2.exe'nin grntleridir.) Bir assembly'deki trler, snflar,
fonksiyonlar eitli sembollerle temsil edilmitir. Hangi sembollerin ne anlama geldiini
MSDN kitaplndan bulabilirsiniz.
imdi de alacak pencereden Main blmne tklayn, ve aadaki grnty elde edin.
Buradaki btn kodlar IL kodudur.

Dier blmlerde tklayarak IL kodlarn inceleyebilirsiniz.

Yukarda bahsettiimiz gibi Assembly'ler private ve shared olmak zere ikiye ayrlr.
Normal olarak gelitirilen Assembly'ler private Assembly olarak adlandrlr. Bu tr
assembly'ler uygulama ile ayn dizinde ya da alt dizinlerde bulunur. Versiyon ve isim
uyumazl sorunu bu tr assembly'lerde olmamaktadr. Shared assembly'ler ise daha
ok byk projelerde mesela bir projenin bir firmaya ait farkl ofislerinde gerekletirildii
durumlarda kullanlr. Bu durumda assembly'lerin uymas gereken baz kurallar vardr.
Bunlardan en nemlisi strong name dediimiz tekil bir isme sahip olmasdr. Bu sayede
shared assembly'ler tekil olduu iin bir sistemde global dzeyde ilem grrler. Yani
farkl farkl uygulamalardan ayn anda shared assembly'lere ulalabilir. imdi shared
assembly kavramn biraz aalm.

Shared Assembly

Assembly'ler varsaylan olarak private'tr. Bu yzden bu tr Assembly'ler sadece


bulunduklar dizin ierisindeki uygulamalar tarafndan grlr ve altrlrlar. Oysa ki
baz durumlarda btn programlar tarafndan o Assembly'ye birbirlerinden bamsz
olarak eriilmesini isteriz. Bunu salamak iin Global Assembly Cache denilen bir
sistemden faydalanacaz. .NET 'in ykl olduu btn sistemlerde Assembly Cache
mekanizmas vardr. Bu Assembly Cache'ye ykl olan Assembly'ler btn uygulamalar
tarafndan kullanlabilir. Bir assembly'yi GAC'a(Global Assembly Cache) yklemek iin 3
yntem kullanlr:

- Assembly'leri Windows Installer 2.0 ile yklemek


- Gacutil.exe isimli .NET ile gelen arac kullanmak
- /assembly 'ye Assembly dosyasn kopyalamak (C:\winnt\assembly\)

imdi adm adm bir shared assembly oluturmay grelim. Bunun iin ikinci yntemi
kullanacam. Balang olarak gacutil.exe program hakknda bilgi vermek istiyorum.
Gacutil(global assembly cache utility) program .NET ile birlikte gelir. Assembly cache'ye
yeni assembly yklemek varolan assembly'leri listelemek ve silmek iin kullanlr. Komut
satrndan aadaki parametrelerle bu program altrabiliriz.
* gacutil /l ---> GAC 'da bulunan btn assembly'leri listeler.
* gacutil /i assemblydll---> assemblydll adl shared assembly'yi GAC 'a ykler.
* gacutil /u assemblydll---> assemblydll adl shared assembly GAC 'dan siler.

lk adm olarak btn shared assembly'lere strong name dediimiz bir isim vermeliyiz.
GAC 'da bulunan btn assembly'lerin farkl bir ad vardr. COM teknolojisindeki globally
unique identifier(GUID) 'e benzetebiliriz bu isimleri. Peki bu strong name 'leri nasl
oluturacaz? Bu i iin yine .NET ile birlikte gelen sn.exe adl arac kullanacaz. sn
program aadaki gibi kullanlarak bir tekil isim oluturulur ve anahtar.snk adl
dosyaya yazlr.

sn -k anahtar.snk

anahtar.snk dosyasn oluturduktan sonra bu anahtar ismi projemizdeki AssemblyInfo.cs


dosyasndaki manifeset blmne ekliyoruz. Yani AssemblyKeyFile zelliini anahtar.snk
olarak deitiriyoruz. Sonu olarak AssemblyInfo.cs dosyas aadaki gibi olacaktr.

...............
[assembly AssemblyDelaySign(false)]
[assembly AssemblyKeyFile("../../anahtar.snk")]
[assembly AssemblyKeyName("")]
...............

Bu ilemleri yaptktan sonra projeyi "Build" edip oluan Assembly dosyasn gacutil.exe
yardmyla GAC 'a ekliyoruz. Bu ilemi komut satrndan aadaki gibi yapmalyz.

gacutil /i Assembly1.dll

Bu ilemi yaptktan sonra shared olan bu assembly'ye istediimiz .NET projesinden


ulaabiliriz. Tabiproject->Add reference mensnden shared assembly'ye referans
verdikten sonra yapabiliriz bunu. Shared assembly olduu iin yeni bir projede bu
assembly kullandmz da lokal bir kopyas oluturulmaz dolaysyla GAC zerinden
eriilir.

Kaynaklar

C# Primer (A Practical Approach) - Stanley Lipman


MSDN Ktphanesi
Kaynak Dosyalarnn Kullanm(Resource Files)

Bir uygulamann iindeki kaynaklar neler olabilir; resimler, mzikler ve yazlar(string). Bu


makalede bu tr kaynaklarn, harici olarak programmza nasl ekleneceini reneceiz.
Derlenmi bir program ierisinde bir yazy deitirmek ok zordur. Bu yzden sonradan
deime ihtimali bulunan kaynaklar ynetmek iin .NET platformu bizim iin byk
kolaylklar salamtr. Baz durumlarda da programmzn farkl dillerdeki versiyonlar
olabilir. Bu durumda her dil iin bir string kaynak dosyas(resource file) hazrlamamz
yetecektir.

Bu makalede, .NET ile birlikte gelen ve kaynak dosyalar oluturmada kullanlan


resgen.exe adl program, System.Resources isimalannda bulunan ResourceWriter
isimli snf, ve bu oluturulan kaynak dosyalar kullanmak iin yine System.Resources
isimalannda bulunan ResourceManager adl snflarnn kullanmn greceiz. Ve tabiki
bunlar anlatrken basit bir uygulama zerinden anlatacam.

Yukarda da bahsettiim gibi kaynak dosyalarda resim ve yazlar bulunabilir.lk admda


basit bir .txt dosyasna istediimiz yazlar alt alta yazalm. Resgen.exe yardmyla bu txt
dosyasndan .NET platformu iin zel bir kaynak dosyas oluturacaz. Yalnz dikkat
etmemiz gereken nokta u : bu ekilde hazrlanacak bir kaynak dosyasna resimleri
ekleyemiyoruz. Eer kaynaklarmz sadece yazlar ise bu yntemi kullanyoruz. Eer
kaynak olarak resim eklemek istiyorsak birazdan anlatacam ResourceWriter snfn
kullanarak basit bir program yazacaz. imdi aadaki terimler.txt dosyasn oluturun.

Pointer = Gsterici
Function = Fonksiyon
Array = Dizi
Template = ablon
yazilar.txt

imdi resgen.exe yardmyla yazilar.txt den yazilar.resources adl kaynak dosyay


oluturalm. resgen.exe yi altrmak iin Start-> Programs -> Microsft Visual Studio.NET
-> Visual Studio.NET Tools -> Visual Studio.NET Command Prompt yolunu
kullanabilirsiniz.
Konsol ekranna

resgen yazilar.txt

yazarak yazilar.resources dosyasnn olumasn salayan. yazilar.resources dosyasn bu


ekilde kullanabileceimiz gibi XML formatnda bir kaynak dosyas da oluturabiliriz.
Bunun iinde konsol ekranna aadaki komutu yazn.

resgen yazilar.resources yazilar.resx

Kaynak dosyalarnn nasl kullanldna gemeden nce resimlerin de eklenebilecei bir


kaynak dosyas hazrlayan bir program yazalm. Bu programda yukarda da dediim gibi
System.Resources isimalan altnda bulunan ResourceWriter snfn kullanacaz. Bunun
iin aadaki program yazyorum.

using System;
using System.Drawing;
using System.Resources;

class Class1
{
static void Main(string[] args)
{
ResourceWriter resw = new ResourceWriter("yazilar2.resources");
Image resim = Image.FromFile("logo.gif");

string anahtar,deger;

for(int i=0 ; i<=3 ; i++)


{
Console.Write("Kaynak iin anahtar kelime girin: ");
anahtar = Console.ReadLine();
Console.WriteLine();
Console.WriteLine("Girdiginiz anahtarin degerini girini: ");
deger = Console.ReadLine();

resw.AddResource(anahtar,deger);
}
resw.AddResource("Cslogo",resim);
resw.Close();
}
}

Biraz program aklamakta fayda var. Visual Studio.NET 'de yeni bir Console Uygulamas
an. Resimlerle i yapabilmek iin daha dorusu Image snfn kullanabilmek iin
System.Drawing isimalann eklememiz gerekir. Bunun iin Project->Add Reference
mensn kullanp System.Drawing.dll i iin projemize referans verelim. Kaynak dosyay
oluturmak iin ise System.Resources isimalannda bulunan ResourceWriter snfn
kullanyoruz. Programmzn banda yeni bir ResourceWriter nesnesi oluturuyoruz.
Varsaylan yapc ilevine ise oluturacamz kaynak dosyasnn ismini veriyoruz. Daha
sonra kaynak dosyasna ekleyeceimiz bir resim dosyasndan Image trnden bir nesne
tanmlyoruz. Yine ayn ekilde Image snfnn yapc ilevine resim dosyasnn adn
gnderiyoruz. Dosyann alan programla ayn klasr iinde olmasna dikkat edin. Aksi
halde FileNotFoundException hatas alrz. Daha sonra bir for dngs yardmyla 4 defa
kullancdan kaynak iin anahtar ve deer girilmesini istiyoruz. Kaynak dosyasna
kaynaklar eklemek iin ResourceWriter snfnn overload edilmi iki ye ilevini
kullanyoruz. Bu iki ye ilevinin prototipi aadaki gibidir.

public void AddResource(string, object); // bu fonksiyonu kaynaa Image nesnesini


eklemek iin kullanyoruz.
public void AddResource(string, string); // bu fonksiyonu ise iki string anahtar-deer
ikilisini kaynak dosyasna girmek iin kullanyoruz.

Son olarak Close ilevi ile hafzada bulunan bilgiler yazilar.resource dosyasna yazlr. Bu
ilevi kullanmadmzda bilgiler dosyaya kaydedilmeyecektir.

Bu ekilde oluturduumuz kaynak dosyasnn resgen.exe ile oluturduumuzdan tek


farkl kaynak dosyasna bir resim bilgisinin binary olarak yerletirilmesidir. Kaynak
dosyas oluturmann iki yntemini grdkten sonra imdi bu kaynak dosyalar bir
uygulamada nasl kullanacamz grelim. Bu amala yeni bir Windows Uygulamas
balatalm. Amacmz bir picturebox yardmyla kaynak dosyadaki binary resim bilgilerini
gstermek ve yazlar da bir label kontrolu zerinde gstermek. ncelikle Visual
Studio.NET 'de bulunan solution explorer penceresinden projemize hazrladmz kaynak
dosyasn eklememiz gerekir. Bunun iin solution explorer'daki projemize sa tklayp
Add->Add Existing Item 'dan yazilar2.resource adl kaynak dosyasn seelim. Bu
yntemle kaynak dosyas projemize Embed Resource olarak eklenecektir. Properties
penceresindeki Build Action zelliini kullanarak bu ayar deitirebiliriz. Kaynak dosyasn
ekledikten sonra aadaki gibi bir form penceresi tasarlayn. Form zerine bir picturebox
ve 4 tane label kontrolu ekleyin.

Formumuzu tasarladktan sonra Form1 'in load metodunu aadaki gibi dzenleyin.

private void Form1_Load(object sender, System.EventArgs e)


{
ResourceManager rsm = new
ResourceManager("winAppRes.yazilar2",Assembly.GetExecutingAssembly());
pictureBox1.Image = (Image)rsm.GetObject("Cslogo");

label1.Text = rsm.GetString("Pointer");
label2.Text = rsm.GetString("Function");
label3.Text = rsm.GetString("array");
label4.Text = rsm.GetString("Template");
}

Yukardaki metotda form1 yklendiinde ResourceManager yardmyla kaynak dosyadaki


bilgileri ,form zerindeki kontrollere yerletiriyoruz. Bu kodun alabilmesi iin
System.Reflection(Assembly snf iin) ve System.Resources(ResourceManager snf iin)
isimalanlarnn projeye using ile eklenmesi gerekir. lk olarak o an zerinde allan
assembly iin bir ResourceManager nesnesi oluturuyoruz. Yeni bir ResourceManager
nesnesi olutururken ResourceManager 'in yapc ilevine kaynak dosyann projedeki
greceli yolunu ve o an zerinde altmz Assembly nesnesini geiyoruz. Benim
oluturduum projenin ismi winAppRes olduu iin 1. parametre "winAppres.yazilar2"
olmaldr. (Dikkat edin 1. parametrede kaynak dosyasnn uzants olan .resource ekini
yazmadk ). 2. parametreye ise Assembly(System.Reflection) snfnn statik ye ilevi
olan GetExecutingAssembly ile dnen Assembly nesnesini geiyoruz. Kaynak
dosyasndaki verileri formun zerindeki kontrollere yerletirirken ResourceManager
snfnn iki ayr ye ilevini kullanyoruz. Bunlardan GetObject ilevi ile picturebox 'a
kaynaktaki resmi aktaryoruz. GetObject ilevinin parametresi kaynak dosyasndaki
resime ait verinin anahtar adn geiyoruz. Hatrlarsanz kaynak dosyay oluturuken
resim iin "Cslogo" anahtarn kullanmtk. GetObject ile geriye dnen nesne object
trnden olduu iin resim bilgisini picturebox 'a yerletirebilmek iin
(Image)rsm.GetObject("Cslogo") ifadesiyle tr dnm yapyoruz. GetString ilevi ile
de kaynak dosyasndaki yazlar alyoruz. Bu ilevden geriye dnen deer parametre
olarak verilen anahtara ait string deeri olduu iin label kontrollerinin text zelliine
atayabiliriz.

Program derledikten sonra aadaki ekran grntsn elde etmelisiniz.


Not : Eer kaynak dosyasn resgen.exe ile XML formatnda hazrlasaydk yukardaki
ilemlerin ayns yine geerli olacakt. Benim tavsiyem kaynak dosyalarn XML formatnda
hazrlamanz ynndedir. Hem Visual Studio.NET ortamnda kaynak dosyay daha rahat
dzenleyebilirsiniz hem de XML formatndaki dosyaya istediiniz ortamlardan rahatlkla
ulaabilirsiniz.
C#'da ArrayList Snfnn Kullanm

Programlarn ounda birden fazla ayn tipte deikenlere ihtiya duyarz. Bu sorunun
zm olarak birok dilde kullanlan veri yaplar ,dizilerdir. Bildiimiz klasik dizilerin
programlama tekniklerine getirdikleri kolaylklarn dnda birtakm kstlamalar da vardr.
Bu makalede klasik dizilerde sk sk karlatmz eitli sorunlar ve bu sorunlar nasl
zebileceimizi inceleyeceiz.

.NET platformunun snf kitaplklarnda bulunan ve programclarn ilerini ok


kolaylatran ArrayList snf ile klasik dizilerde karlatmz sorunlar nasl zeceimizi
greceiz.

Klasik dizilerle alrken karlaabileceimiz temel sorunlar u ekilde sralamak


mmkndr:

Dizilerin snrlar sabittir.


Dizilerin tm elemanlar ayn trden olmaldr.
Kullanmadmz dizi elemanlarndan dolay bellek alanlar gereksiz yere
igal edilmektedir.

rnein saysn bilemediimiz bir dizinin eleman saysn 500 olarak belirlediimizi
varsayalm. alma zamannda dizimizin sadece 10 elamann kullandmz durumda
dier 490 elemanlk bellek alan bo olarak kalr. te yandan dizimizde tutmak istediimiz
deikenlerin says 501 bir olduu bir durumda "IndexOutOfRangeException" istisnai
durumu ortaya kar ve program bu hatadan dolay sonlanr.

Mesela aadaki kodu derlemeye alalm:

using System;

class CshaprNedirCom
{
static void Main(string[] args)
{
int[] intDizi= new int[10];

try
{
intDizi[20]=5;
}

catch( Exception e)
{
Console.WriteLine(e.GetType());
}

Console.ReadLine();

Yukardaki programda intDizi 'mizi 10 eleman alacak ekilde tanmlamamza ramen bu


dizinin 20. elemanna ulap ona bireyler atamaya altk. Bu durumda programmz
alrken hata verdi. nk dizinin snrlar bellidir ve bu snrlarn dna kamyoruz.
Eleman says ihtiyacmza gre deien bir veri yaps olmas gerekten ho olmaz myd?
Evet C#'da byle bir dizi yapmz var. Bunun ismi ArrayList'tir.

ArrayList snrlar dinamik olarak deiebilen diziler olarak tanmlanr. Bu veri yaps .NET
snf ktphanesinin System.Collections isim alannda bulunur. sterseniz ArrayList'i
nasl kullanacamz bir rnekle inceleyelim:

using System;
using System.Collections; // ArrayList snfn kullanmak iin
// System.Collection isimalann eklemeliyiz..

class CshaprNedirCom
{
static void Main(string[] args)
{
ArrayList aList= new ArrayList(); // aList isimli ArrayList nesnesi
oluturalm.

// aList nesnemize sras ile 5, 8, 1, 17 ve 20 deerlerini


// Add metodu ile ekleyelim.
aList.Add(5);
aList.Add(8);
aList.Add(1);
aList.Add(17);
aList.Add(20);

// aList'in elemanlarn ekrana yazdryoruz:


Console.WriteLine("\t aList'in elemanlar:");
foreach(int eleman in aList)
Console.WriteLine(eleman);

// aList dizimizden 8 ve 20 deerlerini kartalm:


aList.Remove(8);
aList.Remove(20);

// aList dizimize 66 ve 4 deerlerini ekleyelim:


aList.Add(66);
aList.Add(4);

Console.WriteLine("\n\t aList dizisinden 8 ve 20\' kartp, 66 ve 4 ekledik:");


foreach(int eleman in aList)
Console.WriteLine(eleman);

Console.ReadLine();

}
}

Yukardaki rneimizde ncelikle ArrayList snfn kullanmak iin NET snf ktphanesinin
System.Collections isim alannn kullanacamz using System.Collections; ile
bildiriyoruz. Main fonksiyonumuzun iindeki ilk satrda, ArrayList aList= new ArrayList() ,
aList ismini verdiimiz ArrayList snfndan bir nesne oluturuyoruz. aList nesnemizi
oluturduunuz satrdan sonraki be satrda ArrayList snfnn Add() metodu ile aList
adl dizimize elemanlar ekliyoruz.

Daha sonra aList diziminizin elemanlarn ForEach dngs ile tek tek ekrana
yazdyoruz. ArrayList snfndaki bir nesnenin elemanlarn tek tek silmek iin Remove()
metodunu kullanrz. Remove() metodu ile istediimiz eleman diziden atabiliriz. Biz de 8
ve 20 elemanlarn diziden attk. Son olarak dizimize 66 ve 20 elemanlarn ekleyip dizinin
son halini ekrana yazdrdk.

C# dilinde normal diziler bildiiniz gibi sadece ayn tipten verileri tutar. Ama ArrayList
snfna ait dizilerimiz her trl nesneyi ayn dizi iinde tutabilir. Yani ayn dizide int,
float, ve string tiplerindeki deikenleri depolama ansmz var. Mesela aadaki kod
C# dili kurallar erevesinde geerli bir koddur:

ArrayList karmaList= new ArrayList(); // karmaList isimli ArrayList nesnesi


oluturalm.

karmaList.Add("Ahmet");
karmaList.Add(12);
karmaList.Add(true);
karmaList.Add(32.4f);
karmaList.Add('c');

Bu kod ile karmaList isimli ArrayList nesnemizin iinde string, int, bool, float ve char
tiplerinden oluan verileri ayn anda saklarz. ArrayList snfnn bize sunduu dier bir
gzel zellik ise tek bir komut ile ArrayList dizimizin ierisindeki elemanlar ters
evirebilmemizdir. Ters evirme ilemi iin Reverse() metodu kullanlr. sterseniz
Reverse() metodunu ve ArrayList'lerde nasl birden farkl trdeki elemanlar
kullanacamz bir rnekle inceleyelim:

using System;
using System.Collections; // ArrayList snfn kullanmak iin
// System.Collection isimalann eklemeliyiz..

class CshaprNedirCom
{
static void Main(string[] args)
{
// karmaList isimli ArrayList nesnesi oluturalm.
ArrayList karmaList= new ArrayList();

// karmaList'e deiik tipte elemanlar ekliyoruz.


karmaList.Add("Ali");
karmaList.Add(23);
karmaList.Add(false);
karmaList.Add(52.8d);
karmaList.Add('r');

// karmaList'in elemanlarn ekrana yazdryoruz:


Console.WriteLine("\t karmaList'in elemanlar:");
foreach(object eleman in karmaList)
Console.WriteLine(eleman);
karmaList.Reverse(); // karmaList'imizi ters eviriyoruz.

Console.WriteLine("\n ---> karmaList'in elemanlar ve trleri <---");


foreach(object eleman in karmaList)
Console.WriteLine("Tr: {0,15} deeri: {1,7}",eleman.GetType(), eleman);

Console.ReadLine();
}
}

Yukardaki programda karmaList isimli ArrayList snfndan bir nesne oluturduktan sonra
onu deiik trlerden veriler ile doldurduk. Bu dizinin elemanlarn sra ile foreach
dngs yardmyla ekrana yazdrdk. karmaList.Reverse() satrnda ise dizimizi ters
evirdik. Son iimizde ise karmaList dizisinin elemanlarn ekrana tek tek yazdrrken ayn
zamanda eleman.GetType( ) her elemann trn bulup yazdk.

Makalemizi ArrayList snfnn temel metodlarnn tablosunu vererek bitirmek isterim. Bu


tablodaki metodlarn iimize yaraca kanaatindeyim.

Add Bir nesneyi ArrayList'in sonuna ekler.


Sralanm bir ArrayList iinde bir nesneyi Binary
BinarySearch
search algoritmas kullanarak arar.
Clear ArrayList'in tm elemanlarn siler. Sfrlar.
Herhangi bir nesnenin ArrayList'in eleman olup
Contains
olmadn kontrol eder.
Dizinin sonuna deilde istediimiz bir yerine
Insert
indeksini belirterek eklememizi salar.
Remove Herhangi bir eleman diziden siler.
Reverse Diziyi ters evirir.
Sort ArrayList'i sralar.
Her Ynyle C#'da Yn (Stack) Snf

Bu yazmzda nemli veri yaplarndan olan yn (Stack) veri yaplarna giri yapacaz.
Yn veri yaplarnn alma mantklarn anladktan sonra .NET snf kitaplklarnda
yeralan Stack snfn C#'da nasl kullanacamz inceleyeceiz.

1. Yn veri Yapsnn alma ekli


Ynlar genelde ayn tipten verilerin tutulduu ve Son Giren lk kar (LIFO) alma
mantn kullanan veri yaplar olarak tanmlanr. Bir yna en son giren eleman ilk olarak
kar. Ynlar anlatrken en ok st ste konmu tabaklar veya herhangi bir nesne
grubunda ok kullanlana benzetirler. Mesela bir masann stnde sra ile st ste
konmu birden fazla tabaktan birisine ihtiyacmz olursa nce en sttekini alrz. Bu
aldmz tabaklarn en son konulandr.

Ynlarn alma prensibini daha iyi


kavramak iin yandaki canladrmay
inceleyelim. Canlandrmada ynn dnda
bulunan saylar ynn iine koymak iin
"Yn Doldur" dmesine
tkladmzda sras ile 17, 23, 4, 55 ve 8'i
yna sokuyor. Yn doluyken "Yn
Boalt" dmesine tklaynca ise
yndaki saylarn yerletirildikleri srann
tersi sra ile boaltr. Bu durumda en son
giren 8 says ilk nce, sonra 55, sonra 4
ve bu sra ile en son 17 says yndan
dar kar.

2. .NET Snf Ktphanesi Yn Snf (Stack)

.NET snf ktphanesinde yn veri yapsn kullanmak iin Stack snfn kullanrz.
Normalde C ve C++ dillerinde yn veri yapsn deiik veri trleri ve kendi
tanmladmz snflarla birlikte kullanmak zahmetli bir iti. (C'de snf kavram yoktur!)
Ama .NET ortamnda ynlarmz bize birok konuda esneklikler sunarak programlamay
daha zevkli ve verimli hale getiriyor.

.NET'in yn (Stack) snfn kullanmak iin program kodunun ba tarafna using


System.Collections; eklememiz gerekir. Buradan yn snf System.Collections isim
alannda bulunuyor sonucunu da kartrz.

C# veya herhangi bir dilde yazlan yn veri yaplarnda Push(), Pop(), Peek() veya
Top(), Clear() fonksiyonlar ve Count, zellii temel olarak bulunur. Temel
fonksiyonlarn yannda Clone(), CopyTo(), ToArray(), Contains() ve Equals()
metodlar .NET'in yn snfnda yeralr.

Yn snfnn Push() metodu yna yeni bir eleman ekler. Pop() metodu ile ynn en
stndeki eleman yndan siler ve silinen eleman geriye dndrr. Eer ynn
tepesindeki eleman renmek istersek Peek() medodu iimize yarar. Bu metod ynn
tepesindeki nesneyi dndrr ama bu nesneyi yndan silmez.

using System;
using System.Collections; // Stack snf bu isim alan iinde bulunur.

class YiginSinifi1
{
public static void Main(string[] args)
{
// Stack snfndan yigin nesnemizi tanmlyoruz.
Stack yigin = new Stack();

// Yigini deiik deerlerde dolduruyoruz..


yigin.Push(12);
yigin.Push(5);
yigin.Push(23);
yigin.Push(34);
yigin.Push(70);
yigin.Push(8);

Console.WriteLine("Ymzn ilk hali...");


ElemanlariYaz(yigin);

// Yigininin tepesinden bir say aldk


// ve bunu sayi deikenine atayp ekrana yazdralm
int sayi = (int) yigin.Pop();
Console.WriteLine("\n Yndan {0} saysn aldk", sayi);

// Yigininin tepesinden bir say daha aldk


// ve bunu sayi deikenine atayp ekrana yazdralm
sayi = (int)yigin.Pop();
Console.WriteLine("\n Yndan {0} saysn aldk", sayi);

// imdi ise Yigininin tepesindeki sayya bir bakalm


// bu sayy yndan karmyoruz.. Sadece ne olduuna bakyoruz..
sayi = (int) yigin.Peek();
Console.WriteLine("\n Ynn tepesindeki say u anda : {0}", sayi);

Console.ReadLine();

public static void ElemanlariYaz(Stack yigin)


{
object obj = new Object();
Stack yeniYigin = (Stack)yigin.Clone();

if(yigin.Count!=0)
{
while(yeniYigin.Count>0)
{
obj = yeniYigin.Pop();
Console.WriteLine("\t"+ obj.ToString());
}
}
else Console.WriteLine("Yn bo...!");
}
}

Yukardaki programda nce Stack snfndan yigin isimli bir nesne oluturuyoruz. Sonraki
alt satrda ynmza 12, 5, 23, 34, 70 ve 8 tamsaylarn Push() metodu ile ekliyoruz.
EkranaYaz() ismini verdiimiz static fonksiyonumuz (bu fonksiyon tam olarak optimize
edilmi bir fonksiyon deil! ) ile ynmzda bulunan elemanlar ekrana yazdryoruz. Daha
sonra yndan iki tane eleman Pop() metodu yardmyla alyor ve herbirini ekrana
yazdryoruz. Programn son ksmnda ise Peek() metodunu kullanarak ynn en
stndeki elemann ne olduunu reniyoruz.

Yn snflarnda bulunan dier iki temel fonksiyonlar olan Count zellii ve Clear()
metodlardr. Bunlardan Count, yn nesnesinde bulunan elemanlarn saysn geriye
dndren bir zelliktir. zellikler C# dilinde snflarda bulunan ye deikenlerin
deerlerini renmemize ve onlarn deerlerini deitirmemize yarayan bir tr
fonksiyonlardr. Count zellii eleman saysn int tipinde dndrr ve sadece okunabilen
(readonly) yapdadr. zellikler program iinde arlrken parantezleri kullanmayz. Eer
yigini boaltmak/temizlemek istersek Clean() metodu iimizi yarayacaktr. Clean()
metodu hibir parametre almaz ve hibir ey dndrmez. Herhangi bir yn nesnesinin
iinde bir elemann olup olmadn anlamak iin Contains() metodu kullanlr. Bu metod
aranacak nesneyi alr ve geriye true veya false deerlerini dndrr. sterseniz aadaki
programda Contains() ve Clear() metodlar ile Count zelliklerini nasl
kullanabileceimizi grelim:

using System;
using System.Collections; // Stack snf bu isim alan iinde bulunur.

class YiginSinifi1
{
public static void Main(string[] args)
{
// Stack snfndan yigin nesnemizi tanmlyoruz.
Stack yigin = new Stack();

// Ynmza yeni elemanlar ekliyoruz.


yigin.Push("Ahmet");
yigin.Push("Sefer");
yigin.Push("Cemal");
yigin.Push("Onur");
yigin.Push("Aziz");

// Ynda ka tane eleman bulunduunu bulup yazalm.


int elemanSayisi= yigin.Count;
Console.WriteLine("\nYnmzdaki eleman says: {0}", elemanSayisi);

// Yndaki elemanlar.
Console.WriteLine("\nYndaki elemanlar: ");
ElemanlariYaz(yigin);
//Contains() metodunun kullanm:
if(yigin.Contains("Sefer"))
Console.WriteLine("\nYnda Sefer eleman var...");
else
Console.WriteLine("\nYnda Sefer eleman yok...");

// Yn boaltalm.
yigin.Clear();

// Yn boalttktan sonra ka tane eleman bulunduunu bulup yazalm.


elemanSayisi= yigin.Count;
Console.WriteLine("\nYnmzdaki eleman says: {0}", elemanSayisi);

Console.ReadLine();
}

public static void ElemanlariYaz(Stack yigin)


{
object obj = new Object();
Stack yeniYigin = (Stack)yigin.Clone();

if(yigin.Count!=0)
{
while(yeniYigin.Count>0)
{
obj = yeniYigin.Pop();
Console.WriteLine("\t"+ obj.ToString());
}
}
else Console.WriteLine("Yn bo...!");
}
}

Hemen stteki programdan nceki programda ynmza int tipinden nesneler (c#'ta
primitive trler dahil herey nesnedir!) yerletirmitik. Bu rnekte ise string snfna ait
nesneleri ynmza ekledik ve onlar zerinde ilemler yaptk. Yani yn snfmz
herhangi bir nesneyi tutabilecek yetenekler sabit. ster temel veri trleri olsun (int, byte,
double veya bool) ister kendi tanmladmz veri trleri olsun yn snfmza ekleyip
kartabiliriz.

Yukardaki programda yigin olarak oluturduumuz ve yn snfndaki nesnemize be


tane veriyi ekliyoruz. Sonra ynda ka tane eleman olduunu bulmak iin Count
zelliinden faydalanyoruz. Yndaki elemanlar yazdrmak iin ElemanlariYaz() sabit
fonksiyonumuzu kullanyoruz. Contains() metodunu kullanmna rnek olmas amacyla
if deyimi iinde yigin.Contains("Sefer") sorgusunu yapyoruz. Eer Sefer eleman ynda
mevcutsa ekrana ynda olduunu, yoksa ynda olmadn yazdryoruz. Programn
geriye kalan ksmnda yn boaltmak iin Clear() metodunu kullanyoruz,yndaki
eleman saysn tekrar bulup bunu yazdryoruz. Eer tekrar ElemanlariYaz()
fonksiyonunu kullansaydk. "Yn Bo..!" uyarsn alrdk!

.NET snf ktphanesinde bulunan Yn (Stack) snfnn getirdii kolaylklar


yukardakilerden daha fazladr. Mesela herhangi bir yn nesnemizi baka bir ynn iine
kopyalayabiliriz. Bir yn baka bir yna kopyalamak iin Clone() metodunu
kullanabiliriz. Ayrca bir yn nesnesini herhangi bir dizinin iine kopyalamak iin
ToArray() metodu kullanlabilir. ki tane ynn birbirlerine eit olup olmadn
renmek iin Equals() metodu hemen yardmmza yetiir. Burada unu belirtmekte
yarar var: Equals() metodu sanal (virtual) bir fonksiyon olup c#'daki tm nesnelerin
tredii System.Object nesnesine aittir.

Bu makalede inceleyeceimiz son program aadadr. Bu programla Clone(), Equals()


ve ToArray() metodlarn programlarmz iinde ne ekilde kullanacamz renebiliriz.

using System;
using System.Collections; // Stack snf bu isim alan iinde bulunur.

class YiginSinifi1
{
public static void Main(string[] args)
{
// Stack snfndan yigin nesnemizi tanmlyoruz.
Stack yigin1 = new Stack();

// Ynmza yeni elemanlar ekliyoruz.


yigin1.Push("Ahmet");
yigin1.Push("Sefer");
yigin1.Push("Cemal");
yigin1.Push("Onur");
yigin1.Push("Aziz");

//kinci ynmz tanmlyor ve yigin1'in


// bir kopyasn yigin2'ye koyuyoruz..
Stack yigin2= (Stack)yigin1.Clone();

// yigin1'den bir eleman kartyoruz.


yigin1.Pop();

//yigin1 ve yigin2 nesnelerimizin en stteki


// elemanlarna bir bakalm:
Console.WriteLine(" Peek of Yn2: "+ yigin2.Peek());
Console.WriteLine(" Peek of Yn1: "+ yigin1.Peek());

//yigin1 ve yigin2 eit mi? Bir bakalm:


Console.WriteLine("\n yigin1 ve yigin2 eit? --> "+ yigin1.Equals(yigin2));

//yigin2'yi kopyalamak iin yeni bir dizi oluturalm:


Array arr = new Array[5];

// yeni oluturduumuz diziye yigin2'yi kopyalayalm:


arr = yigin2.ToArray();

// arr nesnesinin elemanlar:


Console.WriteLine( "\n\n arr nesnesinin elemanlar:\n"+
"\n\t"+arr.GetValue(0)+
"\n\t"+arr.GetValue(1)+
"\n\t"+arr.GetValue(2)+
"\n\t"+arr.GetValue(3)+
"\n\t"+arr.GetValue(4) );

Console.ReadLine();
}

public static void ElemanlariYaz(Stack yigin)


{
object obj = new Object();
Stack yeniYigin = (Stack)yigin.Clone();

if(yigin.Count!=0)
{
while(yeniYigin.Count>0)
{
obj = yeniYigin.Pop();
Console.WriteLine("\t"+ obj.ToString());
}
}
else Console.WriteLine("Yn bo...!");
}
}

Yazmzda bilgisayar programlama alannda en nemli veri yaplarndan biri olan ynlarn
(Stack) nasl altklarn ve .NET snf ktphanesinde bulunan Stack snfn ve
metodlarnn nasl iimize yarayacak ekilde kullanabileceimizi rendik. Umarm bu
yaznn size gerek manada yarar olur.
C#'ta Gsterici(Pointer) Kullanmak I

Gstericiler(Pointer) alt seviye programlama iin olmazsa olmaz yaplardr. Gstericiler


nesnelerin bellekte tutulduklar adresleri saklayan veri yaplardr. Bu makalede C#'ta
kullanm ok fazla gerekli olmayan gstericilerin nasl kulanldklarn inceleyeceiz. Bu
yaz gstericiler hakknda temel bilgilere sahip olduunuzu varsaymaktadr.

.NET' in altyapsnda gsterici kavram sklkla kullanlrken gstericilerin akca kullanm


programclar iin gizlenmitir. Bunun nedeni gsterici kullanmnn programlardaki
grlemeyen hatalara ska yol aabilmesidir. zellikle dili yeni renenler iin gsterici
hatalar iinden klmaz bir hale gelebilmektedir. C#'ta gstericiler yerine referans
deikenleri mevcuttur. Referanslar heap bellek blgesindeki nesnelerin balang
adresini tutar. Ancak bu adresin deerine kesinlikle ulaamayz. Oysa C ve C++ dillerinde
stack blgesindeki deikenlerin de adreslerine eribilmemiz mmkndr. stelik
deikenlerin adreslerini rnein 0x965474 eklinde elde etmemiz bile mmkndr. C ve
C++ programclarna pek yabanc gelmeyecektir bunlar, ancak programlama dnyasna
C# ile giren biri iin gstericilere neden ihtiya duyabileceimiz pek anlaml gelmeyebilir.
unu da syeleyelim ki ok istisnai durumlar dnda gstericilere ihtiyacmz olmayacak,
peki bu istisna durumlar nelerdir?

Geriye Uyumluluk(Backward Compatibility) : COM ve WinAPI'deki


fonksiyonlar gibi sk sk gsterici kullanan fonksiyonlar C# ile programlarmzdan
arabilmek iin parametre olarak gsterici alan fonksiyonlara gsterici
gndermemiz gerekebilir. Eer C# ta gsterici kullanmna izin verilmemi olsayd
tr uyumsuzluu yznden gsterici kullanan eski COM ve DLL'lere eriebilmemiz
mmkn olamazd.

Performans : C ve C++ dillerinin gnmze kadar ok popler olmasnn altnda


yatan nedenlerden biri de bellee direkt eriimi salad iinperformansn
inanlmaz derecede ykselmesidir. Bizim iin performansn ok nemli olduu
yerlerde gsterici kullanmamzdan daha doal birey olamaz.

Alt Seviye lemler : Donanm arayzleri ile direkt bir iliki ierisinde olacak
programlarda gstericilerin kullanm mecburi gibidir. Bazen de bellee
kullanclarn direkt eriebilmesi gereken programlar olabilir. Bu durumlarda da
gstericilerden faydalanabiliriz.

Btn bunlarn yannda gsterici kullanmann bir ok skntyda beraberinde getirecei


kesindir. ncelikle kullanmnn zor olmas ve kestirilmesi zor olan hatalara yol aabilmesi
bu skntlarn en banda gelenidir. Zaten C#'ta gsterici kullanacamz zaman kodu
unsafe(gvensiz) anahtar szc ile iaretlememiz gerekir. Aksi halde program
derlenemeyecektir. Normal bir metot iinde gsterici kullanm yasaklanmtr.

imdi de unsafe anahtar szcnn kullanmna rnekler verelim.

1-) unsafe olarak iaretlenen snflarn btn metotlarnda gsterici kullanabiliriz.

unsafe class Snf


{

2-) Normal bir metot iinde herhangi bir blou unsafe olarak aadaki gibi iaretleyip
dilediimiz gibi gsterici kullanabiliriz. unsafe bloklarnn dnda ise gsterici
kullanamayz.
int NormalMetot(int a, string str)
{
unsafe
{

}
}

3-) Normal bir metodu unsafe olarak iaretleyip sadece o metodun iinde de gsterici
kullanabiliriz.

unsafe int NormalMetot(int a, string str)


{

4-) Bir snfn ye deikenlerinden biri unsafe olarak iaretlenip gsterici olarak
bildirilebilir. Ancak bir metot ierisinde yerel bir gsterici tanmlanamaz. Yerel bir gsterici
tanmlamak iin unsafe olarak iaretlenmi metod yada blok kullanlr.

class Snf
{
unsafe char *ptr;
}

Gsterici Tanmlama ve Gsterici Operatrleri

Gstericiler aadaki gibi tanmlanabilir.

char* ptr1, ptr2;


int* ptr3;

ptr1 ve ptr2 char trden bir gsterici iken ptr3 int trden bir gstericdir. Bir gstericide
iki bileen vardr. Bu bileenlerden birincisi adres bileenidir. Adres bileeni nesnenin
bellekte bulunduu balang adresidir. kinci bileen ise tr bileenidir. Bu bileen ise
ilgili adresteki nesneye ulamak istediimizde bellekten ne kadarlk bilgili okunacan
salar. rnein int trden bir adresteki bilgiyi okumak istediimizde 4 byte'lk bir bilgi
okunacaktr, ayn ekilde char trden bir gsterici ise 2 byte'lk bir bilgi okunacaktr.

& operatr

Adres operatr olarak bilinen bu operatr deikenlerin veya nesnelerin bellekte


bulunduklar adresleri elde etmek iin kullanlr. Bu operatr hangi tr deikenle
kullunlrsa o trden bir gsterici retilir.

* operatr

erik operatr olan *, bir adresteki bilgileri elde etmek iin kullanlr. Aadaki
programda bu iki operatrn kullanmna bir rnek verilmitir.

using System;

class Class1
{
unsafe static void Main()
{
int* ptr1;
char* ptr2;

int a = 50;
ptr1 = &a;
int Adres = (int)ptr1;
Console.WriteLine("{0:X}",Adres);

char ch = 'A';
ptr2 = &ch;
*ptr2 = 'B';
Console.WriteLine(ch);
}
}

Bu program derleyebilmek iin komut satr derleyicisene programn iinde unsafe


blounun olduunu belirtmemiz gerekir. Bunun iin komut satrna

csc /unsafe KaynakKod.cs

yada

csc -unsafe KaynakKod.cs

yazarak program derleyebilirsiniz. Eer Visual Studio.NET kullanyorsanz projeye sa


tklayp proje zelliklerine gelip Build ksmndan "Allow unsafe code blocks" ksmn true
olacak ekilde deitirin.

Program altrdnzda ekrana a deikeninin adresi ve B karekteri yazlacaktr. Adres


bilgisini ekrana yazdrmadan nce gstericide tutulan adresi normal bir tre nasl
dntrdmze dikkat edin. Bunu yapmamzn sebebi Consol.WriteLine() metodunun
gsterici parametres alan versiyonunun olmamasdr.

C#'ta tr gvenliinin ne kadar nemli olduunu vurgulamak iin aadaki deyimleri


rnek verebiliriz.

int* ptr1;
*ptr1 = 50;

Bu deyimleri ieren bir program derlenemeyecektir. nk ptr1 gstericisinde hangi


adresin tutulduu belli deildir. Bu yzden adresi belli olmayan bellek blgesine bir deer
yerletirmek imkanszdr. C ve C++ dillerinde bu kullanm tamamen geerlidir. Ama gelin
bir de bunun sakncasna bir gz atalm. ptr1 gstericisi tanmlandnda ptr1 de rastgele
bir adres deeri bulunmaktadr. Bu adreste rastgele bir adres olduu iin o an bellekte
alan kendi programmzdaki bir deikenin adresi bile olabilir. Yada sistemde alan
baka bir prosesteki elemanlarn adresleri olabilir. Kaynan bilmediimiz bir adresteki
deeri * operatr ile deitirdiimizde hi tahmin edemeyeceimiz alma zaman
hatalar alabiliriz. in kts adresler rastgele olduu iin programmzn test aamasnda
bu hatalar olumayabilir. Adresler nasl rastgele ise hatalarn olumas da rastgeledir.
Programmz piyasada iken byle bir hatann farkna varlmas i maliyetlerini ne kadar
artrdn siz tahmin edin artk. Btn bu dezavantajlar gstericilerin asla gereksiz olduu
anlamna gelmemelidir. Sadece gstericileri kullanrken daha dikkatli davranmamz
gerektiinin gstergesidir.
Gstericiler arasnda tr dnmleri mmkndr. rnein int trden bir gsterici char
trden bir gstericiye aadaki gibi dntrlebilir.

char* ptr1
int* ptr2;

ptr1 = (char*)ptr2

Ayn ekilde bir gsterici de tamsay trlerine dntrlebilir. Adresler tam say
trnden birer say olduklar iin bunu yapabilmemiz son derece normal bir durumdur. Bir
nceki alan programda da Console.WriteLine() metodu ile ekrana yazmak istediimiz
nesnenin adresini tamsay trlerinden birini evirdiimizi hatrlayn. rnein aadaki
deyimleri ieren bir program derlenemeyecektir.

char* ptr1
char ch = 'A';
ptr1 = ch;

Console.WriteLine(ptr1)

Gstericilerle ilgili dier nemli yap ise void gstericilerdir. void olan gstericilerde tr
bilgisi saklanmamaktadr. void gstericilere herhangi bir trden gsterici atanabilir. void
gstericiler daha ok eskiden yazlm API fonksiyonlarnda void parametre alan
fonksiyolar programlarmz ierisinden armak iin kullanlr. void gstericilerin
kullanmna aada bir rnek verilmitir.

int* ptr1;
void * x;
x = ptr1;

sizeof operatr

sizeof operatr temel trlerin ve yaplarn bellekte ne kadar alan kapladklarn verir.
rnein sizeof(int) = 4, sizeof(char) = 2 ' dir. sizeof operatrn snflar iin
kullanamayz ancak tanmlayacamz yaplar iin kullanabiliriz.

Bu yaznn sonuna geldik. Bir sonraki yazmzda yap gstericileri tanmlamay snflar ile
gstericiler arasndaki ilikiyi, gsterici aritmetiini inceleyip rnek bir gsterici
uygulamas yapacaz.

Kaynaklar:

C# and The .NET Platform (Andrew Troelsen)


Professional C# 2nd Edition (Wrox)
MSDN Ktphanesi

C#-JAVA' nn Sonu mu?

JAVA'nn gn getike yaygnlaan kullanm alanlar, Microsoft firmasn gerekten g


duruma drd. 1995 ylnda JAVA ufukta grnd ve getiimiz 6 yl ierisinde kendisi
ile rekabet eden dier btn popler diller zerindeki stnln gsterdi. Balangta
Microsoft bu duruma direndi ancak daha sonra, JAVA mehur Visual Studio nun Visual J+
+ ad altnda bir paras oldu. JAVA' y karan Sun Microsystems, Microsft aleyhine lisans
anlamasn ihlal ettii gerekesiyle dava at ve Microsft buna karlk bir bedel demek
zorunda kald.

Sonunda ortalk yatt ve Microsft Visual J++ 'n yeni versiyonlarn karmaya devam
etti. Fakat Microsoft'un JAVA dilini Visual Studio paketinin iine koyma abas baarya
ulaamad ve en sonunda baarz oldu. Elbette ki bu baarszlk ta pazarlamann iyi
yaplamamasnn da etkisi olmutur. Sonu olarak Microsoft 1998 ylndan sonra Visual J+
+ iin yeni bir versiyon karmad, ve yakn bir gelecek iinde de bu tr planlarn askya
ald.

Sonunda Microsft anlad ki bir yerlerden dn alnan rnler uzun vadede ie


yaramayacak, bu yzden Microsoft, daha ok JAVA'ya benzeyen ancak JAVA da olmayan
bir takm yeni zellikleride ekleyerek C# (C Sharp) isimli yeni bir programlama dili
tasarlamaya balad. Bu makalenin amac C# hakkndaki phelerinizi gidermek ve JAVA
ile karlatrmaktr.

Peki, Microsoft 'un ilgilendii bu pakette nerdikleri nelerdi?

Bu pakette Microsoft'un nerdii iki ana yap vard:

.NET Mimarisi
Yeni bir dil - C#

.NET Mimarisi

.NET mimarisinin 3 ana bileeni vardr.

Herhangi bir dil tarafndan kullanalabilecek Web Servisi denilen yeni bir ortak servisler
kmesi. Bu servisler ara kod(intermediate kod) dediimiz mimariden bamsz bir yap
ierisinde altrlr. Bu ara kod daha sonra alma zamannda CLR denilen birim
tarafndan altrlr, ki bu bahsedilen CLR birimi programla ilgili kaynaklar yneten ve
programn almasn izleyen bir birimdir.

.NET'in birincil amac gelitiriciler asndan Web Servislerini kullanarak mimariden


bamsz uygulamalar gelitirmeyi kolaylatrmaktr. rnein bir servise hem PC hem PDA
hemde Mobil cihazlardan eriebilme gibi.

imdi bu yaplar tek tek inceleyelim.

Web Servisleri

Web Servisleri internet standartlar olan XML ve HTTP zerinden hizmet verebilen
yaplardr. Daha teknik bir dille sylemek gerekirse, web servisleri internet zerinden
eriilebilen bir ktphane, bir fonksiyon yada bir veritaban gibi dnlebilir. rnein;
bir web servisi herhangi bir irkete ait bir yllk ciroyu hesaplayp veren bir fonksiyon
ierebilir. Bu fonksiyon parametre olarak bir yl deeri almaktadr. Dolaysyla istemci
uygulamamz geri dn deeri 2000 ylna ait ciroyu Yllk_ciro(2000) gibi bir fonksiyonu
ararak elde edebilir.

Aslna bakarsanz bir firmada farkl platformlara ynelik hazrlanm uygulamalar arasnda
ki senkronizasyonu salamak amacyla Web Servisleri kullanlabilir. Buna ramen Web
Servisi kelimesindeki "Web" szc ile internet ortamnda web servislerinin kullanmn
n plana karmak iin kullanlmtr. Fakat normal ugulamarda da ou durumda Web
servsilerinden faydalanmamz mmkndr.
Web servislerinin en gzel yani servisin her yerden istenebilmesidir. Ksacas web servisi
uygulama alanlarna Windows, Linux, Unix, Mac-Os gibi platformlarn yansra komut
satrndan alan dier ortamlar bile girebilir. Yani Web servisleri sayesinde platform
bamsz uygulamalar gelitirebiliriz. nternet standartlarnn platform bamsz olmas ve
web servislerininde internet zerinden arlmas, web servislerinin herhangi bir iletim
sisteminin yada programlama dilinin tekelinde olmamasn salamtr.

Ara Kod(ntermediate Code)

Ara kod! Kulaa pek ho gelmiyormu? Bu bana bireyi hatrlatyor....hmmm..... JAVA?


Evet, elbette. Microsoft ak bir ekilde .NET ile JAVA' nn alma platformundan
esinlendiini kabul etti bylece. .NET ortamnda, programlar bir ara dil zerinden ikili
koda evrilir. letim sisteminden ve donanmdan bamsz olan bu dile MSIL(Microsft
Intermediate Language) denir. (evirenin notu: MSIL artk IL olarak anlmaktadr.) IL
kodu, JAVA platformundaki JVM de olduu gibi CLR tarafndan derlenip makina koduna
evrilir. IL kodunu makine koduna eviren derleyicilere ise JIT(Just In Time) derleyicileri
denilmektedir.

IL kodu eklinde derlenmi bir uygulamaya tanabilen altrlabilir(Portable


Executables) uygulama denir. CLS nin art btn dillerin ortak bir noktada toplanmasn
salayacak kurallar oluturmaktr. Ancak burada bir problemle karlald, oda btn
dillerin farkl semantik yapya sahip olmasdr, rnein her dilin farkl zellikleri olabilir,
baz diller prosedrel teknii destekler, bazlar nesne ynelimi tekniini destekler,
bazlarnda operatr ykleme varken bazlarnda yok, ve dierleri.

Bir dilin .NET uyumlu olmas iin CLS(Common Language Specification) standartlarna
uymas gerekir. Dolaysyla bir dilin .NET ortamna uyumlu olmas iin salamas gereken
iki koul vardr:

CLS ile uyumluluk


Kaynak kodu IL koduna evirecek derleyici

Peki yukarda bahsedilen komplek yap bize ne kazandracak? Diller aras alma?
Btn .NET uyumlu dillerde yazlm kodlar ara koda evrilecei iin herhangi bir dil de
yazlm bir nesneyi baka bir dilde yazdmz programda oluturabiliriz. rnein .NET
uyumlu C# dilinde yazlm bir snf ile, VB programcs bir nesne oluturabilir.

Peki JAVA'nn bu durumdaki rol ne? Yada Microsoft JAVA y devre dm brakt? Tam
olarak deil. JAVA nn .NET dilleri arasnda olmas dnld. JAVA kodunu IL koduna
evirecek derleyici Rational firmas(nl UML yazlm gelitirme aracn gelitiren firma)
tarafndan hazrlanmaktadr.(Not: bu yaznn yald tarihte JAVA derleyicisi yeni
yazlyordu). Peki bu eskisiyle ayn JAVA m olacak? Aslna bakarsanz hayr. JAVA kodlar
artk byte kod yerine IL koduna evrilecek.Yeni JAVA, J2EE'nin salad RMI, JMS, JDBC,
JSP vs gibi API' lerden faydalanamayacak.Yeni gelitirilen JAVA ile EJB mant yerini
.NET'in datk nensne modeline brakmtr.

CLR(Common Language Runtime)

Yukarda da bahsettiim gibi CLR, konsept olarak JVM(Java Virtual Machine)'ye ok


benzemektedir. JVM bellek ynetimi iin kaynaklarn dzenlenmesi, gereksiz bilgi(p
bilgi) toplama ve iletim sistemi ile uygulama arasndaki iletiimi salayan bir birimdir.

CLR, dizilerin snrlarnn almas, tahsis edilmeyen bellek alanna ulalmas, bellekteki
gerekli alanlarn zerine yazlmas gibi programlarn kmesine sebep olan geleneksel
hatalarn durumunu izler. Bu izleme hzllktan fedakarlk salamak demektir. Microsoft bu
yntemle performansn %10 orannda deceini kabul etmitir, fakat bu sistemler
devamllk ve gvenilirlik asndan daha n plandadr.

.NET Senaryoyu Sunuyor

Bu yln ortalarna doru .NET'in tam srm piyasada olacak(evirenin not: Yaznn
yazld tarihe gre dnmelisiniz) Microsoft mimarisinin kullanld eski uygulamalar
.NET uyumlu Windows 2000 sunucularnda hala geerliliini srdrecek. Eski mimarideki
uygulamalarn yeni gelecek bu mimariye tanabilmesi iin gerekli aralarn olacan
Microsft garanti etmitir, ancak bunun iyi bir zm olaca grlmyor. Halihazrdaki
tamak iin gelitirilen aralarn bu ilemi %100 yapamayaca aktr. Gelitiriciler bu
tama ileminden dolay epeyce bir zaman harcayacak.

.NET'in Gelecei

.NET'in gelii ile birlikte, elektronik uygulamalarn altyapsnn deimesi gerektiini inkar
edemeyiz. Her dil, .NET uyumlu olmas iin yapsal bir takm deiiklikler yapmaldr. Java
dilini bir dnn. Hangi Java daha tercih edilir sizce, JVM ile JAVA m yoksa .NET ile
JAVA m? Bu sorunun cevabn siz okurlarma brakyorum.

Yeni Bir Dilin Douu

Microsft .NET'in 27 farkl dil desteinin olduunu iddia ediyor.(evirenin not: u an bu


dillrein says daha fazla) Bir dili .NET uyumlu hale getirmek dilin varolan mimarisine yeni
yamalar eklemek demektir. Microsft bu durumu deerlendirerek temel olarak .NET
mimarisi hedef alnarak yeni bir dil tasarlad. Bu dilin ad C-Sharp yada C#. Bu dili daha
ok JAVA y andryor olmasna ramen var olan dier dillerden de gzel zellikler alnp
C# diline eklenmi gibi gzkyor.

C# nedir?

Geen iki yzyl ierisinde C ve C++ dilleri ticari ve i uygulamalar gelitirmek iin en ok
kullanlan diller olmutur. Bu iki dil programclara byk miktarda kontrol salamasna
ramen, retim asndan ok olanak salamyordu.

Bu dilleri Visual Basic gibi dillerle karlatrdmzda ayn uygulamy gelitirmenin C ve


C++ dillerinde daha fazla zaman ald bir gerektir. Yllardan beri istenilen tek ey
gllk ve retim hznn arasnda bir denge kuracak bir dilin olmasyd. Getiimiz
yllarda bu problem Sun Microsystems tarafndan anlald. Ve dier dillerin alma
mantndan tamamen farkl olan JAVA dilini gelitirdi. Bytecode konsepti, JVM ve ak
kaynak kod vs ve sonu olarak bedeva olmas bu farkllklardan bir kadr.

Fakat unutulan bir ey vard. JAVA ile yazlan kodlar baka dillerde kullanlamyordu.
Tekrar kullanlabilirlik denen bu zellii JAVA desteklemiyordu. Bylece, tekrar
kullanlabilirlii standartlatracak bir ortamn gereklilii ortaya kt. Bu ortam .NET ile
saland, zira .NET ile uyumlu dillerin salamas gereken CLS standartlar mevcuttur.
Fakat daha ncede dediim gibi .NET ile tam uyumlu alacak ve dier dillerin gzel
zelliklerini salayacak yeni bir dile ihtiya vard.

Hakknda konutuum bu dil C-Sharp diye okunan C#'tan baka birey deildir.

C#, modern, nesne ynelimli, tip gvenliine byk nem veren, temel hesaplama ve
haberleme gibi geni bir yelpazedeki uygulamalar gelitirmek iin .NET platformu iin
tasarlanm yeni bir dildir.
C#, C++ programclarnna retkenlii ve C++ dilinin gllnn gstergesi olan
kontrol mekanizmalarndan taviz vermeden hzl bir ekilde uygulama gelitirme olana
tanmaktadr.

C# ve JAVA'nn Karlatrlmas

yi bir dilin salamas gereken eyler nelerdir? Yada programclarn gnln kazanmak
iin bir dil yapsnda neyi barndrmaldr? Bu sorular on yllardan beri dil tasarmclarnn
zerinde durduu tartmaya ak sorulardr. Btn programclar tarafndan ittifakla kabul
edilmitir ki, bu sorularn cevabn en iyi ekilde veren dil JAVA'dr. C#, sentaks olarak
JAVA'ya ok benzemektedir, ancak derinlerine daldka Microsoftun bu dili tasarlamak iin
ok efor sarfettiini ve bu yeni eklenen bu zellikler iin Microsoft'a teekkr etmemiz
gerektiini anlarz.

imdi isterseniz JAVA nn zelliklerini tek tek ele alp bunlar C#'n ilgili zellikleriyle
karlatralm.

Intermediate Language(Ara dil)

JAVA kaynak kodu byte koduna evirirken C# MSIL(IL) koduna evirir. IL dili .NET
uyumlu btn dillerde yazlm olan programlarn ortak olarak derlendii dildir. Fakat IL
ve Byte Kod'un alma mantnda ince bir farkllk vardr. JAVA daki bytecode'lar
yorumlanrken IL kodu derlenerek makina koduna evrilir.

Interoperability (Diller aras uyumluluk)

JAVA'nn gc platform bamsz olmasndan kaynaklanmaktayken C# ayn zamanda


diller arasndaki uyumluluuda salar. Yani dil bamszl. Gzel!. imdi bunlar biraz
daha aalm: JAVA ile yazlm bir program JVM'nin olduu btn sistemlerde almas
szkonusu iken, C# ile yazlan bir kod dier .NET uyumlu diller tarafndan tekrar
kullanlabiliyor. rnein bir dilde yazlan snf, dier .NET uyumlu diller ile rahatlkla
kullanlabilir.

Bellek Ynetimi

JAVA otomatik bellek ynetimi salamaktadr.(daha teknik bir deyimle gereksiz bilgi
toplama mekanizmas denir.) Bu zellik programclar tarafndan takdirle karlanmtr.
Fakat eski C/C++ programclar JAVA diline gemeye alnca bu zellik onlar rahatsz
ediyordu. Bu tr programclarn problemlerini da gz ard etmeden, C# otomatik bellek
ynetiminin yannda programcnn bellei kendisininde ynetmesini salayan sistem
sunmutur. Ne demek bu? Basit. C#' ta hala pointer kullanabiliyoruz. (evirenin Notu:
Mthi!)

Harici Kodlara Referans

Harici kodlar C# ve JAVA'da benzer ekilde ele alnmtr. JAVA dilinde import anahtar
kelimesi kullanlrken C# ta using anahtar kelimesi kullanlmaktadr. JAVA
paket(packages) kullanrken, C# isim uzaylar(namespace) kullanr. Fakat bunlarn
anlamlar aa yukar ayndr.

Veri Tipleri

Bir dilin gc, dilin destekledii farkl veri trleri tarafndan belirlenir. Veri tipleri
programclara gll ve esneklii salayan varlklardr. C#, JAVA daki btn veri
tiplerini salamtr, bunun yansra JAVA da olmayan baz trler de eklenmitir, rnein
baz iaretsiz(unsigned) veri trleri JAVA da yoktur. Ayrca C# ta kayan noktal(floating
point) bir veri tr olan 12 byte'lk decimal tr de mevcuttur.

Alan Dzenleyicileri (Field Modifiers)

C# taki Alan dzenleyicileri temel olarak JAVA dilindeki gibidir. Deitirlemeyen yada
sabit bir deiken tanmlamak iin JAVA daki final dan farkl olarak read only ve const
belirleyicileri kullanlr. const olan alan dzenleyiciler, ilgili deerin IL kodunun bir paras
olduu ve sadece alma zamannda hesaplanaca anlamna gelir.

Kontrol Mekanizmas Oluturma

if-else, switch, while, do-while, for, break, contine deyimleri her iki dilde ayndr. Fakat
C# ta yeni bir kontrol daha vardr. C# taki bu yeni yap koleksiyonlar arasnda dolamak
iin gerekli olan for each yapsdr.

int slist(Arraylist alist)


.
foreach (int j in alist)
{
.
}

Yukardaki yapda j dng deikeni olarak adlandrlr. Bu dng deikenine her


iterasyonda alist dizisinin int trden olan eleman atanr.

Arayz ve Snf Bildirimi

JAVA daki extends ve implements anahtar szckleri C# te yerini iki nokta iaretine(:)
brakmtr.

stisnai Durumlar Ele Alma(Exception Handling)

C# ta catch bloundaki argman istee baldr. Eer catch ile argman belirtilmemise,
bu catch blou try blounda frlatlacak herhangi bir hatay yakalamak iin kullanlr.
Btn catch blouda C# ta kullanlmayabilir. Ayrca C# ta throws(evirenin not: throw ile
kartrmayn) anahtar szc yoktur.

Arayzler

C# ta bir snf istee bal olarak akca bir arayz uygulayabilir. Akca uygulanan
metotlar arayz ve snf arasndaki tr dnm sayesinde arlabilir.

Kaltm

JAVA ve C# ta sadece tekli tretme mevcuttur. Eer oklu tretme yapmak gerekiyorsa
arayzleri kullanmak tek yoldur.

ok Biimlilik(Polymorphism)

Sanal metotlar ok biimlilii gerekletirmek iin kullanlr. Bunun anlam taban snflarn,
tremi snflara ait ar yklenmi metotlar arabilmesidir. JAVA da btn metotlar
sanaldr, fakat C# ta tremi bir snftaki metodu taban snf ile arabilmek iin
metodun akca virtual anahtar kelimesi il iaretlenmesi gerekir. C# ta override anahtar
kelimesi bir metodun treyen snfta yeniden yazlacan bildirmek iin gereklidir. Sanal
olmayan bir metodu yeniden uygulamaya almak derleme zaman hatasna yol
aacaktr. Fakat eer tremi snftaki metot new anahar szc ile iaretlenirse
program hata vermeden derlenecektir.

Pekala, sonu nedir? C# te yeni bir ey bulabildinizmi, yoksa JAVA nn vey kardei gibi
mi duruyor? Microsoft bu urann karln ilerde alacakm? Yeni bir dilin var olan
uygulamalar zerinde, deiik platformlarda hatta programclar zerindeki etkisi ne
olacak? Bu can alc sorularn cevabn ancak zaman verebilir. Fakat bu arada beyninizde
bu sorular yava yava zn ve dnn. C# gerekten JAVA nn sonumu?

----------------------------

Bu makale http://www.csharphelp.com/archives/archive86.html adresindeki yazdan


Trkeye tercme edilmitir.

C# ile Zamanlayc Kullanmak (System.Timers)

Windows programlama ile uraanlar Timer kontroln sk sk kullanmlardr. Bu yazda


System.Timers isim alannda bulunan Timer snf ile bir programdaki rutin olarak
yaplmas gereken ileri belirli bir zaman aral iinde ne ekilde yapabileceimizi
reneceiz. Ancak alalgelmi ekilde bir grafik arayz olan program yerine
uygulamamz komut satrndan alacak ekilde gelitireceiz. Burdaki amacmz
zamanlayc dediimiz timer nesnelerinin alma prensibini yakndan grmektir.

yle bir konsol uygulamas yapmanz gerektiini dnn. Her 5 dakikada bir, belirli bir
kaynaktaki deiiklikler kontrol edilecek. Eer kaynakta bir deiiklik varsa kullancya
uyar verilecek. Bunu klasik yntemlerle ne ekilde yapabilirdiniz bir dnn? Yada ben
syliyeyim. Muhtemelen sonsuz bir dng ierisinde sistem saatini kontrol edip belirli bir
aralk gemi ise kayna kontrol eden ilevi aracaktnz. Eer zamansal bir ilem
yapyorsak ki bir olay bir zaman dilimi iinde srekli gerekletirmek zamana bal bir
olaydr; mutlaka sistem saatinden faydalanmamz gerekir. Sistem saatini makine
dzeyinde ileyen bir birim olarak dnebilirsiniz. Bilgisayar bilimlerinde bir ok
algoritma sistem saati zerine kurulmutur. Zatan eer zaman lebilecek bir birim
olmasayd u anki teknolojik imkanlara kavumamz mmkn olamazd. Sonu olarak
zaman ne kadar deerliyse zaman lebilmek te o derece nemlidir.

Bu yazda bir metodu bir zaman dilimi ierisinde tekrar tekrar armay reneceiz.
Bunun iin System.Timers isim alannda ki Timer isimli snf kullanacaz. Timer snfnda
bulunan Elapsed olay timer nesnesinin Interval zellii ile belirlenen aralkta
altrlacak metodun referansn tutmaktadr. Metodun referans Timer snfnn iindeki
delegate(temsilci) ve olay(event) veri yaplar ile salanmaktadr. (Delegate ve Event veri
yaplar ile ilgili ayrntl yazlar ileriki zamanlarda yaynlanacaktr.)

imdi isterseniz Timer snfnn yapc metotlarn inceleyelim.Timer snfnn iki tane yapc
metodu vardr. Bu metotlardan birincisi herhangi bir parametre almamaktadr. kincisi ise
double trden bir parametre almaktadr. Double trden olan bu parametre Timer
nesnesinin Elapsed olaynn ne kadar srede meydana geleceini belirtmektedir. Bu
metodun prototipi aadaki gibidir.

public Timer(double TickSays)

TickSayisi milisaniye cinsindendir. rnein her 1 saniyede almasn istediimiz bir


metot iin TickSayisi 1000 olan bir Timer kullanmamz gerekir. Saniyede on defa
almasn istediimiz bir metot iin ise TickSayisi 100 olan bir Timer nesnesi
kullanmalyz. Eer yapc metot herhangi bir parametre ile kullanlmaz ise varsaylan
TickSayisi olan 100 ile Timer nesnesi oluturulur.

alma zamannda timer nesnelerinin TickSayisini deitirmek yada Tick saysn


renmek iin Interval zellii kullanlabilir. Timer nesneleri varsaylan olarak aktif
deillerdir. Bu yzden Timer nesnelerinin ileyebilmesi iin bool trden olan Enabled
zelliinin true olarak ayarlanmas gerekir. Yada Timer snfnn Start() metodunu
kullanarak zamanlaycy balatmanz gerekmektedir.

Timer snf ile ilgili en nemli nokta Interval ile belirtilen sre dolduunda hangi metodu
aracan nerden anlayacadr. Bunun iin temsilciler ve olaylar kullanlr. Timer snf
tasarlanrken yapsnda tanmlanan event ve delegate veri trleri ile bu mmkn
olmaktadr. Timer snfnn Elapsed olay bu ie yaramaktadr. Elapsed olayna +=
operatr ile olay yneticisi yardmyla(event handler) yeni metotlar ekleyebiliriz. Timer
snfnn Elapsed olay iin ElapsedEventHandler isminde zel bir temsilci tanmlanmtr.
Bu temsilci nesnesine parametre olarak verilecek metodun parametreik yaps aadaki
gibi olmaldr.

SaniyelikIs(object o, ElapsedEventArgs a)
ElapsedEventArgs snf Timer nesnesi ile ilgili ayrntl bilgiler tutmaktadr. rnein
ElapsedEventArgs snfnn SignalTime zellii ile Elapsed olaynn meydana geldii saati
ve tarihi renebiliriz. rneimizi verdikten sonra ElapsedEventArgs snfn daha iyi
reneceksiniz.

Timer snfnn dier bir nemli eleman ise Stop() metodudur. Bu metodu ardmz
anda Timer nesnesinin Elapsed olay artk meydana gelmez. Stop() metodu yerine Timer
nesnesnin Enabled zelliini false yapmak ta dier bir zmdr.

Timer snf ile ilgili bu bilgileri verikten sonra bir rnek ile bilgilerimizi pekitirelim.
rneimiz de her saniye de saati ekrana yazadracak bir metot bildireceiz. Bu metot bir
Timer sayesinde her saniye arlacaktr. rnein kaynak kodu aadaki gibidir.

using System;
using System.Timers;

class Zamanlayici
{
static void Main()
{
Timer t = new Timer(1000);
t.Elapsed += new ElapsedEventHandler(SaniyelikIs);
t.Start();

while(true)
{

}
}

static void SaniyelikIs(object o, ElapsedEventArgs a)


{
Console.WriteLine(DateTime.Now);
}
}

Timer snfnn ilevini grebilmek iin programmzn en az be on saniye almasna


devam etmesi gerekir. Bunun iin while(true) eklinde sonsuz bir dng kurduk. Eer bu
sonsuz dng olmasayd programn icras bir saniyeden ksa bir srede bitecei iin
Elapsed olay meydana gelmeyecekti. Programn almas srasnda elde edilmi bir ekran
grnts aadaki gibidir.

Ekran ktsndan da grld zere her saniyede ekrana yeni saat deeri yazld iin
programmz bir saat gibi almaktadr.
SaniyelikIs() metodunu ElapsedEventArgs snfndan dolay aadaki gibi de
yazabilirdik. ElapsedEventArgs snfnn SignalTime zellii Elapsed olaynn meydana
geldii zaman vermektedir.

static void SaniyelikIs(object o, ElapsedEventArgs a)


{
Console.WriteLine(a.SignalTime);
}

Timer snfn kullanrken karlaabileceimiz en byk sorunlardan biri Elapsed olaynn


meydana gelme aralnn olaydan sonra altrlacak kodlarn icras iin geen zamandan
az olmasnda grlr. Bu sorun, ikinci Elapsed olay meydana geldiinde birinci Elapsed
olayna ilikin kodlar halen alyor durumda olmasndan kaynaklanr. rneimizdeki
Timer nesnesinin Tick saysn 1000 yerine 100 yaptmzda ayn saat deerinin 10 defa
ekrana yazdrlmas gerektiini anlarz. nk Elapsed olay her saniyede 10 defa
gerekleecektir. Her 10 Elapsed olay gerekletiine bir saniye geecei iin ekrana ayn
saat deeri 10 defa yazmaldr diye dnrz. Ama bunun gerekte byle olmadn
grrz. Tick saysn 100 yaptmzda programn ekran kts aadaki gibi olmaktadr.

Ekran ktsnda baz saat deerlerinin daha fazla sayda bazlarnn ise daha az sayda
yazldn gryorsunuz. Bu demek oluyorki programn bellek durumuna ve ilemcinin
younluuna gre Elapsed olaynn meydana gelme says deimektedir. Bunu
nlemenin yolu tick saysnn, Elapsed olayndan sonra alacak metot yada metotlarn
toplam icra sresinde daha fazla olacak ekilde ayarlamaktr.

Elapsed olayna birden fazla metotodu ilikilendirebiliriz. rnein Elapsed olay her
saniyede bir meydana geldiinde ekrana ayrca "Merhaba Elapsed olay!" yazdrmak iin
aadaki program yazabilirsiniz.

using System;
using System.Timers;

class Zamanlayici
{
static void Main()
{
Timer t = new Timer(1000);
t.Elapsed += new ElapsedEventHandler(SaniyelikIs);
t.Elapsed += new ElapsedEventHandler(Selam);
t.Start();
while(true)
{

}
}

static void SaniyelikIs(object o, ElapsedEventArgs a)


{
Console.WriteLine(DateTime.Now);
}

static void Selam(object o, ElapsedEventArgs a)


{
Console.WriteLine("Merhaba Elapsed olay!");
}
}

Bu programda Elapsed olay meydana geldiinde ilk nce SaniyelikIs() metodu ardndan
da Selam() metodu arlacaktr. Bunun sebebi olayla ilikilendirilen metotlarn olay
yneticisine eklenme srasdr. lk eklenen metot ilk arlr. Bu programn ekran kts ise
aadaki gibi olacaktr.

Bu yaznn sonuna geldik. Size Timer snfnn kullanmn ve dikkat etmeniz gereken baz
noktalar aktarmaya altm. Yaz ile ilgili dnceleriniz elektronik posta adresime
yazabilirsiniz.

C#'ta Gsterici(Pointer) Kullanmak II


C#'ta gstericilerin kullanmna ynelik ilk yazda gstericilere giri yapmtk, C#'ta
gstericilerin kullanmn 3 yazlk bir seri halinde anlatmay dndm. Bu yazda
gsterici aritmetiini ve fixed anahtar szcnn kullanmn reneceiz.

Gstericilerin adres bilesenlerine sabit tamsayi degerleri ekleyebiliriz, ayni sekilde


gstericilerin adres bileseninden sabit bir tamsayi degerini ikarabiliriz. Ancak
gstericilere uygulanan bu toplama ve ikarma islemleri biraz farklidir. Gstericilere sabit
degerlerin eklenmesi yada bir degerin gstericiden ikarilmasi gstericideki tr bileseni ile
yakindan ilgilidir. Bir gstericinin degerini bir artirmak gstericinin adres bilesenini,
gstericinin trnn ierdigi byte sayisi kadar artirmak demektir. Ayni kural ikarma
islemi iinde geerlidir. rnegin int trnden bir gsterici ile 1 sayisini toplamak
gstericinin adres bilesenini 4 artirmak anlamina gelir. nk int tr 4 byte
byklgndedir. Ayni sekilde int trden bir gstericiden 1 sayisini ikarmak gstericinin
adres bilesenini 4 eksiltmek anlamina gelir. Gstericilerle yapilan bu tr aritmetik
islemlerin tamamina gsterici aritmetigi denilmektedir.

Gsterici aritmetigini daha yakindan grmek iin asagidaki programi yazin ve sonucunu
inceleyin.

using System;

class Gosterici
{
unsafe static void Main()
{
int* ptr1 = (int*)500;
char* ptr2 = (char*)500;
double* ptr3 = (double*)500;
byte* ptr4 = (byte*)500;

ptr1 += 2;
ptr2 += 5;
ptr3 += 2;
ptr4 += 6;

Console.WriteLine((uint)ptr1);
Console.WriteLine((uint)ptr2);
Console.WriteLine((uint)ptr3);
Console.WriteLine((uint)ptr4);
}
}

Programi /unsafe argmani ile derleyip alistirdigimizda asagidaki ekran grntsnz


elde ederiz. Programda Main() metodunun unsafe olarak isaretlendigine dikkat edin.

508
510
516
506

Programin iktisindan da grldg zere int trden bir gstericiye 2 sayisini eklemek
gstericinin adres bilesenini 2*4=8 kadar artirmistir. Ayni sekilde char trden bir
gstericiye 5 degerini eklemek gstericinin adres bilesenini 5*2 =10 kadar artirmistir.
Toplama yerine ikarma islemi yapilmis olsaydi bu sefer ayni oranda adres bileseni
eksiltimis olacakti.
Gstericiler zerinde sadece tamsayilarla aritmetik islemler yapilabilir. Gstericiler ile
asagidaki aritmetik operatrleri kullanabiliriz.

+ , - , -- , ++ , -=, +=

void gstericilerde herhangi bir tr bilgisi olmadigi iin bu tr gstericiler zerinde


aritmetik islemler yapilamaz. nk void trnden bir gstericiye rnegin 1 eklemek
istedigimizde gstericinin adres bileseninin ka byte telenecegi belli degildir.

Gstericiler zerinde yapilabilecek diger nemli islemde iki gstericinin birbirinden


ikarilmasidir. Gsterici trleri ayni olmak sartiyla iki gstericiyi birbirinden ikarabiliriz.
Ancak iki gstericinin ikarilmasi sonucunda retilen deger bir gsterici tr degildir. Iki
gsterici arasindaki fark, adres bilesenlerinin sayisal farkinin gsterici trlerinin
byklgnden ka adet byte miktari edecegidir. Diger bir deyisle adres bilesenlerinin
sayisal farki alinip gsterici trnn byte miktarina gre bir deger belirlenir. Iki
gstericinin farki long trden bir deger retir. Iki gstericinin farkina rnek verecek
olursak, int trden 5008 adres ile int trden 5000 adresinin farki (5008-5000) %
sizeof(int) tir. Yani sonu long trden 2 dir. Asagidaki programi yazarak sonucu
grebilirsiniz.

using System;

class Gosterici
{
unsafe static void Main()
{
int* ptr1 = (int*)500;
int* ptr2 = (int*)508;

long fark=ptr2 - ptr1;

Console.WriteLine(fark);
}
}

Diger bir ilgin nokta iki gstericinin adres bilesenlerinin farki gsterici trlerinin
byklgnn tam kati olmadiginda grlr. rnegin ptr2 gstericisini tanimlanmasini

int * ptr2 = (int*)507;

seklinde degistirdiginizde bu sefer ekrana 1 yazdigini grrsnz. Burdan ikarmamiz


gereken sonu iki gstericinin farki adres bilesenlerinin sayisal farkinin olmamasidir.

Dikkat: Iki gstericinin farki long trden bir deger retir. Bu yzden iki gstericinin farki
aikca bir tr dnsm yapilmadika long trnden kk trden olan degiskenlere
atanamaz.

Gstericiler ile kullanilabilecek diger operatrler ise ==, < ve > gibi karsilastirma
operatrleridir. Bu operatrler iki gstericinin adres bilesenini karsilastirip ture yada false
degeri retirler. Karsilastirma operatrleri gstericiler iin ok istisnai durumlar disinda
anlamli degildir. Bu istisna durumlardan biri gstericileri kullanarak dizi islemleri
yaptigimizda grlr.

fixed Anahtar Szcg


Bildiginiz gibi C#' ta tanimladigimiz referans degiskenleri heap bellek blgesindeki
adresler temsil ederler. Ancak biz adresler yerine nesnenin ismini kullaniriz. Gereksiz bilgi
toplayicis(garbage collector) bellek optimizasyonui aisindan heap bellek blgesindeki
nesnelerin yerlerini her an degistirebilir. Bu yer degisiminden bizim haberimiz olmaz,
nk nesnenin yeri degistigi anda bu nesneye referans olan stack bellek blgesindeki
degiskenin adres bileseni de degistirilir. Dolayisiyla biz ayni referans ile farkli bellek
blgesini istegimiz disinda kullanmis oluruz. Ancak bazi durumlarda gereksiz nesne
toplayicisina bir nesnenin adresini degistirmemesi iin ikna etmek durumunda kaliriz. Bu,
zellikle sinif nesnelerinin ye elemanlarindan birinin adresi ile islem yapmamiz gerektigi
durumlarda karsimiza ikar. Bir degiskenin adresinin belirlenen bir faaliyet alani boyuncu
degismeden kalmasi iin bunu gereksiz nesne toplayicisina bildirmemiz gerekir. Bunun
iin fixed anahtar szcg kullanilir.
Zaten fixed anahtar szcgn kullanmadan referans trnden nesnelerin ye
elemanlarinin adreslerini elde etmemiz mmkn degildir. ye elemanlarinin adreslerini
elde edemedigimiz bu tr nesnelere managed type(ynetilen tip) denilmektedir. Buna
gre siniflar managed type kapsamina girmektedir.

Asagidaki programda ManagedType isimli sinifin int trden olan x elemaninin adresi bir
gstericiye atanmak isteniyor.

using System;

class ManagedType
{
public int x;
public ManagedType(int x)
{
this.x = x;
}
}

class Gosterici
{
unsafe static void Main()
{
ManagedType mt = new ManagedType(5);

int* ptr1 = &(mt.x);


}
}

ManagedType sinifinin x elemani deger tipi olmasina ragmen mt nesnesi zerinden x


degiskeninin adresi elde edilememektedir. nk x degiskeninin adresi gereksiz nesne
toplayicisi tarafindan her an degistirilebilir. Eger yukaridaki kod geerli olmus olsaydi x
degiskeninin adresi degistigi anda ptr1 gstericisi nereye ait oldugu bilinmeyen bir adres
bilgisi tasiyor olacakti. x degiskeninin bir blok ierisinde sabit adreste olmasini istiyorsak
asagidaki gibi fixed anahtar szcgn kullanmaliyiz.

using System;

class ManagedType
{
public int x;
public ManagedType(int x)
{
this.x = x;
}
}

class Gosterici
{
unsafe static void Main()
{
ManagedType mt = new ManagedType(5);

fixed(int* ptr1 = &(mt.x))


{
//x'in adresi bu blokta asla degismez.
}
}
}

Yukaridaki fixed ile isaretlenmis blokta x'in adresinin degismeyecegi garanti altina
alinmistir. Birden fazla degiskeni fixed olarak isaretlemek iin asagidaki gibi bir kullanim
geerli kilinmistir.

ManagedType mt1 = new ManagedType(5);


ManagedType mt2 = new ManagedType(5);

fixed(int* ptr1 = &(mt1.x))


fixed(int* ptr2 = &(mt2.x))
{
//x'in adresi bu blokta asla degismez.
}

te yandan bir fixed bildirimi iinde adreslerinin degismesini istemedigimiz elemanlari


virgl ile ayirarak asagidaki gibi de bildirebiliriz.

ManagedType mt1 = new ManagedType(5);


ManagedType mt2 = new ManagedType(5);

fixed(int* ptr1 = &(mt2.x), ptr2 = &(mt2.x))


{
//x'in adresi bu blokta asla degismez.
}

Gstericilerle ilgili son yazda, yap gstericileri, gstericiler ile dizi ilemleri ve stackalloc
ile dinamik alan tahsisat yapma gibi konular inceleyeceiz.

C# ile Nesne Ynelimli Programlama I


Bu makalede nesne ynelimli programlama tekniine kadar kullanlan yazlm
gelitirmedeki yaklamlara gz atacaz. Daha sonra nesne ynelimli programlamann
temel kavramlar ve neden byle bir tekniin kullanld zerinde duracaz.

Yazlm Gelitirme ve Bu Alandaki Yaklamlar

Kimilerine gre getiimiz yzyln en nemli buluu olarak kabul edilen bilgisayar
teknolojisi, ba dndrc bir hzla gelimektedir. Biliim sektrndeki deiimler bazen
varolan teknolojilere yenilerinin eklenmesi eklinde olabilir. Dier taraftan bir ksm
yenilikler vardr ki bu alanda byk deiimlere ve evrimlere yolaar. Mesela; kiisel
bilgisayarlarn kullanlmaya balanmas veya internetin belli bal akademik kurumlarn ve
askeri organizasyonlarn tekelinden alnp tm insanln hizmetine sunulmas gibi.

Hepimizin bildii gibi bir bilgisayar sistemi iki ana paradan oluur. Bunlar
donanm(hardware) ve yazlm(software). Donanmn yazlm ile uyumlu alimas
sonucunda sistemlerimiz sorunsuz bir ekilde bizlere hizmet verirler. Ayrca donanmn
amacmimza uygun hizmet vermesi uygun yazlmn gelitirilip kullanlmasna bagldr.

Yazlm sektrnde program gelitirme konusunda gnmze kadar bir ok yaklaim


denenmitir. Bunlarn ilki programn batan aaya sras ile yazlp altrlmasdr. Bu
yaklamla BASIC dili kullanlarak bir ok program yazldn biliyoruz. Burda sorun
programn ak srasnda deiik ksmlara goto deyimi ile atlanmasdr. Program kodu
bir ka bin satr olunca, kodu okumak ve ynetmek gerekten ok byk sorun oluyordu.

kinci yaklam ise prosedrel yaklamdr. Programlarda bir ok iin tekrar tekrar farkl
deerleri kullanlarak yapld farkedildi. Mesela herhangi bir programda iki tarih arasnda
ne kadar gn olduunu bulmak birok kez gerek olabilir. Bu durumda balang ve biti
tarihlerini alp aradaki gn saysn veren bir fonksiyon yazlabilir ve bu fonksiyon ihtiya
duyulduu yerde uygun parametrelerle arlp istenen sonu elde edilebilir. Prosedrel
yaklam Pascal ve C dillerinde uzun yllar baari ile kullanlmtr.

Ama her geen gn programlarn daha karmak bir hal almas, program kodunun
kurumsal uygulama projelerinde onbinlerce satr bulmas ve yazlm gelitirme
maliyetinin ok arttin gren bilim adamlar, programclara yeni bir yaklamn
kullanlabilineceini rettiler. Bu yakamn ismi Nesne Ynelimli Programlama(Object
Oriented Programlama)dr.

Nesne ynelimli programlama teknii, diger yaklamlara nazaran, yazlm gelitiren


insanlara byk avantajlar salamaktadr. Birincisi karmak yazlm projelerinin
retilmesini ve bakmn kolaylatryor olmasdr. Dieri ise program kodunun tekrar
kullanlabilmesine (code-reusability) olanak salamasdr. Bu noktada program kodunun
tekrar kullanlabilmesi profesyonel yazlm irketlerinin maliyetlerini azaltmtr. Dolaysi
ile programlarn lisans cretleri dm ve sektrn srekli olarak canl kalmasna ve
rekabet iinde gelimesine yardmc olmutur.

Nesne Ynelimli Programlama Nedir?

Nesne ynelimli programlamada esas olan, gerek hayatta varolan olgularn


programlamaya aktarlmasndaki yeni yaklamdr. Prosedrel programlamada verilerimiz
ve fonksiyonlarmz vard. Yani veri ve bu veriyi ileyen metodlar etrafinda dnyordu
herey.

Aslnda nesne ynelimli programlamada da iki nemli birim veri ve veriyi ileyip mantkl
sonular reten metodlar bulunur. Ama burdaki fark gerek hayattaki olgularn da daha
iyi gzlenip programlama dnyasna aktarlmasndadr.
Mesela elimizde bir tmz olsun. tnn markas, modeli, rengi, alst elektrik voltaj,
ne tr kumalar tleyebildii bu tye ait zelliklerdir (veri). Ayn zamanda tmz
stabiliriz, tleme iinde kullanabiliriz ve soumaya brakabiliriz. Bunlar ise tnn
fonksiyonalardr(metod). Eer t ile ilgili bir program yapm olsak ve nesne ynelimli
programlama tekniini kullansak hemen bir t snf(class) olutururduk. Bu snfta tye
ait bilgiler (veriler) ve t ile yapabileceimiz iler(metod) bulunurdu. O zaman nesne
ynelimli programlama da bir snfta, snfa ait veriler ve bu verileri ileyip bir taki faydal
sonular reten fonksiyonlar/metodlar bulunur.

Dahas, biz birtane t sinifi tasarlarsak bu snftan istediimiz sayda deiik


tler(object veya instance) yapabiliriz. Aagidaki ekilde t snf ve bu snftan
oluturduumuz neslerin grsel olarak anlatm bulunmaktadr.

Snf Nedir ve Nasl Tasarlanr?

Az nce de deindiimiz gibi, snf bir yazlm kurgusudur ve gerek hayattaki herhangi
bir olguyu modelleyen ve bu olguya ait zellikleri(veri) ve davranlar(metdodlar)
tarifleyen yapdr.

sterseniz t ile ilgili bir rnek zerinde alalm. Aadaki rnek C# program kodunu
ltfen dikkatlice inceleyeniz.

using System;

class t_rnegi
{
static void Main(string[] args)
{
t t1= new t("Beyaz", "AyBakr");

Console.WriteLine(t1.Isn(70));
Console.ReadLine();
}

class t
{
public int scaklk;
public string renk;
public string marka;

public t(string renk, string marka)


{

scaklk=15;
this.renk=renk;
this.marka= marka;

Console.WriteLine(scaklk+ "derece scaklnda,\n "


+ renk + " renginde ve\n "
+ marka +" markasyla bir t nesnesi oluturuldu\n\n");

public string Isn(int derece)


{
scaklk+=derece;
return "u an scaklgm: " + scaklk+ " derece";
}
}

Yukardaki rnek programmzda nce altta bulunan t snfmz inceleyelim. Bu snfn


scaklk, renk ve marka olmak zere adet verisi vardr. Ayrca t snfmzn t(string
renk, string marka) eklinde tanmlanm yaplandrcs (constructor) vardr.
Yaplandrclar bir snftan oluturulan nesnelerin ilk deerlerini atama ve baslang
ilemlerini yapmak iin kullanlrlar. t snfnmzn yaplandrcs, oluturulan her t
nesnesinin scakln varsaylan deer olarak 15 dereceye ayarlyor. Ayrca paratmetre
olarak alnan renk ve marka deerlerini de atayp, tye ait zellikleri ekrana yazdryor.

t snfna ait olan dier metod ise Isn(int derece) olarak tanmladmz metoddur. Bu
metod tnn scakln derece parametresinde verilen deer kadar artrp sonucu string
tipinde geri dnderiyor.

t_rnegi snfna geri dnersek, burda sadece Main() metodunun bulunduunu


grrz. Main() metodu, C# dilinde her programda bulunmas gereken zorundu bir
metoddur. nk programn alitrlmas buradan balar. Ayrca her C# programnda
sadece bir tane Main() metodu bulunur. rneimizde Main() metodundaki en nemli
satir:
t t1= new t("Beyaz", "AyBakr");

satrdr. Bu satrda t snfna ait t1 nesnemizi oluturuyoruz. Yukardaki satrdan da


grebileceimiz gibi herhangi bir snfa ait yeni nesneyi olutururken genel olarak u yap
kullanlr:

SnfAd nesneAd = new SnfAd(parametre1, parametre2, parameter N)

Referans Tipleri ve Nesneler

Nesnelerin en nemli zellii referans tipinde olmalardr. Referans tiplerinde bir nesnenin
deeri saklanmaz. Sadece nesnenin hafzadaki (heap memory) yeri saklanr. Bir nesnenin
hafizadaki yerini new operatr geri dnderir. Aadaki program kodu ile referans
tiplerine ait bir ka temel zellii inceleyelim:

using System;

class t_rnegi
{

static void Main(string[] args)


{
t t1= new t("Beyaz", "AyBakr");

Console.WriteLine("t1'nin ilk zellikleri: " +


t1.zellikler());
Console.WriteLine("t1'i 50 derece stalm: "+
t1.Isin(50)+ "\n\n");

// t2 nesnemizi renksiz ve markasz olarak olusturalm:


t t2 = new t("","");

//t2 nesnemizin zelliklerine bir gz atalm:


Console.WriteLine("t2'nin ilk zellikleri: " +
t2.zellikler());

t2= t1; // t2 nesnemizi t1 nesnemize atyoruz.


Console.WriteLine("t2'nin zellikleri: " +
t2.zellikler());

Console.ReadLine();
}

class t
{
public int scaklk;
public string renk;
public string marka;

public t(string renk, string marka)


{
scaklk=15;
this.renk=renk;
this.marka= marka;
}

public string Isn(int derece)


{
scaklk+=derece;
return "u an scaklm: " + scaklk+ " derece";
}

public string zellikler()


{
string sonuc= " Scaklk: " + scaklk+
"\n Renk: " + renk+
"\n Marka: " + marka+ "\n\n";
return sonuc;
}
}

sterseniz kodumuzu incelemeye yine t snfndan balayalm. Bir nceki rnee gre
snfmzda degiikler yaptk. t snfnn zelliklerini gsteren ayr bir metod yazdk. Bu
metod zellikler() isimli olsun. Doal olarak t snfnn yaplandrcsnda, snf
oluturulduktan hemen sonra nesnenin zelliklerini gsteren ksm kaldrld.

imdi ise t_rnegi snfndaki Main() metodu zerinde younlaalm. Yine, birinci
rnekte olduu gibi, t1 nesnemizi

t t1= new t("Beyaz", "AyBakr");

ile oluturuyoruz. Sonra t1 nesnesinin zelliklerini ekrana yazdryoruz. Bir sonraki


satrda ise t1 nesnemizi 50 derece stp sonucu ekrana yazyoruz.

Artk ikinci bir t nesnesinin oluturmanin zaman geldiini dnp

t t2 = new t("","");

satrnda t2 nesnemizi oluturuyoruz. Burada dikkatinizi ektii gibi t2 nesnesinin


renk ve marka zelliklerini bo olarak (null) oluturuyoruz. t2 nesnesini oluturunca
zelliklerine gzatmak iin

Console.WriteLine("t2'nin ilk zellikleri: " +


t2.zellikler());

satrlarn yazyoruz. Bir sonaki satr programmzn en nemli satrdr. Bu satrda t2=
t1 ifadesi ile t2 nesnesinin referansn t1 nesnesinin referansna atyoruz. Deer
tiplerinde "=" operatr ile bir deikenin deeri dierine kopyalanr. Ama nesneler
referans tipleri olduklar iin, "=" operatr bir nesnenin referans dierine atar. Bu
durumda t2 nesnesi artik t1'in elemanlarnn adreslerini ierir. Bu andan sonra
t2'nin eskiden gsterdii sicaklik, renk ve marka verilerine erimemiz mmkn
deildir. Artk onlar hafzada bir yerde ve biz bilmiyoruz. Bu verilerin hafzada kapladklar
alan .NET Framework'nun p toplaycs (garbage collector) uygun grd bir anda
temizleyecektir.
t2 nesnesinin son durumda zelliklerine bakacak olursak gerektende t1'i referans
ettiini grrz. Yukardaki programmz altrdmzda aadaki sonucu elde ederiz:

Son olarak u ilgin soruya cevap vermeye alalm. "Bir nceki program kodunun
sonuna aadaki ksm eklersek ne gibi bir deiiklik olur?"

// t2 nesnemizin zelliklerini degitiriyoruz:


t2.scaklk=30;
t2.renk="Krmz";
t2.marka="Dolu";

//t1 nesnemizin zellikerine bir gz atalm:


Console.WriteLine("t1'nin son durumdaki zellikleri: " +
t1.zellikler());

//t1 nesnemizin zellikerine bir gz atalm:


Console.WriteLine("t2'nin son durumdaki zellikleri: " +
t2.zellikler());

Yukardaki kodun eklenmi halini derleyip altirmay deneyelim. Sonu aadaki gibi
olacaktr:
Evet t1 ve t2'nin son durumdaki zellikleri ayndr. Bu durumdan u sonuca
ulaabiliriz: " t1 ve t2'nin herhangi biri ile zellikleri degitirirsek dieri de ayn
zelliklere sahip olur. nk her iki nesne de hafzada ayn yere referans ediyorlar."

Bu makalede nesne ynelimli programlamaya giri yaptk. Nesne ynelimli


programlamann iki temel kavram olan snf(class) ve nesne(object)'yi inceledik. Sonraki
makalelerde nesne ynelimli programlamann dier nemli zellikerini birlikte incelemek
dileiyle.
C#'ta Gsterici(Pointer) Kullanmak III

C#'ta gstericilerin kullanm ile ilgili yaz dizisinin son blm olan bu yazda gsericiler
ile dizi islemlerinin nasl yapldgi, stackalloc le dinamik bellek tahssatnn yaplmasn ve
son olarak yap(struct) gstericilerinin kullanln inceleyeceiz.

Gstericiler ile Dizi lemleri

C#'ta tanmladgmz diziler System.Array snfi trndendir. Yani btn diziler managed
type kapsamna girerler. Bu yzden tanmladgmz bir dizinin herhangi bir elemannn
adresini fixed blou kullanmadan bir gstericiye atayamayz. Bu yzden gstericiler ile
dizi islemleri yaparken ya fixed bloklari kullanp gereksiz nesne toplaycsn uyarmalyz
yada stackalloc anahtar szcn kullanarak kendimiz unmanaged type(ynetilemeyen
tip) dizileri olusturmalyz. Her iki durumuda birazdan inceleyeceiz.

Bildiiniz gibi dizi elemanlar bellekte ardl bulunur. O halde bir dizinin elemanlarn elde
etmek iin dizinin ilk elemannn adresini ve dizinin boyutunu bilmemiz yeterlidir.
System.Array snf dizilerinin elemanlarina gstericiler yardimiyla rahatlkla ulasabiliriz.
Bunun iin ilk olarak fixed ile isaretlenmis bir blok ierisinde dizinin ilk elemannn adresini
bir gstericiye atamalyz. Ardndan gstericinin degerini bir dng ierisinde birer birer
artrdgmzda her dngde dizinin bir sonraki elemanina ulam oluruz. Dizilere bu
sekilde erisebilmemizi salayan ise gsterici aritmetiidir. Tabi dizilerin elemanlarnn
bellekte ardl bulunmas da bu ilemi bu ekilde yapmamz salayan ilk etkendir.

imdi ynetilen trden(managed) bir dizinin elemanlarna nasl eritiimizi bir rnek
zerinde inceleyelim.

using System;

class Gosterici
{
unsafe static void Main()
{

int[] a = {1,2,3,4};

fixed(int* ptr = &a[0])


{
for(int i=0; i<a.Length; ++i)
Console.WriteLine(*(ptr+i));
}
}
}

Program derlediinizde dizinin elemanlarnn

1
2
3
4

seklinde ekrana yazdrldn grrsnz. (program derlerken /unsafe argmann


kullanmay unutmayn). Programn kritik noktas

fixed(int* ptr = &a[0])


satr ile dizinin ilk elemannn adresinin elde edilmesidir. Zira dizinin dier elemanlarda
srayla ilk elemandan itibaren her eleman iin adres deeri 4 byte artacak eklindedir.
Diger nemli nokta ise for dngs iindeki

*(ptr+i)

ifadesidir. Bu ifade her dngde ptr gstericisinin adres bileeni, dng degikeni kadar
artrlyor, szgelimi dng degikeni 1 ise ptr'nin adres bileeni 4 artrlyor. Bu da dizinin
ikinci elemannn bellekte bulunduu adrestir. erik operatr ile bu adrese eriildiinde
ise dizinin eleman elde edilmis olur.

Gsterici dizileri ile ilgili dier nemli nokta gstericilerin indeksleyici gibi
kullanlabilmesidir. rnein yukardaki rnekte bulunan

*(ptr+i)

ifadesini

ptr[i]

eklinde degitirebiliriz. Burdan aadaki eitlikleri karabiliriz.

*(ptr+0) == ptr[0]
*(ptr+1) == ptr[1]
*(ptr+2) == ptr[2]
*(ptr+3) == ptr[3]

Dikkat: ptr[i] bir nesne belirtirken (ptr+i) bir adres belirtir.

Dizilerin isimleri aslinda dizilerin ilk elemannn adresini temsil etmektedir. rnein
aagdaki programda bir dizinin ilk elemannn adresi ile dizinin ismi int trden bir
gstericiye atanyor. Bu iki gstericinin adres bileenleri yazdrldgnda sonucun ayn
olduu grlmektedir.

using System;

class Gosterici
{
unsafe static void Main()
{
int[] a = {1,2,3,4};

fixed(int* ptr1 = a, ptr2 = &a[0])


{
Console.WriteLine((uint)ptr1);
Console.WriteLine((uint)ptr2);
}
}
}

Program derleyip altrdnzda ekrana alt alta iki tane ayn saynn yazldn
grrsnz.
Ynetilen(managed) tiplerle almak her ne kadar kolay olsa da baz performans
eksiklikleri vardr. rnein bir System.Array dizisinin bir elemanna erimek ile stack
blgesinde olusturacagmz bir dizinin elemanna ulamamz arasnda zaman asndan
byk bir fark vardr. Bu yzden yksek performansl dizilerle almak iin System.Array
snfnn dnda stack tabanl diziler oluturmamz gerekir. Stack tabanl diziler
ynetilemeyen dizilerdir. Bu yzden bu tr dizileri kullanrken dikkatli olmalyz. nk
her an bize tahsis edilmeyen bir bellek alan zerinde islem yapiyor olabiliriz. Ancak
ynetilen dizilerde dizinin snrlarn amak mmkn degildir. Hatrlarsanz bir dizinin
snrlar alnca alma zamannda IndexOutOfRangeException istisnai durumu
meydana geliyordu. Oysa stack tabanl dizilerde dizinin snrlar belirli degildir ve tabiki
dizinin snrlarn amak kstlanmamtr. Eer dizinin snrlar almsa muhtemelen bu
ilem bir hata sonucu yaplmtr. Hibir programc kendisine ait olmayan bir bellek
alannda islem yapmamaldr. Aksi halde sonularna katlanmas gerekir.

Stack tabanl diziler stackalloc anahtar szc ile yaplr. stackalloc bize istediimiz
miktarda stack bellek blgesinden alan tahsis eder. Ve tahsis edilen bu alann balang
adresini geri dndrr. Dolaysyla elimizde olan bu baslang adresi ile stackalloc ile bize
ayrlm olan btn bellek blgelerine eriebiliriz. stackalloc anahtar szcnn kullanm
aadaki gibidir.

int * dizi = stackalloc int[10];

Bu deyim ile stack bellek blgesinde 10*sizeof(int) = 40 byte'lk bir alan programcnn
kullanmasi iin tahsis edilir. Bu alan, dizinin faaliyet alan bitinceye kadar bizim
emrimizdedir. Tahsis edilen bu 40 byte byklndeki bellek alannn ilk byte'nn adresi
ise int trden gsterici olan dizi elemanna aktarlr. Dolaysyla dizi gstericisi ile ierik
operatrn kullandmzda bize ayrlan 10 int'lik alann ilk elemanna erimi oluruz.

! stackalloc ile tahsis edilen bellek alanlarnn ardl olmas garanti altna
alnmtr.

stackalloc ile alan tahsisat yaplr. Ancak alan tahsisat yaplan bellek blgesi ile ilgili
hibir islem yaplmaz. Yani yukaridaki deyim ile, iinde tamamen rastgele deerlerin
bulundugu 40 byte'lk bir alanmz olur. Bu alandaki deerlerin rastgele degerler olduunu
grmek iin asagidaki program yazn.

using System;

class Gosterici
{
unsafe static void Main()
{
int * dizi = stackalloc int[10];

for(int i=0; i<10;++i)


Console.WriteLine("*(dizi+{0}) = {1}",i,dizi[i]); }
}
}

! Yukardaki programda bir gsterici ile bellekteki ardl blgelere indeksleyici


operatr ile nasl eritiimize dikkat edin.

Program /unsafe argmani ile beraber derleyip altrdktan sonra aadaki ekran
grntsn elde etmeniz gerekir. Tabi bu deerler rastgele oldugu iin sizdeki grnt
tamamen farkl olacaktr. Rastgele deerden kast alma zamannda Random gibi bir
snfin kullanlp rastgele bir say retilmesi deildir. Burdaki saylar daha nce almi
olan programlardan kalan p deerlerdir.

C:\Programlar\StackAlloc
*(dizi + 0) = 0
*(dizi + 1) = 1244236
*(dizi + 2) = 1243328
*(dizi + 3) = 1350496
*(dizi + 4) = 124334
*(dizi + 5) = 1287174
*(dizi + 6) = 1243328
*(dizi + 7) = 0
*(dizi + 8) = 0
*(dizi + 9) = 1243404

C:\Programlar\StackAlloc

Console.WriteLine("*(dizi+{0}) = {1}",i,dizi[i]);

satrndaki

dizi[i]

yerine

*(dizi + i)

yazmamz herhangi bireyi deitirmezdi. Daha nce bu iki kullanmn edeer olduunu
belirtmitik.

Stack tabanli dizilerle ilgili bilinmesi gereken en nemli nokta dizinin snrlarnn almas
ile ilgilidir. Daha nceden de denildii gibi stack tabanli dizilerin snrlar aldnda
herhangi bir uyar verilmez. Elbetteki program baaryla derlenir ancak almma
zamannda bize ait olmayan bir adresin ieriini degitirmi oluruz ki bu da bir
programcnn baina gelebilecek en tehlikeli durumdur. rnein aaidaki programda
stackalloc ile 10 int trnden nesnelik alan tahsis edilmektedir. Buna ramen istediimiz
kadar alan kullanabiliyoruz.

using System;

class Gosterici
{
unsafe static void Main()
{
int * dizi = stackalloc int[10];

for(int i=0; i<50;++i)


*(dizi+i) = i;
}
}

stackalloc ile oluturacamz dizilerin boyutu derleme zamannda bilinmek zorunda


deildir. rnein alma zamannda kullancnn belirledii sayda elemana sahip olan bir
ardl bellek blgesi aagdaki programda oldugu gibi tahsis edilebilir.
using System;

class Gosterici
{
unsafe static void Main()
{
Console.Write("Dizi boyutu gir: ");
uint boyut=0;

try
{
boyut = Convert.ToUInt32(Console.ReadLine());
}
catch(FormatException e)
{
Console.WriteLine(e.Message);
}

int * dizi = stackalloc int[(int)10];

for(int i=0; i<(int)boyut; ++i)


{
*(dizi+i) = i;
Console.WriteLine(dizi[i]);
}
}
}

Bu program ile alma zamannda 7 elemanl stack tabanl bir dizinin oluturulduunu
aadaki ekran grntsnden grebilirsiniz.

Yap(Struct) Trnden Gstericiler

int,char,double gibi veri trleri aslnda birer yapdr. Bu konun banda btn deer tipleri
ile gsterici tanmlayabileceimizi sylemitik. C# temel veri trlerinin yansra kendi
bildirdiimiz yaplar da deer trndendir. O halde bir yap gstericisi tanmlayabilmemiz
doal bir durumdur. Yap gstericilerinin tanmlanmas temel veri trlerinden gsterici
tanmlama ile ayndr. Ordaki kurallarn tamam yaplar iinde geerlidir. Fakat yap
gstericisi tanmlamann bir art vardr, oda yapnn ye elemanlarnn tamamnn deer
tipi olma zorunluluudur. rnein aadaki yap gstericisi tanmlamas geersizdir.

using System;

struct Yapi
{
int x;
char c;
string s;

public Yapi(int x,char c, string str)


{
this.x = x;
this.c = c;
this.s = str;
}
}

class StackAlloc
{
unsafe static void Main()
{
Yapi yapi = new Yapi(2,'a',"Deneme");

Yapi* pYapi = &yapi;


}
}

Yukarda 'Yapi' trnden gstericinin tanmlanamamasnn sebebi yapnn ynetilen


trden(managed type) bir ye elemannn bulunmasdr. Bu ye eleman da doal olaral
string trdr. Yap bildiriminden string trn karp aadaki gibi ilgili deiiklikleri
yaptmzda 'Yapi' trnden gstericileri tanmlayabiliriz.

using System;

struct Yapi
{
int x;
char c;

public Yapi(int x,char c)


{
this.x = x;
this.c = c;
}
}

class StackAlloc
{
unsafe static void Main()
{
Yapi yapi = new Yapi(2,'a');

Yapi* pYapi = &yapi;


}
}

Yap gstericileri zerinden yap gstericisinin adresine ilikin nesnelerin elemanlarna


zel bir operatr olan -> operatr ile eriebiliriz. rnein yukardaki programn Main()
metodunu asadaki gibi deitirdiinizde ekrana yap nesnesinin x ve c elemanlar
yazdrlacaktr. Tabi Yapi'nn ye alamanlarn public olarak deitirmeniz
gerekecektir. nk ok operatr ilede olsa ancak public olan elemanlara
ulaabiliriz.

unsafe static void Main()


{
Yapi yapi = new Yapi(2,'a');

Yapi* pYapi = &yapi;


Console.WriteLine("yapi.x= " + pYapi->x);
Console.WriteLine("yapi.c= " + pYapi->c);
}

Not: ' -> ' operatrne ok operatr de denilmektedir.

Yapnn public olan elemanlarna ok operatr yerine yap nesnesinin ieriini * operatr
ile elde edip nokta operatr ile de ulaabiliriz. Buna gre yukardaki Main() metodu ile
asagidaki Main() metodu edeerdir.

unsafe static void Main()


{
Yapi yapi = new Yapi(2,'a');

Yapi* pYapi = &yapi;

Console.WriteLine("yapi.x= " + (*pYapi).x);


Console.WriteLine("yapi.c= " + (*pYapi).c);
}

Her iki Main() metodunun rettii kt ayndr.

Gstericilerin en ok kullanld dier bir uygulama alan da karakter ilemleridir. Bir


yazy karekter dizisi olarak temsil edip yazlar ile ilgili ilemler yaplabilir. C#' taki string
trnn altnda geekleen olaylarda zaten bundan ibarettir. Karakter dizileri ile ilgili en
nemli nokta bir yazy char trden bir gstericiye atayabilmemizdir. Karekter dizileri olan
stringlerdeki her bir karakter bellekte ardl bulunmaktadr. Dolaysyla yazdaki ilk
karakterin adresini bildiimizde yazdaki btn karakterlere eriebiliriz. C#'taki string
tr ynetilen tip(managed type) oldugu iin char trden bir gstericiye bir yaznn ilk
karekterinin adresini atamak iin fixed anahtar szcn kullanmalyz. Aadaki
programda bir yaznn char trden gstericiye nasl atandn ve bu gsterici ile yazdaki
her karaktere ne ekilde eriildiini gryorsunuz.

using System;

class KarakterDizisi
{
unsafe static void Main()
{
fixed(char* ptr = "Sefer Algan")
{
for(int i=0; ptr[i] != '\0'; ++i)
Console.Write(ptr[i]);
}
}
}

Buradaki en nemli nokta ptr[i]' nin '\0' karakteri ile karlatrld yerdir. Gstericiler ile
bellekte char trnn byklg kadar ilerlerken yaznn nerede sonlandgn bilemeyiz.
Bunun iin

char* ptr = "Sefer Algan"


deyimi ile bellee yerlestirilen 'n' karakterinden sonra null deerini ifade eden '\0'
karekter yerletirilir. Bu karektere rastlanld zaman yaznn sonuna gelmi bulunuyoruz.

Not: Gstericilerle ilgili yaynlanan bu makale dizisi yazm olduum ve yaknda Pusula
yaynclktan kacak olan C# kitabndan alnmtr.

.NET'te Dinamik Kontrol Oluturma


Bu yazda windows ve web uygulamalarnda dinamik kontrollerin nasl oluturulacan ve
oluturulan dinamik kontrollere eriim yntemlerini inceleyceiz. Ayrca bu yazda
dinamik kontrol oluturma ile ilgili kapsaml bir rnek kod yeralmaktadr.

Bir ok uygulamada(zellikle oyunlarda) kontrollerimizin saysn tasarm aamasnda


bilemeyebiliriz. rnein hepimizin bildii mayn tarlas oyununda, oyun alan bir ok
kareden olumaktadr. stelik oyun alan, kullancnn isteine gre deiebilmektedir.
Eer tasarm aamasnda btn kontroller form zerine yerletirilmi olsayd hem bu
kontrollerin ynetimi zorlaacakt hemde gereksiz yere bir ok kod yazlm olacakt. Buna
benzer bir durum web formlar ile programlama yaparken de grlebilir. rnein bir
anket sisteminde anketin seenekleri kadar CheckBox kontroln dinamik olarak web
formunun zerine yerletirebilmemiz gerekir. Eer bu imkanmz olmasayd Web formlar
ok esnek bir programlama modeli sunmazd. Neyse ki Microsoft tasarmclar hereyi
dnm... :)

Dinamik kontrol oluturmaya gemeden nce nasl bir form tasarm yapmaya
altmza bakalm. Aadaki formdan da grdnz zere 8X8'lik bir dama tahtasnn
her bir karesi aslnda bir Button kontrolnden ibarettir. Tasarm aamasnda 64 tane
Button kontroln form zerine yerletirip herbirni tek tek dzenlemek yerine bir dng
vastas ile istediimiz sayda Button kontroln oluturup Form elemanna ekleyeceiz.

ToolBox penceresinde grdnz btn kontrolleri temsil eden snflar


System.Windows.Forms isim alannda bulunan Control isimli snftan tretilmitir. Baz
kontroller ise yapsnda deiik kontrolleri barndracak ekilde tasarlanmtr. rnein
Form penceresi zerene eklenen kontroller bu duruma bir rnektir. Kontrolleri gruplamak
iin kullanlan GrouopBox ta bu ekildedir. Bu zel kontrollere yeni bir kontrol eklemek
iin bu Control trnden olan Controls isimli koleksiyon kullanlmaktadr. rnein bir
form zerine yeni bir Button kontrol eklemek iin aadaki deyimleri yazmalyz.

Button tb = new Button();


Form1.Controls.Add(button)

Yukardaki deyimleri bir dng iinde yapp oluturduumuz Button kontrollerinin ilgili
zelliklerini deitirdikten sonra dama tahtasn rahatlkla oluturabiliriz.

imdi bu yaznn en altnda bulunan linki kullanarak projeyi bilgisayarnza ykleyerek


projeyi an. Form1 snfnn iinde bulunan aadaki TahatCiz() isimli metodu
inceleyerek kontrollerin dinamik olarak nasl yaratldklarn inceleyin.
private void TahtaCiz(int Boyut1,int Boyut2, int En, int Boy)
{
int satir =0;
int sutun =0;

Button tb = new Button();

for(int i=0; i < Boyut1*Boyut2; i++)


{

if(i % Boyut2 == 0)
{
satir++;
sutun = 0;
}

tb = new Button();
tb.Name = "tb" + i.ToString();
tb.TabIndex = i;
tb.Text = i.ToString();
tb.Size = new System.Drawing.Size(En,Boy);

Point p = new System.Drawing.Point(tb.Size.Width + (sutun-


1)*tb.Width,tb.Size.Height + (satir-2)*tb.Height);

tb.Location = p;
tb.FlatStyle = FlatStyle.Standard;
tb.Click += new System.EventHandler(this.button1_Click);

Butonlar.Add(tb);
this.Controls.Add(tb);
sutun++;
}

this.ClientSize = new Size(tb.Width*Boyut2 ,tb.Height*Boyut1);


satir = 0;
sutun = 0;
Butonlar.TrimToSize();
RenkAyarla();
}

TahtaCiz() isimli metodu biraz inceleyelim. Bu metot kendisine gnderilen bilgiler nda
form zerine dinamik bir dama tahtas izmektedir. Ayrca ie yarar bir ka ilem daha
yapmaktadr. Bu metoda gnderilen Boyut1 ve Boyut2 deikenleri dama tahtasnn
boyutlarn belirtmektedir. En ve Boy parametreleri ise tahtadaki her bir karenin enini ve
boyunu belirtmektedir. Bu bilgileri parametre olarak almamz istediimiz boyutta dama
tahtasn izebileceimiz anlamna gelmektedir. Zaten form zerine konulan bir men
yardmyla dama tahtasnn boyutu ve karelerin en ve boyu istenildii gibi
deitirilmektedir. Bu metot sadece butonlarn form zerine yerletirilmesinden
sorumludur. RenkAyarla() isimli dier bir metot ise yerletirilen bu butonlarn bir
algoritmaya gre renklerini ayarlamay salamaktadr. Bu metot iinde oluturulan buton
kontrollerine baka metotlar iinde eriebilmek iin oluturulan her kontrol global
dzeyde tanmlanan Butonlar isimli bir Arraylist koleksiyonuna eklenmektedir. Bu
metottaki dier nemli bir satr ise oluturulan dama tahtasnnn boyutlarna gre form
nesnesinin yeniden ekillendirilmesidir. Bu ilem
this.ClientSize = new Size(tb.Width*Boyut2 ,tb.Height*Boyut1);

satryla yaplmaktadr.

Not: Her bir Button kontrolnn yanyana ve alt alta nasl yerletirildiini daha iyi
anlamak iin size tavsiyem kat zerine bir dama tahtas izip her bir karenin konumuna
ilikin matematiksel bir ifade bulun. Bylece herey daha ak olacaktr.

Aadaki satrda her bir buton kontrolnn Text zellii dng deikeni olan i'ye
atanmaktadr.

tb.Text = i.ToString();

Dinamik kontrolleri oluturma ile ilgili dier bir nemli nokta da kontrollere ilikin
olaylarn nasl arlacadr. Dikkat ederseniz yukardaki metotta oluturulan btn
kontrollerin Click olayna EventHandler temsilcisi yardmyla button1_Click() metodu
ilitirilmitir. Oluturulan butonlardan herhangi birine tkladnzda bu metot iletilecektir.
Peki hani butonun tklandn nasl anlayacaz. Bunun iin button1_Click() metodunun
bildirimine bakalm.

private void button1_Click(object sender, System.EventArgs e)


{
Button b = (Button)sender;

MessageBox.Show(b.Text);
}

Yukardaki metodun bir parametresi olan sender deikeni bu metodun hangi button'un
tklanmas sonucu iletildiini tutmaktadr. Bize bu imkan salayan elbetteki
EventHandler temsilcisidir(delegate).

Dnm operatr kullanlarak sender nesnesi Button nesnesine dntrlmektedir.


(Bu ileme unboxing denildiini de hatrlatmak isterim)

Bu durumda, rnein zerinde 39 yazan Button'a tkladnzda gsterilen mesaj


kutusuna gibi 39 yazacaktr.

Aadaki ekran grntsndeki dama tahtasnn biimi uygulamadaki Ayarlar


mensndeki Renk sekmesi tklanarak oluturulabilir.
Not: Dama tahtas biiminde bir form olumas iin Renk Seimi penceresindeki Gradyan
Katsays ortalanmaldr. Renk ayarlama ileminin nasl yapld bu yaz kapsamnda
olmad iin detaylarn anlatmayacam. RenkAyarla() isimli metodu incelemenizi
tavsiye ediyorum.

Web formlar ile dinamik kontrol oluturmak yukarda anlattklarmdan farkl deil. Yeni
bir ASP.NET uygulamas aarak aadaki gibi bir form tasarlayn.
Dinamik olarak oluturacamz kontrolleri Page snfna akleyebileceimiz gibi
PlaceHolder kontroln de kullanabiliriz. Ben bu i iin PlaceHolder kontroln tercih
ettim.

"Olutur" isimli butonun Click olayna ilikin metodunu aadaki gibi deitirip sonucu
inceleyelim.

private void Button1_Click(object sender, System.EventArgs e)


{
int Adet = Convert.ToInt32(TextBox1.Text);

for(int i=0; i<Adet; ++i)


{
TextBox yeni = new TextBox();
yeni.ID = "Text" + i.ToString();
yeni.Text = "TextBox" + i.ToString();

PlaceHolder1.Controls.Add(yeni);
PlaceHolder1.Controls.Add(new LiteralControl("<br/>"));
}
}

Projeyi derleyip altrn ve TextBox kutusuna bir tamsay girip "Olutur" butonuna
tklayn. lermleri baar ile yaptysanz aadaki gibi "PlaceHolder" kontrol iinde 4
adet TextBox kontrol dinamik olarak yerletirilecektir.

Not : Sunucu kontrol olmayan <br> etiketinin LiteralControl olarak tanmlandna


dikkat edin.

Dinamik kontrolleri oluturmay rendiinize gre artk web tabanl bir mayn tarlas
oyunu yapmann zaman geldi sanrm :) Biraz aba ile bu oyunu rahatlkla
yapabileceinizi dnyorum.
Visual C#.NET 2003'teki Yenilikler

Bu yazda Visual StudioNET 2003 ile birlilkte gelen Visual C# dilinde yaplan nemli
deiikliklere ve Visual Stdio.NET gelitirme ortamnn(IDE) yeni zelliklerine
deinilecektir. Bu yeni zellikler ve deiiklikler 3 ana balk altnda incelenecektir :
Derleyici ve dildeki deiiklikler, proje gelitirme ile ilgili deiiklikler ve VS.NET 2003
IDE'sindeki deiikler.

Giri

Bildiiniz gibi 2001 ylndan beri C# dili ECMA(European Computer Manufacturer's


Assocation) tarafndan standart hale getirilmitir. Bu herhangi bir kurum veya kuruluun
istedii takdirde ECMA-334 standartlarna uymak koulu ile kendi C# derleyicisini
retebilecei anlamna gelmektedir. Nitekim ECMA-334 standartlar erevesi ierisinde
u anda farkl platformlar iin gelitirilmi C# derleyicileri bulunmaktadr. Bu derleyiciler
ierisinde en ok bilinen ve kullanlan Microsoft'un Visual C# derleyicisidir. Microsoft,
ECMA standartlarna bal kalmak koulu ile kendi derleyicisini istedii ekilde
biimlendirebilmektedir. Bu yazda Visual C# derleyicisine ve dilin yapsna 2003
versiyonu ile birlikte gelen yenilikleri inceleyeceiz. Ayrca Microsoft'un Visual Studio.NET
yazlm gelitirme platformu IDE'sine yeni ekledii bir takm zellikleri inceleyeceiz.

Visual C# Dili ve Derleyicisindeki Deiiklikler

Visual C# 2003 versiyonunda iki ana deiiklik yaplmtr. Bu deiklikler eski kodlarn
almamasna salayacak nitelikte deildir. Bu deiikliklerin ilki #line nilemci
komutudur. #line nilemci komutu eski versiyonda zaten bulunmaktayd, yeni
versiyonda #line nilemci komutuna yeni bir anlam daha yklenmitir. Yeni kullanmda,
iki #line komutu arasnda kalan kod satr Debugger program iin bilgi salamaz. Yani
Debugger iin bu kodlar nemsizdir. Program debugger ile altnda ilgili kod satrlara
dikkate alnmaz. Dikkat etmemiz gereken nokta derleme ileminin normal biimde
yaplmasdr. Zira #line nilemci komutuna yklenen bu anlam sadece Debugger(hata
ayklayc) programn ilgilendirmektedir. #line nilemci komutunun bu anlamda
kullanlmas iin "hidden" parametresinin kullanlmas gerekmektedir. Aada #line
nilemci komutunun kullanlmas ve sonularnn grlmesi adm adm anlatlmaktadr.

using System;

class MyClass
{
public static void Main()
{
Console.WriteLine("www"); // Buraya "Breakpoint" koyun.

#line hidden

Console.WriteLine("csharpnedir");

#line default

Console.WriteLine("com");
}
}
Krmz yazl satra bir breakpoint ekledikten sonra Debugger ile birlikte program
derleyin. Bunun iin yapmanz gereken F5 tuuna basmak yada Debug mensnden Start
sekmesini semektir. Program altnda programdaki her 3 satrn da ekrana
yazdrldn greceksiniz, ancak kontrol Debugger programna getiinde Debug
mensndeki StepOver(F10) komutu ile program iinde satr satr ilerlerken Degugger
programnn ikinci satrla ilgilenmediini greceksiniz.

Dier bir deiiklik ise XML yorum satrlar ile ilgilidir. Bildiiniz gibi C# kodu ierisinde
XML formatnda yorum satrlar eklenebilmektedir. Bu yorum satrlar metotlar, snflar ve
dier tipler hakknda dkmantasyon salamk iin yazlmaktadr. Derleme ileminde
istenirse bu yorum satrlar C# derleyicisi tarafndan ayklanarak rapor halinde sunulabilir.
Eski versiyonda XML yorum satrlar 3 tane ters bl karekterinden sonra yazlrd.
rnein sklkla grdmz "summary" elementi aadaki gibi yazlabilir

/// <summary>
///
/// </summary>

Yeni versiyonda XML yorum satrlar /** ve */ karekterleri arasnda da yazlabilir hale
getirilmitir. Bu yeni kurala gre aadaki yazm biimleri ile XML yorum satrlar
oluturulabilir.

/**
<summary>yorum</summary>
*/

/** <summary>yorum</summary> */

/**
* <summary>
* yorum</summary>*/

Yukardaki her kullanmda edeerdir.

Bunlarn dnda bir nceki versiyonla yeni versiyondaki kullanmlar birletirip ayn
kaynak kod iinde aadaki gibi de kullanabiliriz.

/**
<summary>Yorum
satiri
*/
/// <summary>

Yapsal Deiiklikler

Visual C# 2003 derleyicisinin rettii baz kodlarda ve isel mekanizmalarda da deiiklik


olmutur. Bu deiikliklerden en nemlileri zellik(property) bildiriminde ve foreach
dng yapsnn alma mantnda grlmektedir.

Snflarn bir ye eleman olan zellik bildirimi set ve get anahtar szckleri ile yaplr. Bu
yzden bu zelliklere genellikle "setter" ve "getter" da denilmektedir. zellik bildirimi C#
derleyicisi tarafndan zel metotlara evrilir. Bu metotlar srasyla get_OzellikIsmi() ve
set_OzellikIsmi() metotlardr. Dolaysyla bir nesne zerinden herhangi bir zellii
ardmzda aslnda bir metot altrm oluyoruz. Zaten C++ dilinde bu tr ilemleri
yapmak iin Get ve Set ile balayan eitli metotlar tanmlanrd. C# bu ilemleri biraz
daha soyutlatrarak kullancnn daha rahat almasn salamtr.

Visual C# 2002'de nemli bir bug vard. Bu bug zellik bildirimlerinin get ve set
bloklarnn varlndan kaynaklanmaktayd. rnein aadaki kodda grdnz snf
bildirimi herhangi bir hata vermiyordu.

class Deneme
{
public int a
{
get
{
return 5;
}
set
{
value = 5;
}
}

public int get_a()


{
return 3;
}

public int set_a()


{
return 3;
}
}

Bu snf bildirimini ieren bir kaynak kodu delendiinde

Deneme d = new Deneme();


d.a = 5;

satrlarndaki d.a; ile a zelliinin set blounun mu altrlaca yoksa set_a()


metodunun mu altrlaca belli deildir. Bu tr bir bildirimin derleme hatasna yol
amas gerekir. nk a zelliinin bildirimindeki set ve get bloklar sayesinde zaten
get_a() ve set_a() metot bildirimleri yaplmtr. Visual C# 2003 derleyicisi ile bu snf
bildirimini ieren bir kaynak kod derlenemeyecektir.

Not: Arayzlerde bildirimi yaplm zellikler iin derleme zamannda get_Ozellik() ve


set_Ozellik() gibi iki metot tanm yaplmaz. Bu yzden aadaki kodda IArayz
arayznden tremi olan snf iinde a zelliinin get ve set bloklar tanmlanrken
set_a() ve get_a() metotlar kullanlamaz.

interface Deneme : IArayuz


{
public int a
{
get;
set;
}
}

class Deneme : IArayuz


{

//Geerli zellik Bildirimi


public int a
{
get
{
return 5;
}
set
{
value = 5;
}
}

//Geersiz Bildirim
public int IArayuz.get_a()
{
}

//Geersiz Bildirim
public int IArayuz.set_a(int deger)
{
}
}

Derleyicinin yapsndaki dier bir deiiklik foreach dngsnn iletilmesi srasnda


grlmektedir. Bildiiniz gibi foreach ile iteratif bir ekilde trlere ait dizilerin
elemanlarna erimemiz mmkn, ancak btn trler iin foreach dngsn
kullanamayz. Bunun iin foreach ile kullanlacak trlerin baz metotlar ve zellikleri
salamas gerekir. Bu metotlar ve zellikler IEnumerator arayz iinde bildirilmitir.
foreach dngsnn bitiminde C# derleyicisi dngde kullanlan trn IDisposable
arayzn uygulayp uygulamadn kontrol etmiyordu. foreach ile kullanlan tr
IEnumerator arayzn uygulasn yada uygulamasn Visual C# 2003 derleyicisi
IDisposable arayznn uygulanm olup olmadn kontrol eder ve bu sayede
IDisposable arayndeki Dispose() metodu arlr.

Gze arpan dier bir deiiklik ise niteliklerin kullanmnda grlmektedir. private
eleman olan nitelikler eski versiyonda kullanlabiliyordu ancak yeni derleyicide sadece
public nitelik elemanlar kullanlabilmektedir. rnein Deneme isimli nitelik snf ve bu
snfn private ye eleman olan Ozellik bildirilmi olsun. Buna gre aadaki metot
bildirimi yeni derleyici iin geersizdir.

[Deneme(Ozellik = "deneme zellik")]


public int Metot()
{

Not: Yukardaki bildirim Visual C# 2002 derleyicisi iin geerlidir.

Dier bir deiiklik enum sabitlerinin artk char trne dntrlebilmesidir. rnein
aadaki program derleyip altrdnzda ekrana 'L' karekteri yazdrlacaktr. (L
karekterinin unicode karl 76'dr)

using System;

enum Harfler
{
A,B = 76,C
}

class Class1
{
static void Main()
{
char c = (char)Sefer.B;
Console.WriteLine(c);
}
}

Yukarda anlatlan deiikliklerin tamam uygulama performansn artrmak ve ECMA


standartlarna daha sk ballk amacyla yaplmtr. Bir nceki versiyonda ECMA
standartlarna uymayan kurallar ve baz bug'lar yeni versiyonda dzeltilmitir.

Gelitirme Ortamndaki Deiiklikler

1- Gelitirdiimiz uygulamalar derlerken eitli uyarlar yada hatalar alabiliriz. Bu yazlm


gelitirmenin doal bir srecidir. Baz durumlarda derleyicinin verdii uyarlar gerekten
can skc olabilir. Bazende bu uyarlar programcnn olas bir hataya kar nlem almas
iin olabilir. VS.NET 2003 ortamnda proje derlenirken baz uyarlarn verilmemesini
salayabiliriz. Komut satr derleyicisinde bu ilem /nowarn argman ile yaplr. rnein
derleme ilemi srasnda CS0050 ve CS0060 kodlu uyarnn verilmemesi iin csc
derleyicisi aadaki gibi altrlr.

csc dosya.cs /nowarn:50,60

VS.NET kullanarak bu uyar engelleme ii proje zelliklerinden ayarlanr. Solution Explorer


penceresinde projeye sa tklayp proje zellikleri penceresinden "Configuration
Properties" sekmesini ardndan "Build" seeneini sein. Aadaki ekran grntsndeki
alana uyar kodlarn noktal virgl ile birbirinden ayrlacak ekilde yazn.

2- Yeni versiyon ile birliktte istersek /nostdlib argmann kullanarak mscorlib.dll


ktphanesini programlarmza eklemeyebiliriz. Bildiiniz gibi btn System isim alan ve
bu isim alannda bildirilmi trler mscorlib.dll ktphanesinde bulunmaktadr. Komut
satrndan

csc dosya.cs /nostdlib-

eklindeki bir derleme ile standart ktphane olan mscorlib.dll uygulamamza eklenmez.
Bu ilemi kendi System isim alanmz bildirmek iin kullanabiliriz.
/nostdlib+ eklindeki kullanm varsaylan kullanm ile edeerdir, yani mscorlib.dll
ktphanesi uygulamaya eklenir.

VS.NET ortamnda bu deiiklii yapmak iin proje zelliklerinden "Configuration


Properties" sekmesini ardndan "Advanced" seeneini sein. Bu pencereden "Do not use
Mscorlib" seeneini aadaki gibi true yapn.

3- Proje zellikleri penceresinde "Common Properties" seeneindeki "Build Events"


ksmndaki alanlar doldurarak projenin oluturulmas srasnda ve proje oluturulduktan
sonra altrlacak batch komutlar yazlabilir. nceden tanmlanm bir ka makroyu da
kullanmak mmkndr. "Post-Build Event Command Line" seenei ile ilgili 3 durum
szkonusudur. Bunlar batch komutlarnn

a) Her zaman altrlmas


b) Yalnzca baarl oluturmalar srasnda altrlmas
c) Oluturma ilemi kt dosyalarn gncelledii zaman altrlmasdr.

Bu seenkelerin ayarland pencere aadaki gibidir.

4- Web ve Windows uygulamalar iin birden fazla alma zaman destei salamak
mmkndr. rnein .NET Framework 1.0 ve .NET Framework 1.1 alma zamann
destekleyecek ve bu ortamlarda alabilecek uygulama gelitirmek mmkndr. Bu ayar
yapmak iin proje zellikleri penceresindeki "Common Properties" sekmesindeki
"General" sayfasndan "Supported Runtimes" zelliini deitirmek gerekir. Bu zellie
tklanldnda aadaki pencere ile karlalr.
Bu ayar yaplrken dikkat edilmesi gereken nokta .NET Framework 1.1 'deki baz
zelliklerin 1.0 versiyonunda bulunmamasdr. Bu yzden 1.1 versiyonunda gelitirilen
projelerin 1.0 versiyonunda alabilmesi iin ortak zelliklerin bulunmas gerekir.

Yeni Eklenen "Intellisense" zellikleri

VS.NET IDE'si gelitirici iin byk kolaylklar salamaktadr. Bu kolaylklarn en bilineni


ve en ie yarayan IDE'nin akll olmasdr. IDE, dilin kurallarna gre legal olan bir ok
olay bizim iin otomatik yapmaktadr. rnein bir nesnenin metotlarn ve zelliklerini '.'
operatrnden sonra grebilmemiz gibi. VS.NET 2003 IDE sine hounuza gidecek yeni
akll zellikler eklenmitir. Bu ksmda bu yeni zellikleri greceiz.

1- Gze arpan ilk deiiklik olaylara yeni bir metot ekleme srasnda grlmektedir.
VS.NET tasarm ekrannda bir kontrole ait olay ilemek istediimizde Properties
ekrannda ilgili olay seip metot ismini yazyorduk. Yeni versiyonda bu ilemler kod
editrnden de yaplabilmektedir. Bir olaya += operatr ile bir metot eklemek
istediimizde "TAB" tuuna basarsak olay ynetecek temsilci new operatr ile eklenir.
Tekrar "TAB" tuuna basldnda olay ynetecek temsilcinin temsil edecei metodun
prototipine uygun bir "event handler" metodunun bildirimi otomatik olarak yaplr.

2- Dier bir yeni zellik arayzlerin tretilmesi srasnda grlr. Bildiiniz gibi bir snf bir
arayzden tretiliyorsa arayzde bildirilmi olan btn zellik ve metotlarn treyen
snfta tanmlanmas yani uygulanmas gerekir. VS.NET IDE si tretilen arayzdeki eleman
bildirimlerini treyen snfta otomatik olarak gerekletirir. Aadaki ekran grntsnde
bu ilemin nasl yapld gsterilmektedir.

Tretilecek arayz ismi yazldktan sonra TAB tuuna baslrsa arayzdeki eleman
bildirimleri Deneme snfna otomatik olarak eklenecektir. Bu ilemden sonra Dispose()
metodunun bildirimi Deneme snfna otomatik olarak eklenmi olacaktr.

3- Tretme srasnda yeniden yklenebilecek(overiride) metotlar override anahtar


szc yazldktan sonra otomatik olarak gsterilir.rnein Metot1 ve Metot2 adnda 2
tane sanal(virtual) metodu olan TemelSnf'tan treyen snf iinde override anahtar
szc kullanldktan sonra aadaki ekran grnts elde edilir.

Yukardaki ekranda Object snfnn metotlarnn da gsterildiine dikkat edin. Ayrca


TemelSnf taki sanal olmayan metotlarn da gsterilmediine dikkat edin.

4- VS.NET IDE'sinde nesneler ile '.' operatr kullanld anda nesnenin trne ait
elemanlar listelenir. Listeleme yaplrken ilk eleman her zaman en bata olur. Yani
sralama ilemi eleman isimlerinin alfabetik sraya gre dizilmesiyle yaplr. Yeni IDE ile
birlikte kullandnz elemanlar "sk kullanlan elemanlar" blmne eklenerek bir sonraki
kullanmda en son kullanm olduunuz elemann seili olmas salanr. En ok
kullandmz Console snfnn WriteLine() metodunu rnek verelim. Listede Write()
metodu WriteLine() metodundan nce gelmektedir. Dolaysyla WriteLine() metodunu
seebilmek iin "WriteL" yazmak gerekecektir. Oysa yeni kullanmda WriteLine()
metodunu bir kere setikten sonra bir sonraki kullanmda '.' operatrne basp "W"
yazld anda WriteLine() metodu seilecektir.

5- Dier bir yeni zellik ise Debug ilemi srasnda kullanlan "Immediate Window"
penceresinin kullanmnda grlr. Artk "Immediate" penceresinde de kod editrnde
olduu gibi nesnelerin zelliklerini ve metotlarn grebilmekteyiz. Object trnden olan s
nesnesinin ye metotlarnn "Immediate" penceresinden ne ekilde grld aadaki
ekran grntsnde gsterilmitir.

Not: "Immediate" penceresi ile alabilmek iin kaynak kodda herhangi bir satra
"Breakpoint" yerletirip program "Debugger" ile birlikte derlemeniz gerekir.

Sonu

Visual C# ve VS.NET IDE'sinde yaplan deiiklikler yukarda anlatlanlar ile snrl deildir.
Ancak gze arpan yeni zellikler bunlardr diyebiliriz. VS.NET 2003'teki dier gze
arpan zellik ise "MMIT" ve "Smart Device" eklentilerinin varsaylan olarak
yklenmesidir.
C# Dilinde zellikler 1

Nesne ynelimli programlamann gnmzde ne kadar yaygn olduunu programlama ile


ilgilenen herkes bilmektedir. Nesne Ynelimli Programlama (NYP) yaklamnda temel
olan prensiplerden birisi bilgi gizleme (information hiding)'dir. Bu prensibi projelerimizde
uygulamak iin C#'in sunduu en nemli aralardan biri olan snf zellikleri (class
properties) konusunu inceleyeceiz.

Bildiiniz gibi, C# dilinde tasarlanm bir snfta iki temel unsur bulunur. Birincisi snfn
zellikleri (fields), ikinicisi ise snfn metodlari (methods)'dr. Herhangi bir snfn zellikeri
snfta tutulan iliikili verilerlerdir. Dier taraftan snfn bizim iin deiik ileri yapmasn
metodlar vastasyla salarz. Snf tasarm ok nemli bir i olup; deneyim,
konsantrasyon ve dikkat ister. Snfmzn zelliklerini tutan veriler, program ak
srasnda snf dnda deitirilebilir veya bu deerlere ulamak istenebilir.

Bu durumda akla ilk gelen zm snfn verilerinin hepsinin dardan ulailabilmesini ve


deitirilebilmesine olanak salayan public anahtari ile tanmlamakdir. Aadaki
programda bu tr bir zmn uygun olabilecei dnlmtr:

using System;

namespace Property_Makale
{
class Otomobil
{
public int model;
public string marka;
public string renk;

public Otomobil(int model, string marka, string renk)


{
if(model>DateTime.Now.Year)
this.model=DateTime.Now.Year;
else this.model=model;

this.marka=marka;
this.renk=renk;
}

public void OzellikleriGoster()


{
Console.WriteLine("\nOtomobilimizin zellikleri: ");
Console.WriteLine("\t Marka: "+ marka);
Console.WriteLine("\t Model: "+ model);
Console.WriteLine("\t Renk: "+ renk+"\n" );
}
}

class OtomobilTest
{
static void Main(string[] args)
{
Otomobil oto1 = new Otomobil(2000, "BMW" , "Siyah");
oto1.OzellikleriGoster();

oto1.model=300;

oto1.OzellikleriGoster();
}
}
}

Yukardaki kod rneimizde iki tane snf bulunmaktadr. Otomobil snf ile otomobil
nesnelerimizi oluturabiliriz. Ayrca bu snfn OzellikleriGoster() metodu ile herhangi bir
otomobil nesnemizin zelliklerini grmek iin ekrarana yazdryoruz. kinci snfmzda
(OtomobilTest) ise Otomobil snfmzdan nesneler oluturmak ve onlarn zellikerini
armak iin kullanacaz. imdi isterseniz Main() fonksiyonunu incelemeye balayalm.
Metodun hemen ilk banda oto1 isimli nesnemizi oluturuyoruz. oto1 nesnemizin
zellikleri 2000 model, siyah ve BMW olsun. Bir sonraki satrda oto1 nesnemizin modelini
300 yapyoruz. te burda byk bir hata yaplyor! nk 300 ylnda henz otomobil
retilmemiti. Byle bir hatay nasl nleriz? zm olarak otomobil nesnemizin herhangi
bir zelliini deitirmek iin ayr bir metod yazmamz gerekir. O zaman programz u
ekilde deitirmemiz gerekiyor:

using System;

namespace Property_Makale
{
class Otomobil
{
private int model;
public string marka;
public string renk;

public Otomobil(int model, string marka, string renk)


{
if(model>DateTime.Now.Year)
this.model=DateTime.Now.Year;
else this.model=model;

this.marka=marka;
this.renk=renk;
}

public void OzellikleriGoster()


{
Console.WriteLine("\nOtomobilimizin zellikleri: ");
Console.WriteLine("\t Marka: "+ marka);
Console.WriteLine("\t Model: "+ model);
Console.WriteLine("\t Renk: "+ renk+"\n" );
}

public void ModelDegistir(int yeniModel)


{
if( (yeniModel>DateTime.Now.Year)||(yeniModel<1900) )
Console.WriteLine("Otomobilin modeli su an ki yildan byk veya 1900'den
kk olamaz ! ");
else this.model=yeniModel;
}
}

class OtomobilTest
{
static void Main(string[] args)
{
Otomobil oto1 = new Otomobil(2000, "BMW" , "Siyah");
oto1.OzellikleriGoster();

oto1.ModelDegistir(300);
oto1.OzellikleriGoster();
}
}
}

Yukardaki programda Otomobil snfna ModelDegistir(int yeniModel) metodunu ekledik.


Bu metod ile modeli deitirilecek nesnenin modelinin u anda bulunulan yldan sonra ve
1900'den nce yaplmak istendiinde hata mesaj veriyor ve modelini deitirmiyor.
Ayrca snf iindeki model deikenin tanmlanmasnda private anahtarn da
kullandmza dikkat ediniz. Bu ekildeki bir yaklam ile hem snfn i ileyiini snf
dndan saklam oluyoruz hem de snfa ait verilerin deitirilmesini srasndaki hatalar
en az seviyede tutmay salyoruz.

Fakat yukardaki yntemi genelde C++ programclar kullanr(d). Bizler C# programclar


olarak daha gelimi bir yola sahibiz. Snf iindeki deerleri deitirmek ve ulamak iin
zellik (Property) aracn kullanrz. Aadaki program ise C#'n zellikleri nasl
kullandna bir rnektir:

using System;

namespace Property_Makale
{
class Otomobil
{
private int model;
public string marka;
public string renk;

public Otomobil(int model, string marka, string renk)


{
if(model>DateTime.Now.Year)
this.model=DateTime.Now.Year;
else this.model=model;

this.marka=marka;

this.renk=renk;
}

public void OzellikleriGoster()


{
Console.WriteLine("\nOtomobilimizin zellikleri: ");
Console.WriteLine("\t Marka: "+ marka);
Console.WriteLine("\t Model: "+ model);
Console.WriteLine("\t Renk: "+ renk+"\n" );
}

public int Model


{
get
{
return model ;
}

set
{
if((value>DateTime.Now.Year)||(value<1900) )
{
Console.WriteLine("Otomobilin modeli su an ki yildan byk veya
1900'den kk olamaz ! \n");
}
else this.model=value;
}
}
}

class OtomobilTest
{
static void Main(string[] args)
{
Otomobil oto = new Otomobil(2000, "BMW" , "Siyah");
Console.WriteLine("Otomobilimizin modeli: "+ oto.Model);

oto.Model=300;
oto.OzellikleriGoster();
}
}
}

Yukardaki program altrdmzda aadaki sonucu alrz:


ktsn grdnz program kodunda C#'n zellik tanmlama ve kullanma yntemini
kullandk. zellikler ile herhangi bir nesneye ait deikenin deerini renebilir ve
deitirebiliriz. Yukardaki rnek kodda yeralan aadaki ksmda bir zellik(Property)
tanmlyoruz. Genellikle bir zelliin ismi zerinde i yapt deikenin ismi ile ayn olup
sadece ilk harfi byk olur. Aslnda bu bir zorunluluk deil. Sadece C#'da bu bir
gelenektir. Bu ekilde bir kullanm bizim kodumuzu okuyanlarn kodu daha kolay
anlamas ve bizim bakalarnn kodlarn daha kolay anlamamza yardmc olur. Bir
zelliin tanmnda zellik isminden nce ne tr bir deer dnderecekse onun tipini
belirtmeliyiz. Bu genelde zelliin ilgili olduu deikenin tipidir :-)

public int Model


{
get
{
return model ;
}

set
{
if((value>DateTime.Now.Year)||(value<1900) )
{
Console.WriteLine("Otomobilin modeli su an ki yildan byk veya
1900'den kk olamaz ! \n");
}
else this.model=value;
}
}
}

zellikler iinde get ve set olmak zere iki ayr blok kod olur. stersek sadece get veya
sadece set bloklar olan zellikler de yazabiliriz. get blounda ilgili deikenimizin deerini
darya dndeririz. set blounda ise deikenimizin deerini deitiririz. Burda gereken
kontrolleri yapp daha sonra uygunsa girilen deeri kabul edebiliriz. Eminimki get blou
iinde dikkattinizi deikeni ismi yerine value eklinde armamz ekmitir. Bu
sayede kod iinde karklk olmaz. Zaten sadece bir tane deiken zerinde
alyorsunuz.

Bu makalemizde C# dilinde yeralan zellik (Property) kavramn inceledik. Bir ilerleyen


makalelerimizde sadece yazlabilir (read-only) ve sadece okunabilir (write-only) zellik
yazmay ve kullanmay inceleyeceiz.
WinAPI Fonksiyonlarnn C#'ta Kullanm

C# ve dotNET ile birlikte yazlm gelitirmeye yeni bir soluk gelmi olsada C# ile eskiden
yazlm COM komponentlerine eriebilmek mmkndr. Daha nceki iki makalede .NET
ve COM ilikisini detayl bir ekilde incelemitik. Bu makalede .NET'in Win 32 API ile nasl
entegre edildii anlatlacaktr. .NET ve C#'n yeni imkanlarnn yansra eski bir teknoloji
olan COM ve ynetilmeyen(unmanaged) kodlarla uyumlu bir ekilde almas belkide C#
ve .NET'i dier yazlm gelitirme platformlarndan ayran en nemli zelliktir.

Bildiiniz gibi C#'ta gsterici kullanm tamamen serbesttir. Bu yzden eskiden(.NET


ncesi) yazlm ve parametre olarak gsterici alan COM komponentleri ve Windows API
fonksiyonlar C# ile sorunsuz bir ekilde altrlabilmektedir. Bu yazda Win API
fonksiyonlarnn .NET ortamnda ne ekilde ele alnd incelenecektir.

Win32 sistem fonksiyonlar kullanldnda, kod CLR tarafndan ynetilmekten kar. .NET
ortamnda gelitirilen bir uygulamada ynetilmeyen kod segmenti ile kalalrsa ilgi kod
segmenti CLR tarafndan ynetilmekten kar. Dolaysyla "garbage collection"
mekanizmas ve .NET'e zg dier servisler kullanm d olur.

CLR tarafndan ynetilmeyen kodlara eriebilmek iin C#'ta


System.Runtime.InteropServices isim alannda bulunan ve DllImprtAttribute snfn
temsil eden DllImport nitelii kullanlmaktadr. DllImport nitelii ile harici bir kaynakta
bulunan metoda referans vermek iin external anahtar szc kullanlr. Bir snf
bildiriminin en banda external anahtar szc ve DllImport nitelii kullanlarak CLR
tarafndan ynetilmeyen bir metot bildirimi yaplr. Tabi metodun gvdesi harici bir
kaynakta zaten var olduu iin bizim metodun gvdesini yazmamzn bir anlam yoktur.
Ardndan bu metot snfn istenildii yerinde kullanlabilir. sterseniz basit bir rnekle
DllImport niteliinin kullanmn gsterelim.

Win API windows sistemlerinin programlanabilir arayzn iermektedir. Windows


uygulamarnn tamam bu arayzdeki fonksiyonlar ve dier yaplar kullanmaktadr.
Aadaki programda Win32 sistemlerinde bulunan MessageBox() fonksiyonunun
kullanmna bir rnek verilmitir.

Not : Bu yazda C#'ta niteliklerin(Attributes) nasl kullanldn bildiiniz varsaylmtr.

using System;
using System.Runtime.InteropServices;

class Class1
{
[DllImport("user32.dll")]
public static extern int MessageBox(int tip,string mesaj,string baslik,int secenek);

static void Main()


{
MessageBox(0,"Mesaj","Win API MessageBox",2);
}
}

DllImportAttribute snfnn bir tane yapc metodu bulunmaktadr. Bu metot parametre


olarak harici kaynan ad belirtmektedir. Yukardaki kaynak kodda MessageBox
fonksiyonunun bulunduu "user32.dll" isimli dosya DllImport niteliine parametre olarak
verilmitir. Bu rnekte dikkat edilmesi gereken dier nokta ise extern anahtar
szcnn kullanmdr. Bu anahtar szck ile bildirimi yaplan metodun harici bir
dosyada olduu belirtilmektedir. Dolaysyla C# derleyicisi metodun gvdesini kaynak
kodda aramayacaktr.

Programn alma eklini aklamadan nce ekran ktsna bakalm :

Yukurdaki ktdan ve kaynak koddan da grld zere Win API deki bir fonksiyonun
arm klasik metot armndan farkl deildir. Deien tek ey metodun bildirim
eklidir.

Not : Gsterilen mesaj kutusunun farkl formlarn grmek iin MessageBox metodunun
parametreleri ile oynayn.

imdi ksaca yukardaki programn alma zamanndaki durumunu inceleyelim. Program


altrldnda, CLR tarafndan ynetilmeyen bir metot arm yapldnda ilgili
kaynaktan metot bellee yklenir ve bellee yklenen metodun balang adresi saklanr.
Ardndan bizim parametre olarak getiimiz deikenler DLL' deki fonksiyona uyumlu hale
getirilir ve parametre olarak geirilir. Eer bir geri dn deeri bekleniyorsa
ynetilmeyen kod blmnden gelen deer uygun .NET trne dntrlerek ilemlere
devam edilir. Bu ilemler tamamen .NET'in alt yapsn ilgilendirmektedir. Dolaysyla
programcnn yapaca i sadece metodun bildirimini doru bir ekilde gerekletirmektir.

DllImportAttribute snfnn bir ka nemli zellii daha vardr. Bunlardan en nemlisi


harici kaynaktaki bir fonksiyona takma isim verebilmemizi salayan string trnde olan
EntryPoint zelliidir. EntryPoint zelliini kullanarak MessagBox fonksiyonuna takma
isim verebiliriz. Fonksiyon arm bu takma isim ile gerekletirilebilmektedir. rnein
MessageBox fonksiyonuna TebrikMesajiVer eklinde bir takma isim vermek iin aadaki
gibi bir bildirim yaplmaldr.

using System;
using System.Runtime.InteropServices;

class Class1
{
[DllImport("user32.dll",EntryPoint = "MessageBox")]
public static extern int TebrikMesajiVer(int tip,string mesaj,string baslik,int secenek);

static void Main()


{
TebrikMesajiVer(0,"Tebrikler","Takma sim Verme",0);
}
}

imdi de DllImport nitelii ile ilgili dier zelliklere ve nemli noktalara bakalm.

1 - DllImport nitelii yalnzca metotlara uygulanabilir.


2 - DllImport nitelii ile iaretlenmi metotlar mutlaka extern anahtar szc ile
bildirilmelidir.

3 - DllImport niteliinin EntryPoint'in haricinde 4 tane isimli parametresi(named


parameter) daha vardr. Bunlar : CallingConvention, CharSet, ExactSpelling,
PreserveSig ve SetLastError parametreleridir. Bu parametrelerden nemli olanlar
aada aklanmtr.

4 - CallingConvention : Bu paramtre CallingConvention numaralandrmas trndendir.


Bu parametre ile harici metodun ne ekilde arlaca ile ilgili bilgi verilir.
CallingConvention numaralandrmas 5 tane sembol ierir. Varsaylan olarak bu sembol
Winapi olacak ekilde ayarlanmtr. Yani CallingConvention parametresini DllImport ile
kullanmyorsak varsaylan olarak bu Winapi'dir. Dier semboller ise Cdecl, FastCall,
ThisCall, StdCall eklindedir. En ok Winapi sembolu kullanld iin dier sembollerin
ne anlama geldii anlatlmayacaktr. Dier sembollerin ne anlama geldiklerini MSDN
ktphanesinden detayl bir ekilde renebilirsiniz.

5 - CharSet : Harici fonksiyonun armnda kullanlacak karekter setini belirler. Bu


parametre CharSet numaralandrmas ile belirtilir. Varsaylan olarak CharSet.Auto
eklindedir. CharSet numaralandrmasnn dier sembolleri Ansi, Unicode ve None
eklindedir.

6 - ExactSpelling : EntryPoint ile belirtilen ismin ilgili fonksiyon ismine yazm biimi
bakmndan tam uyumlu olup olmayacan belirtir. Bu zellik bool trndendir ve
varsaylan olarak false deerdir.

DllImport metodunun varsaylan arm biimi olan Winapi sadece Windows sistemlerine
zgn olduu iin sistemler aras tanabilirliin yksek olmas gereken projelerde bu
niteliin kullanmndan kanmak gerekir. Bu yzden DllImport zelliini kullanmadan
nce ilgili fonksiyonun .NET Framework iinde olup olmadn kontrol etmek gerekir.
rnein MessageBox fonksiyonu zaten System.Windows.Forms isim alannda bulunduu
iin API kullanarak bu fonksiyondan yararlanmak mantkl deildir. Zira ileride
programnzn Linux ortamnda yada dier farkl ortamlarda da almasn istiyorsanz
programnz deitirip yeniden derlemeniz gerekecektir. Oysa .NET Framework iinde
bulunan standart snflar ve onlarn metotlarn kullanrsanz byle bir derdiniz
olmayacaktr.
C#'da Sra (Queue) Snf ve kullanm

Bir nceki yazmzda genel olarak yn (Stack) veri yapsnn alma modeline ve C#'ta
kullanabileceimiz yn snfn ve bu snfn metodlar zerinde durmutuk. imdi burada
ise, dier nemli veri yaps olan sra (queue) veri yapsn inceleyeceiz. Queue veri
yapsnn mantn anladktan sonra .NET snf kitaplklarnda bulunan Queue snfn
reneceiz.

Queue veri tipi ve .NET'in snf ktphanesinde bulunan Queue


snf, yn (stack) snfna ok benziyor. Bu veri tipleri alma
mant olarak tam tersi gibi grnmelerine ramen bir ok
metodlar ve zellikleri birebir rtyor. Bu durumda birazdan
okayacanz makalenin format yn makalemizdekine ok
benzediini greceksiniz.

1. Queue(sra) veri Yapsnn alma ekli

Sralar (queue) lk Giren lk kar (FIFO) prensibi ile alan veri yaps ekinde
bilinirler. Bir sraya ilk giren eleman ilk olarak kar. Sralara rnek olarak bir markette
alveriini yapan mterilerin, aldklar rnlerin cretlerini demek iin kasada sraya
gemeleri verilebilir. Marketteki srada sraya ilk giren mterinin ii ilk nce biter. Daha
sonra ikinci ve nc mterilerin ileri yaplr.

Sralar bilgisayar programlamada sk sk bavurulan veri yaplardr. Mesela, iletim


sisteminde yaplmas gereken ileri bir sra veri yaps ile tutarz. Herhangi bir anda yeni
bir i geldii zaman bu i sraya (Queue) girer. Sras gelen i yaplr ve sonraki ie geilir
gibi. Queue veri yaplar ayrca simulasyonlarda da sk sk kullanlr.

2. .NET Snf Ktphanesi Sra Snf (Queue)

.NET snf ktphanesinde sra veri yapsn kullanmak iin Queue snfn kullanrz.
NET'in yn (Stack) snfn kullanmak iin pogram kodunun ba tarafna using
System.Collections; eklememiz gerekir. Yani sra snf System.Collections isim
alannda bulunuyor.

C# veya herhangi bir dilde yazlan yn veri yaplarnda Enqueue(), Dequeue, Peek(),
Clear() fonksiyonlar ve Count, zellii vadr. Bunlarn yannda Clone(), CopyTo(),
ToArray(), Contains() ve Equals() metodlar .NET'in yn snfnda yeralr.

Sra snfnn Enqueue() metodu sraya yeni bir eleman ekler. Dequeue() metodu ile
ynn en ndeki eleman sradan siler ve silinen eleman geriye dnderir. Eer srann
tepesindeki eleman renmek istersek Peek() medotunu iimize yarar. Bu metod srann
bandaki nesneyi ddrr ama bu nesneyi sradan silmez.

using System;
using System.Collections; // Queue snf bu isim alan iinde bulunur.

class Sira_Ornek1
{

public static void Main()


{

// Queue snfndan bir nesne oluturalm:


Queue sira = new Queue();

// Nesnemize Enqueue metodu ile deerler girelim:


sira.Enqueue("Ahmet");
sira.Enqueue("Ferit");
sira.Enqueue("Hasan");
sira.Enqueue("Hseyin");

// sira isimli nesnemizin eleman says:


Console.WriteLine( "\n sira nesmemizin eleman says: " + sira.Count);

// sira isimli nesnemizin elemanlar:


Console.WriteLine( "\n sra nesmemizin elemanlar: " );
DegerleriYaz( sira );

//sira isimli nesmemizden bir eleman alalm:


string eleman= (string)sira.Dequeue();
Console.WriteLine(" \n Sramizin bandan unu aldk: " + eleman);

//imdi ise siranin en bandaki nesneyi renelim.


// Ama onu iradan kartmayacaz:
eleman= (string)sira.Peek();
Console.WriteLine(" \n Sramzn bandaki eleman " + eleman);

public static void DegerleriYaz( IEnumerable kolleksiyon )


{
System.Collections.IEnumerator Enum = kolleksiyon.GetEnumerator();

while ( Enum.MoveNext() )
Console.Write( "\t{0}", Enum.Current );

Console.WriteLine();
}
}

Yukardaki rnek programda nce Queue snfndan sra isimli bir nesne oluturuyoruz.
Sonraki alt satrda sramza "Ahmet", "Ferit", "Hasan", ve "Hseyin" deerlerini Enqueue
metodu ile ekliyoruz. Degerleri() ismini verdiimiz static fonksiyonumuz ile sramzdaki
eleman saysn ve elemanlar ekrana yazdryoruz. Daha sonra sramzdan bir tane
eleman Deuque() metodu yardmyla alyor ekrana yazdryoruz. Programn son
ksmnda ise Peek() metodunu kullanrak srann en stndeki elemann ne olduunu
reniyoruz ve bu eleman srada kalyor.

Sra snflarnda bulunan dier iki temel fonksiyonlar olan Count zellii ve Clear()
metodlardr. Bunlardan Count, sra nesnesinde bulunan elemanlarn saysn geriye
dnderen bir zelliktir. zellikler C# dilinde snflarda bulunan ye deikenlerin
deerlerini renmemize ve onlarn deerlerini deitirmemize yarayan bir tr
fonksiyonlardr. Count zellii eleman saysn int tipinde dnderir ve sadece okunabilen
(readonly) yapdadr. zellikler program iinde arlrken parantezleri kullanmayz. Eer
sray boaltmak/temizlemek istersek Clean() metodu iimizi yarayacaktr. Clean()
metodu hibir parametre almaz ve hibirey dndermez. Herhangi bir sra nesnesinin
iinde bir elemann olup olmadn anlamak iin Contains() metodu kullanlr. Bu metod
aranacak nesneyi alr ve geriye true veya false deerlerini dnderir. sterseniz aadaki
programda Contains() ve Clear() metodlar ile Count zelliklerini nasl
kullanabileceimizi grelim:

using System;
using System.Collections; // Queue snf bu isim alan iinde bulunur.

class Sira_Ornek2
{

public static void Main()


{

// Queue snfndan bir nesne oluturalm:


Queue sira = new Queue();

// Nesnemize Enqueue metodu ile deerler girelim:


sira.Enqueue(12);
sira.Enqueue(3);
sira.Enqueue(18);
sira.Enqueue(7);
sira.Enqueue(20);

// sra isimli nesnemizin eleman says:


Console.WriteLine( "\n sira nesmemizin eleman says: " + sira.Count);

// sira isimli nesnemizin elemanlar:


Console.WriteLine( "\n sra nesmemizin elemanlar: " );
DegerleriYaz( sira );

//Contains metodunun kullanm:


int sayi=7;

if(sira.Contains(7))
Console.WriteLine("Sramzda " + sayi + " var.");
else
Console.WriteLine("Sramzda " + sayi + " yok.");

// sramzn iindeki elemanlar silelim:


sira.Clear();

// Sramz temizledikten sonra ka tane


//eleman bulunduunu bulup yazalm.
int elemanSayisi= sira.Count;

Console.WriteLine("\n Sramizda u anda {0} tane eleman vardr.", elemanSayisi);


}

public static void DegerleriYaz( IEnumerable kolleksiyon )


{
System.Collections.IEnumerator Enum = kolleksiyon.GetEnumerator();

while ( Enum.MoveNext() )
Console.Write( "\t{0}", Enum.Current );

Console.WriteLine();
}
}

Ynda makalemiz Clone(), ToArray() ve Equals() metodlarnn aynlar Queue snf


iinde bulabiliriz. Sizlerin yn makalesindeki en son rneini sra veri tipi iin de yazp
kendinizi denemenizi tavsiye ederim. Herkese iyi almalar.
Visual C# ile Basit Bir Not Defteri Uygulamas

Bu yazmzda konu olarak Windows Formu setim;nk bu konuda Trke kaynak


neredeyse yok, doru drst bir programn yapmn gsteren bir yaz, bir site
bulamadm, tabi ki Trke bir ok makale var sitelerde, bende onlardan yararlanarak ve
deneyerek bir eyler yaptm ve imdi bu yaptklarm sizinle paylayorum.

Eer bu yazy sonuna kadar okursanz ve kodlar sizde yazarsanz, yaznn sonuna
geldiiniz Basit Not Defteri adnda bir uygulamanz olacak. nce bu programdan biraz
bahsedelim. Ad stnde bir Not Defteri uygulamas ancak basit hem de ok basit.
Yapabildii eyler: Yeni dosya yaratmak, var olan dosyalar amak, dosya kaydetmek
Byle bir program yapmamn sebebi tabi ki metin editrleri konusunda alternatif
oluturma istei falan deil, tek sebep benim ilk balarda ok zorlandm SaveFileDialog,
OpenFileDialog gibi kontroller konusunda rneklemeler yapmak..

Laf daha fazla uzatmadan artk uygulamaya geelim. nce aadaki program Visual
Studio .Netin Designernda oluturun

Ben bu resime kullandm kontrollerin isimlerini de yazdm ki kodlar incelerken zorluk


kmasn. Yalnz burada grnmeyen 2 kontrol daha var. Biri SaveFileDialog (objSave),
dieri OpenFileDialog (objOpen). Bu kontrolleri de ekleyip adlarn parantez ilerindeki
gibi yaparsanz sorun kmaz

imdi kodlarmza geebiliriz. Bu blmde adm adm ilerleyeceiz. Menlerdeki tm


balklarn olaylarn yazacaz.

1)Genel deikenimizi tanmlama


Bu programda Degisim adnda, bool yani sadece true ve false deerleri alabilen bir
deiken tanmladm. Bu deiken sayesinde kullancy metinin deiip deimedii
konusunda uyaracaz, bylece isterse deien metni kayt imkan vereceiz

private bool Degisim;

2)Form1in onLoad Olay


Bu olay programmzn alnda yrtlen olaydr. Burada objSave ve objOpen iin baz
ayarlar yapyoruz ve gstermesini istediimiz dosyalarn uzantlarn giriyoruz.

private void Form1_Load(object sender, System.EventArgs e)


{
objOpen.Filter = "Text Dosyalar(*.txt)|*.txt|Tm Dosylar(*.*)|*.*" ;
objOpen.FilterIndex = 1 ;
objSave.Filter = "Text Dosyalar(*.txt)|*.txt|Tm Dosyalar(*.*)|*.*" ;
objSave.FilterIndex = 1 ;
}

3)Kullanlacak metotlarn tanmlanmas


Ben bu programda sadece 2 tane metot tanmladm. Bunlardan birincisi
KayitMekanizmasi, dieri DegisimUyari . KayitMekanizmasi ad stnde yazdklarmz
kaydedecek olan mekanizma, DegisimUyari ise objText iindeki metnin deiimi durumda
program kapatrken falan bize haber verecek olan kod.

public void KayitMekanizmasi(string strVeri)


{
if (objSave.ShowDialog() == DialogResult.OK)
{
StreamWriter Kayitci = new
StreamWriter(Environment.GetEnvironmentVariable("mydocuments")
+objSave.FileName.ToString(),false,System.Text.Encoding.Unicode);
Kayitci.Write(strVeri);
Kayitci.Close();
Degisim = false;
}
}

nce yukardaki kodu biraz inceleyelim. Burada nce bi if kontrol gryorsunuz. Bu


kontroln amac, Kayt ekran ald zaman kullanc OK dmesine tklayp
tklamadn kontrol etmek. Eer OKe tklad ise programmz bir adet StreamWriter
oluturuyor. Kayitci adndaki bu Writer
Environment.GetEnvironmentVariable("mydocuments) bu kod ile ayarl olan Belgelerim
klasrne gidiyor otomatik olarak. objSave.FileName ise bizim Kayt Ekrann da dosyaya
verdiimiz ismi bize dndryor. Son olarak ise bu satrda Unicode bir kodlama
yaptmz gsteriyoruz. Bunu yazmazsanz Trke karakterlerinizin yerinde yeller estiini
grrsnz.

Kayitci.Write(strVeri) satr ile gelen veriyi kaydediyor ve StreamWriter nesnesini


kapatyor. Degisim deerini ise true olarak atyor. Bunun nedeni deiim oldu ve ben
bunu grdm demek. Kullancya haber vermeye gerek yok anlamna gelecek.
imdi devam edelim.

public bool DegisimUyari()


{
if (MessageBox.Show("Dosyanzda bir deiiklik oldu kaydetmek ister
misiniz?","Deiiklik Var",MessageBoxButtons.YesNo,MessageBoxIcon.Exclamation) ==
DialogResult.Yes)
{
return true;
}
else

{
Degisim = false;
return false;
}

Yukardaki kodda ise tipik bir MessageBox kullanm gryorsunuz. Buradaki metodumuz
birde deer dndryor.Bir bool deeri dndryor. Bu dnen deer ile biz az sonra
kullancnn kan mesaj kutusunda dosyay kaydetmek isteyip istemediini anlayacaz.

MessageBox.Show("Dosyanzda bir deiiklik oldu kaydetmek ister misiniz?","Deiiklik


Var",MessageBoxButtons.YesNo,MessageBoxIcon.Exclamation) == DialogResult.Yes)

Bu satr biraz incelemek lazm. Burada ilk overload (Overload metodlara parantezler
iinde yollanan veri demek.) mesaj kutusunda grnecek olan yaz, ikinicisi bu mesaj
kutusunun bal, ncs mesaj kutusu zerinde ki Evet, Hayr dmeleri ve son
olarak mesaj kutusundaki simge. Ancak kodlara bakmaya devam ettiimizde bir
karlatrma gryoruz (== ifadesi) DialogResult.Yes , aslnda aklamaya bile gerek
yok. Eer kullanc Evete tklad ise demek. Asl kodlarda bu durumda bir true ifadesi
dndrldn grebilirsiniz. Biz daha sonra bunu kontrol ederek KayitMekanizmasi
metodumuzu aracaz.

4) Yeni dmesi
Menmzdeki Yeni dmesine tkladmzda olacak olaylar gireceiz. Bunun iin bu
dmeye Designerdan ift tklaynz.

private void menuItem2_Click(object sender, System.EventArgs e)


{
if (Degisim == false)
{
objText.Clear();

}
else
{
if (DegisimUyari())
{
KayitMekanizmasi(objText.Text);
objText.Clear();
Degisim = false;
}
else
{
objText.Clear();
Degisim = false;
}
}
}

Burada nce Degisim deerini kontrol ediyoruz. Eer deer false ise yani deiim yoksa
ya bu dosya nceden kaydedilmitir ya da yeni almtr. O zaman ieriinin
temizlenmesinde bir sorun yok.

Eer deer true ise biraz karyor ortalk. nce kullancy uyarmak iin DegisimUyari()
altrlyor. Eer kullanc kayt etmek istiyorsa, KayitMekanizmasi() altrlyor, ekran
temizleniyor ve Degisim deeri false oluyor.Eer kullanc kayt etmek istemiyorsa ierik
temizleniyor ve Degisim deeri yine false oluyor. Bylece yeni bir dosya ama ilemlerini
hallettik.

5) Varolan dosyay ama

Metin editrnz ile daha nce var olan bir dosyay amak istersiniz diye byle bir zellik
ekledik birde. Menmzde Aa ift tklayn ve tklama olayna aadaki kodlar girin.

private void menuItem3_Click(object sender, System.EventArgs e)


{
if (Degisim == true)
{
if (DegisimUyari())
{
KayitMekanizmasi(objText.Text);
}
}
if (objOpen.ShowDialog() == DialogResult.OK)
{

FileInfo strKaynak = new


FileInfo(Environment.GetEnvironmentVariable("mydocuments")
+objOpen.FileName.ToString());
StreamReader Okuyucu = strKaynak.OpenText();

objText.Text = Okuyucu.ReadToEnd();
Degisim = false;
Okuyucu.Close();
}
}

Bu kodlarda da nce deiim var m diye bakyoruz. Yani amacmz kullancnn yazd
metni yanllkla bast bir dme yznden kaybetmesini engellemek. Eer deiim
varsa ve uyardan true deeri dnerse kaydediyoruz, aksi halde herhangi bir ey
yapmyoruz.

Bundan sonra yukarda SaveFileDialog iin yaptmz benzer eyleri yapyoruz. Yani
.ShowDialog() metodunu aryoruz. Kullanc OKe tklaynca kodlarmz devam ediyor.
Ancak burada yukardakinden farkl kodlar var. Dosya okumak iin ok farkl yntemler
var. Yazmak iinde tabi ki. Mesela StreamWritern StreamReader da var ve ben burada
bunu kullandm. Eer kodlar incelerseniz biraz farkl olduunu greceksiniz. nk
burada FileInfo diye de bir ey var. FileInfo bu tr dosya ilemcilerine yardmc olur.
strKaynak deikenine atadmz nesnemizde StreamWriter daki gibi path gsterip
dosyamz ayoruz. Burada objOpen.FileNameden gelen veri, kullancnn amak istedii
dosya.

StreamReader nesnesini de oluturup strKaynak.OpenText() ile metin dosyamz ayoruz.


Yalnz burada bir noktaya dikkat ekmek istiyorum. Ben burada alacak dosyann bir .txt
dosyas olduunu bildiim iin .OpenTexti kullandm. Yoksa baka versiyonlar da
mevcut. Bu nesneyi de oluturduktan sonra objTexte Okuyucu.ReadToEnd ile batan
sonra tm veriyi okuyup aktaryoruz. Deiimden haberimiz olduunu programa bildirip,
nesnelerimizi kapatyoruz

6) Kaydet dmesi

Kullanc almasn kaydetmek istedii zaman bu dmeye tklayabilir. ok ksa bir kodu
var. Zaten asl ii yapan KayitMekanizmasi(), biz sadece onu aracaz imdi.

private void menuItem4_Click(object sender, System.EventArgs e)


{
KayitMekanizmasi(objText.Text);
Degisim = false;
}

Burada aklanacak bir kod yok. Grdnz gibi

7) Kapat Dmesi

Kullanc program kapatmak isteyebilir ve bunun iin Dosya mensndeki Kapat


dmesini kullanabilir. O zaman bu dmeye de bir olay atamamz lazm. imdi ift
tklayn ve aadaki kodlar yazn.

private void menuItem6_Click(object sender, System.EventArgs e)


{
Close();
}

Bu kod ok basit. Sadece Close() metodunu aryor. Bu zel tanml bir metodur ve o
form penceresinin kapanmasn salar. imdi aklnza gelebilir ya ieride kaydedilmemi
veri varsa hi kontrol etmedik. O zaman biraz sabr, ona da bakacaz

8) Kapanmadan nce kontrol


Kullancmz program ok farkl ekillerde kapatabilir. Alt + F4 kombinasyonu, kedeki X
ile kapatabilir ya da Kapat dmemize tklar;ancak az nce de dediimiz gibi ya ieride
veri varsa. O zaman bu veri iin bi kontrol yapmamz lazm. Formlarn Closing adnda
olaylar vardr. Bu form kapatlmadan hemen nce yaplacaklar belirler. Biz buna baz
olaylar atyoruz imdi.

private void Form1_Closing(object sender,


System.ComponentModel.CancelEventArgs e)
{
if (Degisim == true)
{
if (DegisimUyari())
{
KayitMekanizmasi(objText.Text);
Close();

}
}
else
{
Close();
}
}

Burada yaplanlardan farkl olan hi bir ey yok. Degisim deerini kontrol ediyoruz ve ona
gre ilem yapyoruz..

9) Son bir metod

Asl en nemli eyi yapmadk sanyorum. rnein kullanc programa bir veri girdiinde
yani herhangi bi yaz yazdnda Degisim deeri deimedi. O zaman bunu halledelim.
objTextin TextChanged adnda bir olay var. imdi o olay kodlar iine aadaki tek
satrlk kodu yazyoruz.

private void objText_TextChanged(object sender, System.EventArgs e)


{
Degisim = true;
}

Evet, bylece olayn i yapan ksm bitti..

Ancak menlerimiz arasnda hi ilgilenmediimiz bir dme var. Hakknda. Bu aslnda en


gereksiz ey belki ama bir programcnn en ok nemsedii blm :). Bunun iin basit bir
form yaratnz. Ben aadaki formu oluturdum ve adn hakkinda yaptm.
Burada altta iki tane de link var. Biri MaxiASP.Com a biri MaxiASP.Nete ynlenmi
durumda. Bunlara tklandnda taraycmzn alp sitelere gitmemizi salayacak kodlarda
aada.

private void linkLabel1_LinkClicked(object sender,


System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.maxiasp.com");
}

private void linkLabel2_LinkClicked(object sender,


System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.maxiasp.net");

Gerekten ok uzun bir yaz oldu. Eer her ey yolunda gitti ise u an canavar gibi alan
bir Basit Not Defteriniz var. Baka yazlarda grmek zere.
C#'n Gelecekteki zellikleri

Bildiiniz gibi C# dili 2001 ylnda Microsoft tarafndan karlan ve nesne ynelimli
programlama tekniine %100 destek veren bir programlama dilidir. C#, programclara
sunulduundan beri bir ok programcnn dikkatini ekmitir. Bu ilgide en nemli neden
herhalde C# dilinin kendinden nce karlm olan JAVA ve C++ dillerini rnek almasdr.
Evet C# modern an gerektirdii btn yazlm bileenlerini iermekle beraber eski
programlama dillerinde bulunan iyi zellikleri de yapsnda barndrmaktadr. Microsoft ve
C# dil tasarmclar her geen gn yeni piyasa aratrmalar yaparak dile katabilecekleri
zellikleri tartmaktadrlar. Bu amala C# dilinin tasarmclar yakn bir zaman iinde C#
diline eklemeyi dndkleri yeni zellikleri bildirmilerdir. Bu yazda muhtemelen
"VS.NET for Yukon(VS.NET Everett'ten sonraki versiyon)" ile birlikte uygulamaya
konulacak C# dilinin muhtemel zelliklerini zetlemeye alacam. Bu bildirinin
tamamn C# topluluunun resmi sitesi olan www.csharp.net adresinden okuyabilirsiniz.

C# diline yakn bir zamanda eklenilmesi dnlen zellikler 4 ana balk altnda
toplanmtr. Bu zellikler temel olarak aadaki gibidir.

1 - Generics (Soysal Trler)

2 - Iterators

3 - Anonymous Methods (simsiz-Anonim- Metotlar)

4 - Partial Types (Ksmi Trler)

Bu yazda yukarda balklar halinde verilen her bir konuyu ayrntl olarak inceleyip,
programcya ne gibi faydalar salayabileceini ve programlarn performansna nasl etki
edeceine deineceim.

1 - Generics

Profesyonel programlamada, trden bamsz algoritma gelitirme nemli bir tekniktir.


Trden bamsz algoritmalar gelitirici iin byk kolaylklar salamaktadr. Sz gelimi iki
int trden saynn toplanmasnn salayan bir fonksiyonu yazdktan sonra ayn ilemi iki
double trden say iin tekrarlamak zaman kaybna sebep olacaktr. C++ dilinde trden
bamsz algoritma kurabilmek iin ablon(template) fonksiyonlar ve ablon snflar
kullanlmaktadr. C#, trden bamsz algoritma gelitirmeye dorudan destek vermiyor
olsada dolayl yollardan trden bamsz ilemler yapabilmek mmkndr. Bu ilemler
C#'ta "Her ey bir Object'tir" cmlesinin altnda yatan gerekle halledilmektedir. C#'ta
hereyin bir nesne olmas ve her nesnenin ortak bir atasnn olmas ve bu atann da
Object snf olmas bu cmlenin altnda yatan gerektir. Dolaysyla herhangi bir tre ait
referans Object referasnlarna ataybiliriz. Yani bir bakma trden bamsz bir ilem
gerekletirmi oluyoruz. Sze gelimi Object trnden bir parametre alan bir fonksiyonu
dilediimiz bir nesne referans geebiliriz. Temel(base) snfa ait referanslara
treyen(inherited) snf referanslarn ataybilmek nesne ynelimli programlama tekniinin
sunduu bir imkandr.

C#'ta Object referanslarna istenilen trden referanslar atanabilir. Bu, byk bir imkan
gibi grnsede aslnda baz dezavantajlarda beraberinde getiriyor. nk alma
zamannda Object trne atanm referanslar orjinal tre tekrar geri dntrlmektedir.
Ksaca unboxing olarak bilinen bu ilem zellikle deer(value) ve referans(reference)
trleri arasnda yapldnda nemsenecek byklkte bir performans kayb meydana
gelmektedir. nk deer ve referans trleri bellein farkl blgelerinde saklanmaktadr.
Bu durum boxing ve unboxing ilemlerinin alma zamannda farkl bellek blgeleri
arasnda uzun srebilecek veri transferlerine sebep olur. Bu tr bir performans kaybn
baz veri yaplar iin nlemek iin C# dil tasarmclar Generics isimli bi kavramn dile
eklenmesini ngrmlerdir. Bu sayede baz veri yaplarnda zellikle .NET snf
kyphanesindeki System.Collections isim alannda bulunan veri yaplarnda epeyce
performans kazanc elde edilecektir.

sterseniz basit bir yn(stack) snf zerinden "generics" kavramnn salayaca yaralar
ve boxing/unboxing ilemlerinin etkisini inceleyelim.

.NET snf ktphanesinde de bulunan Stack snf iinde her trden veri bulunduran ve
istenildiinde bu verilere FIFO(lk giren ilk kar) algoritmasna gre veri ekilebilen bir
veri yapsdr. .NET'teki Stack snf ile btn veri trlerine ait ilemleri yapabilmek iin
Stack snfndaki veri yaps Object olarak seilmitir. Eer bu byle olmasayd Stack
snfnn her bir tr iin ayr ayr yazlmas gerekecekti. Bu mmkn olsa bile herey
bitmi olmayacakt. nk Stack snf kullancn tanmlayaca trleri barndracak
duruma gelmez. te btn bu sebeplerden dolay Stack veri yapsnda saklanan veriler
Object olarak seilmitir. Buna gre Stack snfnn arayz aadaki gibidir.

class Stack
{
private int current_index;
private object[] elemanlar = new object[100];

public void Push(object veri)


{
.
.
elemanlar[current_index] = veri;
.
.
}

public object Pop()


{
.
.
return elemanlar[current_index];
.
.
}
}

Bildirilen bu Stack snfnn eleman Object trnden olduu iin Push() metodu ile
istediimiz trden veriyi saklayabiliriz. Ayn ekilde Pop() metodu ile bir veri ekilecei
zaman veri Object trnden olacaktr. Pop() metodu ile elde edilen verinin gerek tr
belli olmad iin tr dntrme operatr kullanlr. rnein,

Push(3);

eklinde yna eklenen veriyi tekrar elde etmek iin

int a = (int)Pop();

biiminde bir tr dnm yapmamz gerekir. Bu ilemler kendi tanmlayacamz zel


snflar iinde geerlidir. Ancak int ve double gibi temel veri trlerindeki performans kayb
daha fazladr. nk Push(3) eklindeki bir armda boxing ilemi gerekleirken Pop()
metodunun arlmasnda unboxing ilemi gerekleir. stelik bu durumda Pop()
metodunun geri dn deerini byte trne dntrmeye alrsak derleme zamannda
herhangi bir hata almayz. Bu da alma zamannda haberimiz olmadan baz veri
kayplarnn olabileceini gsterir. Kullanc tanml snflar ilgili bir yn kullanyorsak
Pop() metodunun geri dn deerini farkl bir kullanc tanml snfa aviriyorsak bu
sefer de derleme zamannda hata alnmaz, ancak alma zamannda "invalid cast
operation" istisnai durumu meydana gelir.

Btn eksi durumlardan kurtulmak iin generics(soysal tr)'lerden faydalanlabilir. Soysal


trler C++ dilindeki ablon snflarnn bildirimi ile benzerdir. Bu tr snf bildirimlerine
parametreli tip de denilmektedir. Parametreli tipler aadaki gibi bildirilir.

class Stack
{
private int current_index;
private Veri tr[] elemanlar;

public void Push(Veri tr veri)


{
.
.
elemanlar[current_index] = veri;
.
.
}

public Veri tr Pop()


{
.
.
return elemanlar[current_index];
.
.
}
}
ile stack snfnn hangi trden verileri tutaca stack nesnesini oluturacak programcya
braklmtr. rnein int trden verileri saklayacak bir yn aadaki gibi oluturulur.

Stack<int> ygn = new Stack<int>;

Yukardaki ekilde bir ygn olutrulduunda Stack snfnun bildirimindeki Veri tr


ifadeleri int tr olarak ele alnacaktr. Dolaysyla Pop() metodu ile yndan bir eleman
karlp aadaki gibi baka bir deikene atanmak istendiinde tr dntrme
operatrn kullanmaya gerek yoktur. Bu da boxing ve unboxing ilemlerinin
gereklemedii anlamna gelir ki istediimiz de buydu zaten.

Stack<int> ygn = new Stack<int>;

ygn.Push(3); // Boxing ilemi gereklemez.

int a = ygn.Pop(); //Unboxing ilemi gereklemez.

Ayn ekilde ynmzn double trden verileri saklamasn istiyorsak int yerine double
kullanmalyz. Bu durumda alma zamannda hem int hem de double verileri tutan yn
snflar oluturulacaktr. Biz tek bir yn snf bildirmi olmamza ramen alma zaman
bizim iin ayr iki yn snf oluturur.

Soysal trleri kendi tanmladmz snflar iinde oluturabiliriz. rnein Musteri isimli bir
snfn verilerini ynda tutmak iin yn snfn aadaki gibi oluturmalyz.

Stack ygn = new Stack;

Bu durumda yna sadece Musteri nesneleri eklenebilir. Yani ygn.Push(3) eklindeki bir
kullanm derleme aamasnda hata verecektir. Ayn zamanda yndan ekilecek veriler de
Musteri trndendir. Dolaysyla tr dnm uygun trler arasnda olmaldr.

Yn snf yukarda anlatlan ekilde kullanldnda yndaki elemanlarn belirli bir trden
olduu garanti altna alnr. Bylece Musteri trnden nesneleri tutan bir yna "3" gibi
bir sayy ekleyemeyeceimiz iin daha gereki programlar yazlr.

Stack rneinde sadece bri tane parametre tr kullandk. Soysal trlerde istenilen
sayda parametreli tr kullanlabilir. rnein Hashtable snfnndaki Deger ve Anahtar
ikilisi aadaki gibi parametreli tr olarak bildirilebilir.

public class Hashtable


{
public void Add(AnahtarTuru anahtar, DegerTuru deger)
{
.....
}

public DegerTuru this[AnahtarTuru anahtar]


{
.....
}
}
Yani bir Hashtable nesnesi oluturulaca zaman her iki parametre tr de belirtilmelidir.
rnein Anahtar tr int olan ve deer tr Musteri snf olan bir Hashtable nesnesi
aadaki gibi oluturulabilir.

Hashtable<int,Musteri> hashtable = new Hashtable<int,Musteri>;

Not : Parametre saysn aralarna virgl koyarak dilediimiz kadar artrabiliriz.

Soysal trlerin saydmz avantajlarnn yannda bu haliyle baz dezavantajlar ve


kstlamalarda vardr. Sz gelimi Hashtable snfnn bildirimi iinde AnahtarTuru verisinin
baz elemanlarn bir ifade de kullanmak istiyoruz; derleyici hangi AnahtarTuru
parametrelei trnn hangi trden olduunu bilmedii iin bu durumda sadece Object
snfnn ait metotlar ve zellikler kullanlabilir. Mesela Hashtable snfnn Add metodu
iinde anahtar parametresi ile CompareTo() metodunu kullanmak istiyorsak CompareTo
metodunun bildirildii IComparable arayzn kullanarak aadaki gibi tr dnm
yapmalyz.

public class Hashtable


{
public void Add(AnahtarTuru anahtar, DegerTuru deger)
{
switch(((IComparable)anahtar).CompareTo(x))
{

}
}
}

Hashtable snfnn Add() metodu yulardaki ekilde bildirilse bile hala eksik noktalar var.
Mesela AnahtarTuru parametresi eer gerekten IComparable arayzn uygulamyorsa
switch ifadesi iinde yaplan tr dnm geersiz olacaktr ve alma zamannda hata
oluacaktr. alma zamannda meydana gelebilecek bu tr hatalar nlemek iin
yaplabilecek tek ey AnahtarTuuru parametresinin IComparable arayzn uyguluyor
olmasn zorlamaktr. Bu ilemi yapmak iin AnahtarTuru parametresine eitli
kstlar(constraints) getirilir. Aadaki Hashtable snfnda AnahtarTuru parametresinin
IComparable arayzn uygulamas gerektii sylenmektedir. Bu kst iin where
anahtar szc kullanlr.

public class Hashtable<AnahtarTuru, DegerTuru> where AnahtarTuru : IComparable


{
public void Add(AnahtarTuru anahtar, DegerTuru deger)
{
switch(anahtar.CompareTo(x))
{

}
}
}

Dikkat ettiyseniz uygulanan ksttan sonra switch ifadesi iinde anahtar deikeni
zerinde tr dnm ilemi yapmaya gerek kalmamtr. stelik kaynak kodun
herhangi bir noktasnda Hashtable nesnesini IComparable arayzn uygulamayan bir
AnahtarTuru parametresi ile oluturursak bu sefer ki hata derleme zamannda
oluacaktr.
Not : parametreli trler zerindeki kst sadece arayz olmak zorunda deildir. Arayz
yerine snflar da kst olarak kullanlabilir.

Bir parametreli tre birden fazla arayz kst konabilecei gibi ayn snftaki dier
parametreleri trler iin de kst konulabilir. Ancak bir parametreli tr iin ancak sadece
bir tane snf kst olabilir. rnein aadaki Hashtable snfnda DegerTuru Musteri
snfndan tremi olmas gerekirken, AnahtarTuru hem IComparable hemde IEnumerable
arayzn uygulam olmas gerekir.

public class Hashtable<AnahtarTuru, DegerTuru> where


AnahtarTuru : IComparable
AnahtarTuru : IEnumerable
DegerTuru : Musteri
{
public void Add(AnahtarTuru anahtar, DegerTuru deger)
{
switch(anahtar.CompareTo(x))
{

}
}
}

2 - Iterators

Bir dizinin elemanlar zerinde tek tek dolama ilemine iterasyon denilmektedir.
Koleksiyon tabanl nesnelerin elemanlar arasnda tek ynl dolamay salayan foreach
dng yapsnn bizim tanmlayacamz snflar iin de kullanlabilmesi iin snfmzn baz
arayzleri uyguluyor olmas gerekir. foreach dngs derleme ilemi srasnda while
dngsne dntrlr. Bu dntrme ilemi iin IEnumerator arayzndeki
metotlardan ve zelliklerden faydalanlmaktadr. Bu dntrme ileminin nasl
yapldna bakacak olursak :

ArrayList alist = new ArrayList();

foreach(object o in alist)
{
BiseylerYap(o);
}

// Yukardaki foreach blounun karl aadaki gibidir.

Enumerator e = alist.GetEnumerator();

while(e.MoveNext())
{
object o = e.Current
BiseylerYap(o);
}

foreach dngs yaps iin gerekli olan arayzlerin uygulanmas zellikle aa yaps
eklindeki veri trleri iin olduka zordur. Bu yzden C# snflarn foreach yaps ile nasl
kullanlacana karar vermek iin yeni bir yap kullanacaktr.
Snflarda, foreach anahtar kelimesi bir metot ismi gibi kullanlarak snfn foreach
dngsnde nasl davranacan bildirebilriz. Her bir iterasyon sonucu geri dndrlecek
deeri ise yield anahtar szc ile belirtilir. rnein her bir iterasyonda farkl bir
tamsay deeri elde etmek iin snf bildirimi aadaki gibi yaplabilir.

public class Snf


{
public int foreach()
{
yield 3;
yield 4;
yield 5;
}
}

Yukarda bildirilen Snf trnden nesneler zerinde foreach dngs kullanldnda


iterasyonlarda srasyla 3,4 ve 5 saylar elde edilecektir. Buna gre aadaki kod paras
ekrana 345 yazacaktr.

Snf deneme = new Snf();

foreach(int eleman in deneme)


{
Console.Write(eleman);
}

ou durumda foreach yaps ile snfmzn iindeki bir dizi zerinde iteratif bir ekilde
dolamak isteyeceiz. Bu durumda foreach bildirimi iinde ayr bir foreach dngs
aadaki gibi kullanlabilir.

public class Snf


{
private int[] elemanlar;

public int foreach()


{
foreach(int eleman in elemanlar)
{
yield eleman;
}
}
}

Yukardaki Snf nesneler ile foreach dngs kullanldnda her bir iterasyonda
elemanlar dizisinin bir sonraki elemanna ulalr.

Grdnz gibi programcnn bildirecei snflar da foreach dngs yapsn


kullanabilmek iin eskiden olduu gibi IEnumerator arayzn uygulamaya gerek
kalmamtr. Bu ilemi derleyici bizim yerimize yapar.

3 - Anonymous Metotlar(simsiz Metotlar)

simsiz metotlar, bir temsilciye ilikin kod bloklarn emsil eder. Bildiiniz gibi temsilciler
yapsnda metot referasn tutan veri yaplardr. Bir temsilci arm yapldnda
temsilcinin temsil ettii metot altrlr. zellikle grsel arayzl programlar yazarken
event tabanl programlama teknii kullanlrken temsilcilerin kullanmna ska rastlanr.
rnein bir Button nesnesine tklandnda belirli bir kod kmesinin(metot) altrlmas
iin temsilci veri yapsndan faydalanlr. Szgelimi Button nesnesinin tklanma olay
meydana geldiinde Click isimli temsilcisine yeni bir temsilci atanr. Ne zaman button
nesnesinin Click olay gereklese ardndan hemen temsilcinin temsil ettii metot arlr.
Buna bir rnek verecek olursak;

public class Form


{
Button dugme;

public Form
{
dugme = new Button();
dugme.Click += new EventHandler(OnClick);
}

void OnClick(object sender, EventArgs e)


{
....
}
}

Yukardaki koddan da grld zere temsilci ile temsilcinin temsil ettii metotlar ayr
yerlerdedir. simsiz metotlarla bu ilemi biraz daha basitletirmek mmkndr. Temsilci
oluturulduktan sonra alan ve kapanan parantezler arasna temsilci arldnda
altrlacak kodlar yazlabilir. Yukardaki rnei isimsiz metot ile yapacak olursak :

public class Form


{
Button dugme;

public Form
{
dugme = new Button();
dugme.Click += new EventHandler(object sender, EventArgs e);
{
//altrlacak kodlar.
};
}

Tanmlanan kod bloundan sonra noktal vrgln eklenmi olduuna dikkat edin.
Temsilci bloundaki kodlar normal metotlardan biraz farkldr. Normal kod bloklar ile
benzer zellikler tar. Yukardaki temsilci kod blounda, blok dnda tanmlanan
deikenlere eriebilmek mmkndr. Ayrca olay argmanlarnn da(sender,e)
EventHandler trnn parantezleri iinde yazldnda dikkat edin. Bir nceki versiyonda
olay argmanlarnn yerine temsil edilen metodun ismi yazlmt.

Peki isimsiz metotlar nasl altrlmaktadr? simsiz metot tanm ile karlaan derleyici
tekil isme sahip bir snf iinde tekil isme sahip bir metot oluturur ve isimsiz metot
gvdesindeki kodlara bu tekil metot iinden eriilir. Temsilci nesnesi arldnda,
derleyicinin rettii bu metot ile isimsiz metodun bloundaki kodlar altrlr.
4 - Partial Types (Ksmi Trler)

Ksmi trler yardmyla bir snfn elemanlarn farkl dosyalarda saklamak mmkndr.
rnein Dosya1.cs ve Dosya2.cs aadaki gibi olsun.

//Dosya1.cs

public partial class deneme


{
public void Metot1
{
...
}

//Dosya2.cs

public partial class deneme


{
public void Metot2
{
...
}

Yukardaki iki dosyay ayn anda derlediimizde eer ksmi trler kavram olmasayd
derleme zamannda hata alrdrk. nk ayn isim alannda birden fazla ayn isimli snf
bildirimi yaplm. Halbuki ksmi trler ile bu iki snf bildirimi ayn snf olarak ele alnr, ve
birletirilir. Yani deneme isimli snfn Metot1() ve Metot2() adnda iki tane metodu olmu
olur.

Bir tre ait elemanlar tek bir dosya iinde toplamak Nesne Ynelimli Programlama
asndan her ne kadar nemli olsada bazen farkl dosyalarla almak kodlarmzn
ynetilebilirliini artrabilmektedir.

Not : Bu yaz "MSDN Magazine" deki "Future Features of C#" balkla bildiri baz alnarak
hazrlanmtr.
Kaynak Kodunuzu XML ile Ssleyin

Byk yazlm projelerinde en nemli aktivitelerden birisi proje baznda iyi bir
dkmantasyon yapmaktr; proje analiz srecindeki dkmantasyon genellikle standart
olan UML diyagramlar ile yaplmaktadr, tabi iin bir de gelitiriciye bakan taraf vardr.
Projenin en nihayi sonu kod yazmak olduuna gre kodlarn dkmantasyonu da en az
analiz srecindeki dkmantasyon kadar nemlidir. Bu yazda .NET ile birlikte n plana
kan XML yorum format ile kodlarmz nasl dkmante edebileceimizi inceleyeceiz.

Bildiiniz gibi kodlarmza yorum satr koymamzdaki en byk ama kodlarn bakas
tarafndan kolaylkla anlalabilir hale gelmesini salamaktr. Bazen bu ilemi kendimiz
iinde yapmak durumunda kalabiliriz, zira bir ok karmak uygulamada yazdmz
kaynak koda yllar sonra belkide aylar sonra baktmzda vakt-i zamannda neler
dndmz hemen aklmza gelmeyebilir. Bu durumda en byk yardmcmz o
zamanlar tembellik etmeden yazdmz yorum satrlar olacaktr. Eer kendinize yorum
satr ekleme alkanln kazandrrsanz bunun getirisini ileride mutlaka greceksiniz.
Peki ne kadar yorum satr gereklidir? Bu sorunun cevab size ve yazdnz kodlarn
karmaklna gre deiir. Eer iir gibi kod yazyorum diyorsanz belkide bir cmlelik
yorum satr iinizi grebilir, yok arap sa gibi kod yazyorum diyorsanz belkide
yazdnz kod satr saysndan daha fazla yorum yazmak zorunda kalabilirsiniz.

.NET bir ok meselede olduu gibi yorum ekleme mekanizmasn da estetik bir ekilde
zmtr. ok deil daha bir ka yl ncesine kadar kaynak kodlarmzdaki yorum
satrlar // ve /* */karekterleri ile belirtiliyordu. .NET bu eski yorum yazma eklini
desteklemekle birlikte XML formatndaki yorum ekleme mekanizmasyla n plana
kmaktadr. XML sayesinde artk kodlarmzdaki yorumlar standart hale getirilmitir.
Bylece bir XML yorumunda belirli bir etiketi grdmzde o etiketin iindeki
aklamann neyi ifade ettiini anlarz. Ayn zamanda VS.NET kodlarmzdaki XML
yorumlarn ayrtrarak saf bir XML dosyas da retebilmektedir. Bu sayede XML
formatndaki yorum dosyasn istediimiz sistem ile rahatlkla entegre edebilirz, sz gelimi
proje yneticisine XML dosyasndaki yorum bilgilerini HTML formatnda sunabiliriz.

XML Yorum Satrlar

C#'ta XML yorum satrlar " /// (3 adet slash karakteri) " ile balayan satrlarda yazlr.
nceden belirlenmi bir takm standart XML etiketleri vardr, yleki bu etiketler ayn
zamanda ECMA tarafndan da standart olarak kabul edilmitir. Ancak XML etiketlerini
programc istedii ekilde irketin ihtiyalarna yada kendi ihtiyalarna gre geniletebilir.
XML yorum yazmadaki belkide tek kst XML szdizimine uyma artdr. XML szdizimine
gre alan btn etiketler kapanmaldr.

En ok kullanlan nceden tanml XML etiketleri <param>, <remarks>, <summary>


ve <returns> etiketleridir. Bu etiketlerin bazlar intellisense ve "Object Browser"
program tarafndan kullanlmaktadr. rnein VS.NET editrnde bir nesne yaratldnda
nesne trne ait yapc metottaki parametrelerin ksa aklamas editr penceresinde
gsterilir. Ayn ekilde kendi yazdmz snflar iinde bu aklamalarn kmasn
istiyorsak XML yorum etiketlerini kullanmamz gerekir.

XML yorum etiketleri tr baznda, metot baznda ve parametre baznda olabilir. Tr


baznda yorum ekleme ilemi snflar, temcilciler, indeksleyiciler, olaylar,
numaralandrmalar(enums) ve yaplar(struct) iin uygulanabilir. Metot bazndaki yorumlar
herhangi bir metodun bildiriminden nce yaplr. Parametre bazndaki yorumlar ise bir
metodun parametreleri ve geri dn deerleri ile ilgilidir.

Aklayc olmas asndan rnek bir snf zerinde XML yorumlarn ve VS.NET gibi akll
editrlerde bu yorumlarn ne gibi etkilerinin olduunu inceleyelim.

imdi yeni bir "Class Library" projesi ap aadaki snf bildirimini yazn.

using System;

namespace XMLYorum
{
///<summary>
/// Cebir sinifi bazi zel matematiksel islemleri
/// yapmak iin esitli statik metotlar sunar.
///</summary>
public class Cebir
{
/// <remarks>
/// Mutlak Deger Alma Islemi
///</remarks>
///<summary>
/// Parametre olarak gelen sayinin
/// Mutlak Degerini alir.
///</summary>
///<param name="Deger">Mutlak Degeri alinacak sayi.</param>
///<returns>Paremetre olarak gelen sayinin mutlak degeri.</returns>
public static int MutlakDeger(int Deger)
{
if(Deger < 0)
return -Deger;
else
return Deger;
}

/// <remarks>
/// Kare Alma Islemi
///</remarks>
///<summary>
/// Parametre olarak gelen sayinin
/// karesini almak iin kullanilir.
///</summary>
///<param name="Deger">Karesi alinacak sayi.</param>
///<returns>Parametre olarak gelen sayinin karesi.</returns>
public static double KareAl(double Deger)
{
return Deger * Deger;
}
}
}
Yukardaki rnek koddan grld zere snf ve metot bildirimlerinden nce /// ile
balayan satrlarda XML formatnda yorumlar yazlmtr.VS.NET kod editr ///
karakterinden sonra <summary>, <param name="Deger"> ve <returns> etiketlerini
otomatik oluturdu. <remarks> etiketini ise kendimiz yazmalyz. XML yorum etiketleri de
intellisense zelliklerinden faydalanr. Otomatik tamamlama ilemi etiketler iinde
geerlidir.

Yukardaki rnekte <remarks> etiketi ile snf yada metod ile ilgili ksa bir aklama
yaplr. <summary> etiketi iinde daha ayrntl bilgi verilir. Gerekirse eitli teknik bilgiler
de bu etiket iinde belirtilir.

imdi C# derleyicisinin XML formatndaki yorumlar kaynak koddan ne ekilde ayrdn


grmek iin projeyi derleyelim. Projeyi derlemeden nce eer VS.NET kulllanyorsanz
Proje zellikleri(Solutin Explorer'a sa tklayarak grebilirsiniz) penceresinden
"Configuration Properties/Build" sekmesinin altndaki "XML Documentation File" kutusuna
oluturulacak XML dosyasnn ismini aadaki gibi yazmalsnz. Tabi VS.NET editrnn
intellisense zelliklerinden faydalanmak istiyorsak XML dosyasnn ismini oluturulacak
DLL ismiyle ayn verilmeliyiz.

Eer VS.NET gibi akll bir editrnz yoksa .NET Framework ile birlikte cretsiz olarak
datlan ve komut satrndan altrlabilen C# derleyicisini kullanarak ta XML yorum
dosyalarn oluturabilirsiniz. Bunun iin yapmanz gereken csc derleyicisini komut
satrndan aadaki gibi altrmaktr.

csc /t:library /doc:XmlYorum.xml XmlYorum.cs

VS.NET yada C# komut satr ile oluturulan XML dosyasnn yaps aadaki gibidir.
imdi birde oluturduumuz Cebir isimli bir snfa farkl bir projeden referans verip
metotlarn kullanalm. Yeni bir Console uygulamas an ve oluturduumuz Cebir snfna
ait assembly dosyasna referans verin. Eer komut satr derleyicisi ile alyorsanz "
/r:Cebir.dll " parametresini ekleyin. Tabi bu durumda XML yorumlarnn etkisini
gremeyeceksiniz. nk XML yorumlarn gstermek VS.NET teki akll editrn bir
yeteneidir. Notepad'in yada baka text editrlerinden bu tr imkanlar beklememek
lazm!

Cebir snfnn KareAl() metodunu kullanmak istediimizde VS.NET'teki kod editr bize
KareAl() metoduna ilikin XML formatndaki aklamay sar kutucuk iinde aadaki gibi
gsterecektir. Bylece kullanacamz metodun veya snfn bildirimine bakmamza gerek
kalmamtr.

Ayn durum parametreler iinde geerlidir. rnein KareAl() metodunun arm


parantezini yazdmz anda aktif parametre ile ilgili XML aklamas aadaki gibi
gsterilir.

Ayn XML yorumlar VS.NET ile entegre alan "Object Browser" arayz ile de aadaki
gibi gsterilmektedir.
Not : "Object Browser" penceresine erimek iin (Ctrl + Alt + J) tu kombinasyonunu
kullanabilirsiniz.

Dier XML Yorum Etiketleri

XML yorum etiketleri yukarda anlatlanlar ile snrl deildir. Aada kullanlabilecek
standart etiketler alfabetik sraya gre toplu bir ekilde tablo halinde aklamalaryla
birlikte verilmitir.

<c> Aklama iindeki bir blmn "kod fontu" eklinde olduunu


vurgulmak iin kullanlr.

rnek :

/// <summary>
/// Bu snf <c>Stream</c> snfndan tremitir.
/// </summary>
public class YeniSnf
{
...
}

<code> XML aklamas iinde uzun bir kod blou rnei verilecekse dier
yazlardan ayrmak iin kod blou bu etiket arasnda yazlr.

rnek :

/// <summary>
/// Bu metod iki Kompleks treden sayy toplar. rnein
/// <code>
/// Kompleks sayi1 = new Kompleks(5,6);
/// Kompleks sayi2 = new Kompleks(0,1);
///
/// Kompleks sayi3 = sayi1 + sayi2;
/// </code>
/// </summary>
public Kompleks operator+(Kompleks sayi1, Kompleks sayi2)
{
...
}

<example> Bir metodun yada snfn ne ekilde kullanlacan aklayan blok bu


etiket iinde yazlr. <code> etiketinin kullanm ile hemen hemen
edeerdedir. <code> etiketini verilen rnein ayns <example>
etiketi iinde geerli olduu ayrca bir rnek vermeye gerek yoktur.

<excepiton> Bir metodun frlatabilecei istisnai durumlarla ilgili bilgi vermek iin
kullanlr. <exception> etiketi "cref" nitelii ile birlikte kullanlr.
"cref" nitelii ile frlatlacak istisnai durum(exception) snfnn tr
belirtilir.

rnek :

/// <summary>
/// Bu metod iki Kompleks treden sayy toplar. rnein
/// </summary>
///
/// <exception cref="IndexOutOfRange">
/// </exception>
/// <exception cref="OzelIstisnaiDurum">
/// </exception>
public Kompleks operator+(Kompleks sayi1, Kompleks sayi2)
{
...
}

<list> HTML kodlarndaki <li> etiketine benzer bir amac vardr. Liste
eklinde bir yap olumas gerektii bildirilir. <listheader> listedeki
balk bilgisini, <item> listedeki her eleman, <term> her
elemandaki terimi ve <description> bu eleman hakkndaki detayl
bilgiyi bildirir.

rnek :

/// <remarks>Bu bir liste rneidir.


///
/// <list type="number">
///
/// <listheader>
/// <item>
/// <term>term 1</term>
/// <description>Aklama 1</description>
/// </item>
/// </listheader>
///
/// <item>
/// <term>term 2</term>
/// <description>Aklama 2</description>
/// </item>
///
/// <item>
/// <term>term 3</term>
/// <description>Aklama 3</description>
/// </item>
///
/// </list>
/// </remarks>
public class YeniSnf
{
...
}

Not : Liste tipi(<list type="number">) "number" olabilecei gibi


"bullet" ve "table" da olabilir.

<para> <summary> gibi uzun aklama bloklarnda bir paragraf belirtmek


iin kullanlr.

rnek :

/// <summary>
/// Bu snf Stream snfndan tremitir.
/// <para>
/// Bu snf ayn zamanda IDisposable arayzn uygulamtr.
/// </para>
/// </summary>
public class YeniSnf
{
...
}

<param> Bir metodun parametreleri ile ilgili bilgi vermek iin kullanlr.

rnek :

///<param name="Sayi1">Toplanacak birinci say</param>


///<param name="Sayi2">Toplanacak ikinci say</param>
public static double Topla(int Sayi1, int Sayi2)
{
return Sayi1 + Sayi2;
}

<paramref> <paramref> etiketleri ierisine alnan yerde aslnda metodun ilgili


parametresinin olduu bildirilir. Bylece oluacak XML yorum
dosyasndaki bu etiketi farkl bir biimde yorumlama ansna sahip
oluruz.

rnek :

/// <summary>
/// Bu snfn <paramref name="Sayi1"/> , ve
/// <paramref name="Sayi2"/> ve biiminde iki parametresi vardr.
/// </summary>
public static double Topla(int Sayi1, int Sayi2)
{
return Sayi1 + Sayi2;
}

<permission> ye elemanla ilgili gvenlik bilgisi vermektedir. rnein bir metoda


yada snfa kimlerin eriecei ve ne ekilde eriecei bu etiket
kullanlarak belirtilebilir.

rnek :

///<permission cref="Private">Herkes bu metoda eriebilir.


///</permission>
public static double Topla(int Sayi1, int Sayi2)
{
return Sayi1 + Sayi2;
}

<remarks> Bir tr hakknda ksa bir aklama vermek iin kullanlr.

rnek :

///<remarks>
/// zel cebirsel ilemleri tanmlar.
///</remarks>
public class Cebir
{
....
}

<returns> Bir metodun geri dn deeri ilgili bilgi vermek iin kullanlr.

rnek :

/// <remarks>
/// Kare Alma Islemi
///</remarks>
///<summary>
/// Parametre olarak gelen sayinin
/// karesini almak iin kullanilir.
///</summary>
///<param name="Deger">Karesi alinacak sayi.</param>
///<returns>Parametre olarak gelen sayinin karesi.</returns>
public static double KareAl(double Deger)
{
return Deger * Deger;
}

<see> Yaz iinde bir balantnn(link) olacan belirtir. "cref" nitelii ile
birlikte kullanlr. "cref" nitelii balantnn olaca ye eleman
simgeler.

rnek :

/// <summary>
/// Bu metod iki Kompleks treden sayy toplar. rnein
/// </summary>
///
/// <see cref="KompleksAlgoritmalar"/>
public Kompleks operator+(Kompleks sayi1, Kompleks sayi2)
{
...
}

<seealso> Yaz iinde ilgili elemanla yakndan ilikili olan dier elemanlara
balant vermek iin kullanlr. Kullanm <see> etiketi ile ayndr.

rnek :
/// <summary>
/// Bu metod iki Kompleks treden sayy toplar. rnein
/// </summary>
///
/// <seealso cref="operator-"/>
/// <seealso cref="operator/"/>
/// <seealso cref="operator*"/>
public Kompleks operator+(Kompleks sayi1, Kompleks sayi2)
{
...
}

<summary> ye elemanla ilgili geni aklama yazmak iin kullanlan bir etikettir.

rnek :

///<summary>
/// Cebir sinifi bazi zel matematiksel islemleri
/// yapmak iin esitli statik metotlar sunar.
///</summary>
public class Cebir
{
...
}

<value> Snfn bir ye eleman olan zellikler (Property) hakknda bilgi


vermek iin kullanlr.

rnek :

///<value>
/// Kontroln rengini belirtir.
///</value>
public int Renk
{
get { return a;}
set { a = value;}
}

Kodlarnz XML yorumlar ile sslemiyi unutmayn !...


Visual C# ile Windows Kontrol Hazrlama

Simdi sizlere Visual C# NETte bir Windows Control nasl yaplr ve bu Windows Control
programlarmzda nasl kullanrz onu gstereceim. Gstereceim rnei ok basit
setim, bunun nedeni de yaratcl siz arkadaslarma brakmay uygun grmemdir.
imdi rneimizi adm adm inceleyelim.

I. Visual Studio .NETte yeni bir proje aalm ve Windows Control Libraryyi
seelim ve adn deitirelim(Ben burada NewControls adn verdim siz istediiniz
ad verebilirsiniz.)
II. Daha sonra Anlaml bir isim olmas iin UserControl1in adn MyTextBox
olarak deitirelim.
III. Bu deiiklikleri yaptktan sonra MyTextBoxn zerine bir TextBox
yerletirelim ve onun adn da deitirelim. Ben burada adn myTBox olarak
deitirdim.
IV. Evet imdi MyTextBoxn kodunu aalm ve bir TextBoxn yapmas gerektiini
dndmz zellikleri de eklemek iin istediimiz metodu buraya yazalm.
Burada rnek olarak myTBox zerindeki bilginin integer olup olmadn control
eden bir metod yazalm ve metodun dn deeri eer integer deilse 0 (sfr)
olsun. Eer dn deeri 1 olursa integer olsun.
V. Kod yazmn tamamladktan sonra derleyin, eer derlemek yerine direk
altrrsanz(run) asagdaki uyary alrsnz(Ksaca verdii uyar : "Bu Windows
Control tek basna alamaz. Bunu baska projelerde kullanmalsnz.") Ama sorun
deil nk yaptgmz Windows control zaten dier projelerde kullanmak zere
tasarladk.

imdi sorabilirsiniz bu Windows Control projelerimizde nasl kullanacaz? Yine adm


adm anlatalm.
I. Yeni bir proje an veya nceden var olan bir projeyi an. Ben burada
Deneme adnda yeni bir proje atm.

II. Daha sonra .Netin Ana Proje Penceresindeki MenuBardan ToolsI tklayn
alan menuItemlardan Add/Remove ToolBoxItems tklayn.

III. Daha sonra alan pencereden .NET Framework Componentsin


seili olmasna dikkat edin. Eer seili deilse onu sein. Ve Browse diyerek
daha nce kaydetmi oldugumuz NewControls projesinin iine girilelim oradan
bine oradan da Debugn iine girelim. Daha sonra karmza kan
NewControls.dll adl dosyay seip OK tuuna basalm. Daha sonra tekrar
NET Framework Componentsin seili oldugu pencerede OK tuuna basalm.
IV. imdi ToolBoxa bakalm. ste karmzda MyTextBoxmzn yazl
olduu bir ToolBoxmz oldu. Artk MyTextBoxmz dier Toollar
kullandmz gibi kullanabiliriz.
Artk bundan sonrasn siz uygulama gelitirici arkadaslarma brakyorum. Unutmadan;
artk bu hazrlam oldugumuz Toolu diger projelerimizde de kullanabiliriz. Anlalmayan
herhangi birey olursa aytacozay@msakademik.net adresine mail atabilirsiniz.

Not: Eer kendi Toollarnz kullanarak bir proje yapyorsanz ve yaptgnz projeyi baska
makinelerde altrmak isterseniz kullandgnz Toollar o makineye yukarda bahsettigim
sekilde yklemeniz gerekir.
C#ta Inheritance(Miras) Kavram

Bu yazda inheritancen programlamada ne anlama geldiinden bahsedeceim.


Inheritance aslnda Oject Oriented Programming!in (Nesne Ynelimli Programlama)
prensibinden bir tanesidir. Dier iki prensip ise encapsulation ve polymorphismdir. Tabii
ki dier iki prensibe bu yazda deinmeyeceim. En sade ekliyle: inheritance sayesinde
bir snfn metodlarn kullanan baka snflar tretilebilmesine yarar diyebiliriz. Ancak
ayrntlarna birazdan ineceim. Eer daha nce nesne tabanl bir programlama dili
kullandysanz, (Java ve C++ gibi) C#ta inheritancea ok abuk adapte olursunuz.
Aslnda u ana kadar bahsettiklerim genel kltrden ibaretti ve eminim ounuz da
bunlar biliyordunuz. (Nesne Tabanl Programlama gemii olmayanlar da dnerek
byle bir giri yaptm.)

Evet imdi ana ksma yani programn nasl yazlacana geliyoruz. Bunun iin basit bir
rnek vereceim. Dnn ki student adnda bir snfmz(class) olsun. Ayrca bir de
teacher adnda bir snfmz olsun. Bunlarn ortak zellikleri nedir? Tabii ki insan
olmalar diyeceksiniz ve ana snfmza yani person snfna ulam olacaksnz. imdi
basite zetlersek person snfndan teacher ve student adnda iki snf tretmi olduk.
Srada bunun kodunu nasl yazacamz var. Alkanlklara devam edip adm adm kodu
yazalm. (Bunu program yazarken de ilke edinirseniz faydal olacana inanyorum.
nce ne yapacanz adm adm belirleyin sonra belirlediklerinizi adm adm
uygulamaya geirin.)

I. lk nce person snfn yazalm.

using System;

using System.Windows.Forms;

namespace Miras

public abstract class Person

//snfn sadece tretileceini


//belirtmek iin snf abstaract keywordn kullanarak soyutladk
//Ancak burada abstaract keywordnn kullanlmasndaki temel

//faktr bu snfn abstract metod iermesidir.

//Tretilen snflarda kullanlmak zere 3 tane deiken tanmladk.

protected string Name;

protected int Age;

protected string Gender;

//Tretilen snflarda metodun ii doldurulmas iin


//abstract olarak makeAction metodu tanmladk

public abstract void makeAction();

public Person()

}
}

II. imdi de Student snfn yazalm.


using System;

using System.Windows.Forms;

namespace Miras

//Student class' Person class'ndan miras aldn belirtiyoruz.

public class Student:Person

//Person snfnda tanmlanan abstract metodu override ederek

//metodun iini istediimiz gibi doldurduk.

public override void makeAction()

MessageBox.Show("Ben bir renciyim");

public Student(string name,int age,string gender)

{
this.Name=name;

this.Age = age;

this.Gender=gender;

III. Sra Teacher snfn yazmaya geldi.

using System;

using System.Windows.Forms;

namespace Miras

public class Teacher:Person //Teacher class' Person class'ndan

// miras alyor

private string Unvan; //Teacher snfnda kullanlmak zere

//Unvan adnda bir deiken tanmladk.

//Person snfnda tanmlanan abstract metodu override ederek

//metodun iini istediimiz gibi doldurduk.

public override void makeAction()

MessageBox.Show("Ben bir retmenim");

}
public Teacher(string name,int age,string gender,string unvan)

this.Name=name;

this.Age = age;

this.Gender=gender;

this.Unvan=unvan;

}// teacher snfnn sonu

}// Miras isim uzaynn sonu

imdi dikkat edilmesi gereken noktalar sralayalm:

I. Abstaract (soyut) snftan yeni bir snf tretilemez. rneimizde person snf abstract snftr ve new
anahtar szc kullanlarak yeni nesne oluturulmaz.

II. Abstract metodlarn mutlaka ileri bo olarak yaratlr ve tretildikleri snflarda (en az bir snf
tretilmek zorunda) mutlaka ileri override anahtar szc kullanlarak doldurulur.

III. Bir snftan miras yolu ile baka bir snf tretilecei zaman temel snf(base class) illa ki abstract
anahtar szc ile tanmlanmak zorunda deildir. (Eer abstract metod iermiyorsa.)

Not: Yukarda kodlarn yazdm snflarn basit bir kullanmn ieren Miras adndaki
projeyi indirmek iin buraya tklayabilirsiniz. Bu sayede kafalarda hibir soru iareti
kalmasn istiyorum. Projeyi altrdnz zaman bir windows formu gelecek. Bu formun
zerinde iki tane buton var.

Student Action butonunu tklarsanz Student snfnn iindeki makeAction metodu


alr. Daha sonra da windows formu yaratldktan hemen sonra yaratlan student
nesnesinin Name, Age, Gender deikenleri bir mesaj kutusu araclyla grntlenir.

Teacher Action butonunu tklarsanz Teacher snfnn iindeki makeAction metodu


alr. Daha sonra da windows formu yaratldktan hemen sonra yaratlan teacher
nesnesinin Unvan, Name, Age, Gender deikenleri bir mesaj kutusu araclyla
grntlenir.

Kafanza taklan sorular iin mail adresim aytacozay@msakademik.net


C#'a Ksa Bir Giri

Ben C dilini renmeye 1 yl nce niversitede MS DOS ortamnda yaptmz basit


matematiksel ilemlerle baladm.Gerektende her programda alla gelmemi bir ok
komut vard. Gnmzde kullanlan C# diline gre ok gelimemi olan bu dile o kadar
snmtk ki artk uygulamalara yetiemez olduk. C ok eskiden kan bir dil fakat geliimi
ve insanlarn ona yetimesi ok hzl idi. Srasyla C,C++,C# ben buna 3D diyorum yani 3
dev demekle yetiniyorum. C dili bir ok dilin temeli veya stnde bir dil. Hemen hemen
her alanda kullanlmaktadr. Mesela Javascript,ActionScript... En nemli olan uygulama
alan ise Windows ve Linux gibi gl bir iletim sistemlerinin C de yazlmasdr. C dilinin
uygulama alanlar sadece saydklarmla snrl deildir ama bu alanlarn hepsini burda
listelemem mmkn deildir.

.NET Framework, programclara aina olduu kod dilini kullanma zgrl tanyarak bir
devrim gerekletirdi. Ve, belli belirtimlere sadk kalnd srece, farkl dillerle yazlm
uygulamalarn birbiriyle etkileebileceinin de teminatn verdi.

Evet, .NET diller aras etkileime olanak tanyan, bir ok dile destek veren bir platform.
nc parti derleyiciler yazlarak .NET iin her an yeni bir dil daha yazlabilir. Ama
hereyden nce, .NET'in beraberinde sunduu dillere bakmak gerekiyor. Bu diller temel
olarak 4 tane: C++, Visual Basic .NET, C# ve J#.NET. Dikkat edilirse bu listede, "ben
yeniyim" diye gz krpan bir tanesi var : C#. Yazmzda, bu yeni dili tanmaya alacaz.

C# (si arp) herkesin dile getirmi olduu gibi C++ ve Java nn birlemesiyle olumutur.
Henz nasl bir birleme ekli olduuna dair tam bir fikrim yok ama C# mkemmel bir
ktphaneye sahip. Bu ktphaneye ufak bir gz ainalmz olacak ama ilerideki
yazlarmzda dier dillerden byk bir fark olan esnek bir yapya sahip olmasn
inceleyeceim. Nedir bu esneklik? Yani Program yazarken "of be bu dilin de bu zellii
yokmu" dediimiz anlar olmutur. C ile de phesiz nesnel programlama yapabiliriz.
Fakat bunu yapabilmek olduka zordur. C++ ise Nesne ynelimli programlamaya imkan
vermekten te zaten bu paradigmaya gre tasarlanmtr ve yapsndaki aralar
sayesinde bunu kolaylatrmtr. te C- C++ arasndaki fark bu peki C#'n zellii nedir?

Nesne ynelimli programlamann gnmzde ne kadar yaygn olduunu programlama ile


ilgilenen herkes bilmektedir. Nesne Ynelimli Programlama (NYP) yaklamnda temel
olan prensiplerden birisi bilgi gizleme (information hiding)'dir. Bu prensibi projelerimizde
uygulamak iin C#'in sunduu en nemli aralardan biri olan snf zellikleri (class
properties) konusunu inceleyeceiz.

Bildiiniz gibi, C# dilinde tasarlanm bir snfta iki temel unsur bulunur. Birincisi snfn
zellikleri (fields), ikinicisi ise snfn metodlari (methods)'dr. Herhangi bir snfn zellikeri
snfta tutulan iliikili verilerlerdir. Dier taraftan snfn bizim iin deiik ileri yapmasn
metodlar vastasyla salarz. Snf tasarm ok nemli bir i olup; deneyim,
konsantrasyon ve dikkat ister. Snfmzn zelliklerini tutan veriler, program ak
srasnda snf dnda deitirilebilir veya bu deerlere ulamak istenilebilir.

Elbetteki C# hakknda bilinmesi gerekenler bu kadarla snrl deildir. Bundan sonraki


yazlarmda hereyi daha ayrntlaryla aktarmaya alacam.
.NET in Tavsiye Edilen simlendirme Konvansiyonlar 1

Merhaba, bu makalemizde artk programclk hayatmzn heryerinde, kkl


bykl her program iin ihtiyatan ok bir zorunluluk haline gelen isimlendirme
tekniklerine, tarihelerine deinecek,kendi isimlendirme stilimizi nasl oluturabiliriz ona
bakacaz. 1. blmn tamamn ,yani bu yazy tmyle bu alacakken , 2. blmnnde
zellikle Microsoftun .Net iin de tavsiye ettii konvansiyon olan Pascal & Capitalized
Form (Pascal ve Byk harfler notasyonu) ve uygulamas zerinde duracaz.

Neden simlendirme Konvansiyonlarn Bilmeliyiz?

Tabii ki bu konvansyonlar kullanmak zorunda deiliz,kendi konvansiyonumuzu


oluturup kodlamaya da geebileceimiz gibi,konvansiyonsuz da kodlama yapabiliriz.
Fakat ileri dzey programlamada isimlendirmenin birok avantaj vardr.

simlendirme kavram,programlama dnyasnda komplex kodlarn yazlmaya


balanmasyla,zellikle de OOPL (Nesne Ynelimli Programlama Dilleri) nin gelimesiyle
byk nem kazand. nk ortak olmayan ve anlamsz isimler,modullere blnm ve
zm uzaylarna ayrlm,spesifikasyonlar hazrlanm,yani en nemli blm halledilmi
bir programn sadece kodlama aamasnda eitli ciddi hatalara yol almasna sebep
oluyordu. Bir kiiden fazlasnn almasn gerektiren projelerde insanlar birbirlerinin
yazdklar kodu anlamyor, hatta bir kiinin kendi yazd program bile daha sonra
baktnda anlamas gleiyordu.

simlendirme konvansiyonlarn kullanmann dier baz avantajlar ise unlardr :

o Programa vereceimiz isimler anlaml olur.

o Hepsi bir kurala bal olduu iin dzenli grnr.

o sim seme ilemi artk mekanik olduundan zerinde dnmeye gerek


kalmaz, hzl alrsnz.

o Takm almalarnda ayn dili konumanz salar.

o Kodlarnz anlalr olacandan daha az yorum yazabilirsiniz.

o Kodunuzu bceklerden(bugs) arndrrken faydas olur.

o Kod standardize olduu iin daha sonra programnzn kodunu baka bir
program yardmyla iyiletirebilirsiniz.

o Ortam hazrlayclar tarafndan belirlenen notasyonu kullanmak,ortam


tarafndan otomatik olarak koda yerletirlien kod paralar ile de uyumlu
olaca iin ( r: Form Designern koda eklentileri ) tam uyum salar.

simlendirme konvansiyon eitleri

Bu sorunlara bir zm bulmak iin notasyon ad verilen standartlar gelitirildi.


Ortamlarn farkllndan dolay birok standard ortaya kt. Bunlardan bazlar unlardr :

Hungarian notation (Macar notasyonu):


Macar notasyonu diye bilinen bu notasyon dier notasyonlarn atas olarak kabul
edilmesi itibariyle,gnmzde geerlilii azalmtr.

DOSun ilk kt zamanlarda Microsoftun ef direktr Charles SIMONYI


tarafndan gelitirilen bu tanmlayc isimlendirme notasyonunun temelinde,ismin nne
tipini yazarak aktif isimlendirmeyi salamaktr. rnek verecek olursak, bir boolean flag
iin bFlag isimlendirmesi uygun bir isimlendirme eklidir. String olarak
strFirstName,integer olarak iNumberOfDays uygun isimlendirmelerdir.

Bu isimlendirmenin getirdii faydalar artk modern programlama ortamlarnn


gelitirilmesiyle ortadan kalkmtr. nk,mesela .Net gibi bir ortamda bir deikenin tipi
zaten kodun her yerinde bellidir,bundan dolay ismi uzatmaya gerek yoktur. Yani,bu
notasyonun gnmzde kullanm artk azalmtr.

Ayrca ortamlarn destekledii tr says gnden gne arttndan bu tr bir


isimlendirmeye gitmenin baya bir g olaca aktr. Bu trn Extended Hungarian
Notation,Modified Hungarian Notation ,Simple Hungarian Notation Hungarian Notation
trleri bulunmaktadr.

MFC naming (Member-First Case) (lk harfi tanmlaycl notasyon):

Bu notasyonun temelinde tanmlaycnn tipinden ok tr nemlidir,yani int


mi,short mu olmasndan ok ye,snf,fonksiyon olmasna gore isimlendirilir. Event
isimleri ise (On) ile balar. rnek olarak m_socket, i_counter,OnClose bu notasyona gre
iyi isimlendirilmi tanmlayclardandr.

Bu isimlendirme tekniinin ise eskidii Macar notasyonunda belirttiimiz


nedenlerden tr aktr.

GNU Notation (GNU Derleyici Notasyonu)

stte belittiimiz dier notasyonlardan farkl olarak bu notasyonda kelimeler


arasnda altizgi ( _ ) karakteri bulunma art getirilmitir. rnein
global_number_increase gzel bir isimlendirme iken icantreadthis iyi deildir. Ayrca baz
GNU derleyicilerinde 8 ve/veya 14 harften fazlasna izin verilmediinden zorunlu olarak
bu derleyicilerin standartlarna harf snrlamas da getirilmitir.

Ayrca yine baz derleyicilerde ( __ ) ile balayan deerler ayrlmtr. Bundan


dolay altizgi ile balayan isimlendirmeler iyi isimlendirme rnei deildirler.

Dier baz notasyonlar ise Sun Java notation, SmallTalk Roll Based Naming,
Taligent Form dur.

Kendi simlendirme Konvansiyonumuzu Oluturma

Yaznn bu ksmna kadar , varolan isimlendirme eitlerini iyice anladmz


umuyorum. Fakat hala benim kendi isimlendirme standardm olmal diyorsak, dikkat
etmemiz gereken baz noktalar var.

Bir isimlendirme konvansiyonu olutururken,dikkat etmemiz gerekenlerden ilki,


isimlerin anlalabilecek kadar uzun, fakat yazlabilecek kadar ksa olmasdr. Bunlar
olutururken konvansiyonlar kullanmann temel faydalarna zarar vermemeyi
gzetmeliyiz.
simlendirme konvansiyonumuzu seerken ortam,dil, ve kltr zelliklerine,
isimlendirme konvansiyonu mantnn temelinde yatan estetik kaygya ve algoritma
oluturmann temel artlarna (verimlilik,isteneni verme vs vs ) dikkat etmemiz gerekir.

Tm simlendirme Konvansiyonlarnnda Bulunmas Gereken Temel


zellikler

Btn standartlarda ortak olmas gereken noktalar ise yle sralayabiliriz :

o Tanmlaycnn(deikenin,snfn,metodun vb...) amac dorultusunda isimler


verilmesi gerekir. Mesela okuldaki renci saysn tutan bir deikene tamsayi
eklinde isim vermek yerine ogrencisayisi eklinde isim vermek daha mantkl
olacaktr.
o Tanmlaycnn ismi byk ve kk harfleriyle okunabilir ve anlalr uzunlukta
olmaldr.
o Mmkn olduunca ksaltmalar azaltmaldr. nk ksaltmalar ou zaman
tehlikeli olabilmektedir. rnein Ctr Control olarak anlalabilecei gibi
counter olarak da anlalabilir.
o Tanmlayclarn isimleri,dier tanmlayclar arasnda ayrt edici zellik olarak
kullanlmamaldr. rnein Counter ve counter adnda iki deikenimiz
olmamaldr

Daha sonra i kendi isimlendirme standardmzn artlarn oluturmaya bakyor.


Bunun iin bu yaz genel bir fikir verebilir. simlendirme tekniklerinizi,hibir tanmlayc
tipi akta kalmayacak ekilde tasarladktan sonra projenin daha sonra da ayn
mantkla gelitirilmesi ve isimlendirme konvansiyonunuzun kalcln koruyabilmesi
iin iyi bir ekilde dkmante etmelisiniz.

Dkmantasyonunuz isimlendirme konvansiyonunuzla ilgili hereyi iermelidir(Tip


isimleri,n ekler,arka ekler,ksaltmalar,eklentiler,zel karakterler,vb...) .

Ve son sz olarak , unutmayalm ki , bir ok kod bir kez yazlr ama binlerce kez
okunur. Bunu gz nne alarak kodlamamz daha profosyonel standartlara tayalm.

Yaznn 2. blm Microsoftun .NET ortam iin nerdii formlar olan PASCAL &
CAPITALIZED FORM , CAMEL FORM adl notasyonlar derinlemesine inceleyecek , ve
herhangi bir isimlendirme sistemimize aykr davranldn ok byk kod paralarnda
nasl anlayacamz anlatacam.

Grmek zere,
C# 'ta Kapslleme, Eriim Belirteleri ve Polymorphism

Geen yazmda inheritance' tan bahsederken encapsulation diye bir kavramdan


bahsetmitik, imdi bu kavram aklayacam. Daha nceki yazmda belirttiim gibi 3
OOP prensibinden biri. Trke karlna gelirsek kapslleme demek. Ancak bilgisayar
terimi olarak biraz aarsak kapslleme, ynettii kod ve veriyi birbirine balayan ve bu
ikisini d kaynakl kartrma ve yanl kullanmdan koruyan bir mekanzmadr. Bu sayede
veriyi d ortamdan koruyan bir ambalaj vazifesi grdn de syleyebiliriz. imdi
kapsllemeyi biliyoruz da C#'ta yada .Net Framework'nde ne gibi farkllklar var
diyeceksiniz? ncelikle .Net Framework'nde gelen yeniliklerden bahsedelim.

I. Eriim belirtelerinin(Access Modifiers) varl kapsllemeyi ok daha rahat


yapabilmemize olanak salar. Bu sayede bir metod veya bir deiken anahtar
szckler(keywords) araclyla sadece nceden belirlenen snrlar dahilinde kullanlabilir.
Yada bunlara belirlenen snrlar iinden ulalabilir. Burada bahsedilen keyword'leri
birazdan aklayacam. (Tabii ki C#'ta kullanlan keywordleri aklayacam. Ve
kullanmlarn basite anlatacam.)

II. zellik(Property) Sahalarnn kullanm (Bunun yapmn ilerde C# kodu ile


gstereceim.) Bu sayede .Net Framework kapsllemeyi destekler.

III. Soyut snf(abstract class) ve soyut metodlarn(abstract methods) kullanm. Aslnda


kaltm(inheritance) konusunu anlatrken taban snfmz(base class) soyut snf idi. Onun
iin bu ksm sadece aklayacam. rnek vermeyeceim. rnei grmek isteyenler
miras(inheritance) konusunu anlattm yazdaki rnei incelerlerse istedikleri bilgiye
ulaabilirler.

Evet bu kadarlk giri yeter. imdi yukarda anlattm 3 maddeyi enine boyuna
tartalm.

I. Eriim belirtelerinin ne ie yaradklarndan yukarda bahsettiim iin burada direkt


eriim belirtelerinin neler olduklarn yazalm ve eriim snrlarn izelim. Eriim snrlar
geni olandan dar olana doru bir sralama yaparsak.

public: Btn her yerden eriilmek istenen veriler public anahtar szc ile
birlikte kullanlr. Sadece ayn proje ierisinden deil dier projeler ierisinden de
eriilebilir.
internal: Ayn assembly iindeki tm snflar eriebilir. Yani public anahtar
szcnn sadece ayn proje iinden eriilebileni. (VB .Net'te ise Friend anahtar
szcne karlk gelir.)
protected: Protected anahtar szc ile birlikte kullanlan verilere ise sadece bir
alt snfa kadar eriilebilir.
private: Bu ise sadece tanmland snfta geerli olan veriler iin kullanlr.

Ancak kontrollerde(controller) yaygn olan kullanm ekli kontrollerin dardan eriilmesi


istenen metodlarnn(ayn anda diyelim ki 3 tane kontrol'n belli metodlarnn almas
gerekli olabilir.) public anahtar szc kullanlan bir metod iinde tanmlanmasdr.
imdi bu durumun nasl yapldn gsteren mini bir rnek kod yazalm. Kodda belirtilen
kontrollerin daha nceden tanmlanm olduunu dnelim.

public void ChangeColor(Color color)


{
this.groupBoxLine.BackColor = color;
this.groupBoxOutCity.BackColor = color;
this.groupBoxExternalPriceDetails.BackColor = color;
this.groupBoxInternalPriceDetails.BackColor = color;
this.groupBoxUser.BackColor = color;
this.groupBox1.BackColor = color;
this.btnAddNewLine.BackColor = color;
this.btnAddNewUser.BackColor = color;
this.btnCentralReport.BackColor = color;
this.btnChangePassword.BackColor = color;
this.btnDeleteExternalLine.BackColor = color;
this.btnDeleteInternalLine.BackColor = color;
this.btnDeleteUser.BackColor = color;
this.btnExit.BackColor = color;
}

Yukardaki metod bir renk parametresi gnderilerek arld zaman yukarda yazan
btn (daha ncede private anahtar szc ile tanmlanm olduklarn kabul etmitik.)
kontrollerin rengini gnderilen renge deitirmeye yaryor. Bu sayede yukardaki
kontrollerin hepsinin BackColor dndaki metodlar d dnyadan soyutlanm oluyor.

Aslnda yaptmz metod public anahtar szc ile tanmlanmayp internal anahtar
szc ile de tanmlanabilir. Bu bizim metodun iindeki kontrollere ait BackColor
metodlarnn d dnyadan ne kadar soyutlanmasn istediimiza baldr.

II. zellik sahalar snflara ait zel(private) deikenlerin ayn metodlar gibi d dnyaya
almalarn salyor. Sadece okuma amal da alm yaplabildii gibi hem okuma-hem
yazma amal bir alm da yaplabilir. Teorik olarak sadece yazma amal da bir alm
olsa da ne kadar mantkl olur bilmem!!!! imdi rneklerimize geelim.

private int currentExNumber = -1;


private int loginStatus = 0;

public int CurrentExNumber //Sadece okuma amal zellik


{
get
{
return currentExNumber;
}
}

public int LoginStatus //Hem okuma hem yazma amal zellik


{
get
{
return loginStatus;
}
set
{
loginStatus = value;
}
}
imdi yukardaki zellikleri kullanrken nesneadi.LoginStatus ve
nesneadi.CurrentExNumber eklinde kullanabiliriz. Yalnz dikkat etmemiz gereken
CurrentExNumber kullanlaca zaman sadece eit iaretinin(=) sol tarafnda
kullanlabilecek olmas. nk bata da belirttiimiz gibi sadece okuma yapabildiimiz iin
get metodu var. Zaten bir deer atamaya kalkarsak hata verecektir.(Derleme esnasnda
zelliin sadece okuma amal olduuna dair debug penceresinden mesaj verir.) Bu
sayede de deitirilmesini istemediimiz ama kullanmak zorunda olduumuz verilerin d
ortamdan hem soyutlanmasna hem de bunlarn d ortama belirli izinler dahilinde
almna izin vermi olduk.

III. Aslnda soyut snf ve soyut metod'dan daha nce az da olsa miras konusunu
anlatrken bahsetmitim. Ancak imdi biraz polymorphism'den bahsederek bu kavramlar
biraz daha aacam. Polymorphism kapslleme ve miras'dan ayr dnlemez.
Polymorphism Yunancada "ok formluluk" anlamna gelmektedir. Polymorphism ile soyut
snf arasndaki ilkiden bahsetmeden nce soyut snf ve soyut metodlarla ilgili bir iki
ayrnt daha verelim. Soyut snf sadece taban snflarnda kullanlr ve yeni nesne
yaratlmasnda kesinlikle kullanlamaz. (Yani new anahtar szc kullanlamaz.)

Soyut metodlara gelince bunlarn ise soyut snflarda kullanlacandan bahsetmitik.


Bunun bize salad avantaj bu metodlarn tretilen snflarda nasl gerekletirildiini
bilmek zorunda olmamamzdr. Aslnda bunu syleyerek polymorphism'in yararndan
bahsetmi olduk. Yani polymorphism veri soyutlamas yaparak sadece ilgilenmemiz
gereken olaylar ve verilerle ilgilenmemize olanak salyor. Bu sayede taban snfndan
tretilen ve ayn metodu farkl gerekletirimlerle(implementation) kullanan birden fazla
snfa sahip olabiliyoruz. En basit rnek gen bir okgen, kare de bir okgen ve her
ikisinin de bir alan mevcut. Hemen basite bir taslak karrsak okgen snf soyut taban
snf ve alan adnda soyut bir metoda sahip. gen ve kare snflar ise tretilen snflar
ve alan metodunu istedikleri biimde gerekletiriyorlar. (Bu ilemlerin nasl yapld
miras konusunu anlattm yazda mevcuttur.)

Bir de soyut zellikler(abstract property) var. Bunlarn kullanm ise soyut metodlar ile
zelliklerin birlikte kullanm ile ortaya kmakta. Buna bir rnek kod verirsem anlalmas
daha kolay olacaktr. Ancak bunlarn kullanmna ok sk rastlamadm belirtmem
gerekir.

Sanrm aadaki rnek kod paras soyut zelliklerin kullanmn daha da netletirmitir.

abstract class Taban // Soyut snf


{
protected int CurrentExNumber = -1;

public abstract int GetCurrentExNumber// Soyut zellik


{
get;
}
}

class Turet: Taban //Turet adl bir snf tretiliyor


{

public override int GetCurrentExNumber// overriding property


{
get
{
return CurrentExNumber+1;
}
}
}

Polymorphism'den bahsettik. imdi ise yalanc polymorphism'den bahsedelim. Aslnda bir


rnekle biraz daha aarsam daha net olur. Diyelim ki bir karlatrma metodunuz var ve
hem integer hem de string veri tiplerini karlatrmak istiyorsunuz. Yalanc polymorphism
sayesinde ayn isimde iki metod yazarak bu isteinizi gerekletirebilirsiniz. Bunun iin
mini bir rnek kod yazalm isterseniz.

Aada yazacam metodlarn ayn snf iinde yazldn dnelim. imdi bu metodlar
kullanrken metodlarn iinde yer ald snftan retilen
nesneninadi.karsilastir( yazdmz anda kod tamamlaycs bize iki seenek sunar biri bu
metodun iki tane integer veri tipi ile alt, ikincisi ise bu metodun iki tane string veri
tipi ile altdr. Bu sayede bir arabirim ile birden fazla metod gerekletirilmi olur.

Aslnda bir metodun birden fazla gerekletirime sahip olmas olayna overloading denir.

Dikkat edilmesi gereken nokta overloading ile overriding'in birbirine kartrlmamasdr.


Unutmayn overloading'te btn ilemler ayn snf ierisinde oluyor. Overriding'te ise tek
bir snf yerine taban snf ile bu snftan tretilen snflar iin iine giriyor.

public void karsilastir(int sayi1, int sayi2)


{
//Metodun i implementasyonunu sizlere braktm.
}

public void karsilastir(string data1, string data2)


{
Metodun i implementasyonunu sizlere braktm.
}

Evet bu yazda anlatacaklarm sona erdi. Kafanza taklan ksmlar iin mail adresimi
tekrarlyorum
Yeni Nesil Uygulamalarnn Mimar C# ve Dier Diller

irket yneticileri gelitirilecek proje iin bir programlama dilini semek zorunda
kaldnda genelikle u soruyu sorar : Hangi programlama dili ile projeyi en etkin ve en
hzl ekilde mterime sunabileceim hale getirebilirim? Bu sorunun zmne ulamak
o kadar da kolay olmuyor maalesef. zme zor ulamada programlama dillerinin fazla
olmasnn etkisi omakla beraber her bir programlama dilinin sunduu standart
ktphanenin farkl olmasnn da etkisi olduka fazladr. zellikle gnmz i
uygulamalar birden fazla platformu destelemek zorunda kalmtr. Buda seilecek
uygulama gelitirme ortamnn nemini akca gstermektedir. Uygulamalarn internet
ortamna tanmas ile birlikte bir programlama dilinden beklenen zelliklerde doal
olarak deimitir. 1970 li yllarda bir mikroilemciyi programlamak ne denli nemli
olduysa 2000li yllarda interneti programlamak o kadar nemli olmutur.

nternetin i dnyasna girii ile birlikte gelitirilen uygulamalardan beklenenler de


deimitir. Bu durum doal olarak uygulama gelitiricileri dorudan etkilemitir. nternet
ortamnda alan ve datk yapda alabilen ok ynl bir uygulama gelitirmek eski
yntemlerle imkansz deildir ancak inanlmaz derecede zaman ve insan gc
gerektirmektedir. Bu zoruluklar amak iin gelien teknolojiye ve isteklere paralel olarak
programlama dilleri de doal geliim iine girmitir. Bu yazda son yllarda i ve kiisel
uygulama gelitiricilerin adn ska duyduu C# programlama dili ve dier dillerle olan
ilikisi anlatlacaktr. C# programlama dilinin sunduu imkanlar anlatmaya balamadan
nce programlama dillerinin tarihsel geliimine gz atmak gerekir. Zira C# dili yllardr
youn bir ekilde kullanlan C,C++ ve JAVA dillerinin temelleri zerine kurulmutur. unu
da hemen belirtelim ki, son gelitirilen ilk gelitirilenden ou zaman daha iyi olacaktr.
Bu yzden eski ile yeniyi karlatrrken ticari amalar bir kenara brakp objektif bir
gzle deerlendirmek gerekir.

C# konumadan nce C, C++ ve C# ile yakndan ilikili olan JAVAdan


bahsetmek gerekir.

C dili ve Yapsal Programlama

Dndklerimizi makinelere yaptrma isteimizin bir sonucu olarak programlama


dilleri domutur. Makineleri anlamak insanolu iin o kadar da kolay olmamtr. Zira
makinelerin(bilgisayarlarn) anlad dilden konumak insanlar iin gerekten zor bir itir.
Gn getike makineleri anlamak ve onlar programlamak iin yeni araylar iine girildi.
Somutlatrlm makine komutlar sayesinde bilgisayarlar daha etkili bir ekilde
ynetmek mmkn hale gelmitir. Zaman ilerledike bilgisayarlar sadece belirli bilimsel
hesaplamalar yapmak iin kullanlan ara olmaktan kp insanlarn yaamlarnda rutin
ileri yapabilecek ara haline geldi. Bilgisayarlarn insanlarn ihtiyalarna hzl bir ekilde
cevap verebilmesi iin onlar hzl bir ekilde programlamak gerekiyordu. Klasik
yntemlerle(makine komutlaryla) hzl zmler retilemez hale gelince daha yksek
seviyeli programlama dillerine ihtiya duyuldu. 1980li yllarda en ok kullanlan
programlama dili olan C bu anlamda atlm byk bir admdr. Yapsal programlama
modeli her ne kadar C dilinden nce de yaplyor idiyse de asl byk gelimeler C dili ile
birlikte olmutur. C gibi makine diline gre yksek seviyeli programlama dilleri ile byk
projeler yaplabiliyordu. Artk uygulamalar sadece bilimsel alma arac olmaktan kp i
dnyasnda kullanlabilen uygulamalar haline geldi. Btn bu iyi gelimelerin yannda
zaman su gibi akp gidiyordu, buna paralel olarak projeler byyor ve teknoloji artan
ivmeyle geliiyordu. Yava yava anlald ki C dili ok byk projelerde yetersiz
kalyordu. Yeni bir programlama modeline ihtiya duyuldu ve C++ dilinin temelleri atld.

C++ ve Nesne Ynelimli Programlama

Yapsal programlama modeliyle ok byk projeleri kontrol altna almak neredeyse


imkanszdr. Bu sorunun stesinden gelmek iin yeni bir model gerekiyordu. Nihayet
Bjarne Stroustrup tarafndan C dili baz alnarak yeni bir programlama dili gelitirildi. Bu
dilin ad : C++tr. C++, Cnin zerine inaa edildii iin ilk balarda C with
Classes(Snfl C) olarak adlandrld. Peki bu dil Cden farkl olarak programclara ne
sunuyordu? C++ dilinin sunduu en byk yenilik nesne ynelimli programlamay
destekliyor olmasdr. Nesne ynelimli programlama teknii gnmzde de yaygn bir
ekilde kullanlan bir tekniktir. Bu teknik gerek hayat modellemede byk bir baar
salamaktadr. Sz gelimi bir projeyi paralara ayrp bu paralar arasnda programlama
yolu ile balantlar kurmak ok basit hale gelmitir. Nesne ynelimli programlama teknii
proje gelitirme aamasnda burada sayamayacamz birok kolaylk salamaktadr.

C++ dilinin dier bir zelliide C programclarna hitap etmesiydi. C dilindeki temel
kurallar aynen C++ dilinde de mevcuttur. Bu yzden C++ dilini ve nesne ynelimli
programlama tekniine gei yapmak iin C dilini iyi bilmek gerekir. Daha dorusu C++
dilini sadece nesne ynelimli programlamay destekliyor eklinde dnmemek gerekir.
Gnmzde birok alt seviye ilemlerde(haberleme, iletim sistemi, aygt srcleri) C+
+ dilinin youn bir ekilde kullanlmas bunun bir kantdr.

nternetin Geliimi ve JAVA Dili

nternetiin geliimi bilgisayar dnyasndaki en nemli ilerlemelerden biridir.


Programlama dnyasnda JAVA dilinin ortaya kmas en az internetin ilerlemesi kadar
nemlidir. nk C ve C++ dilleri ile yalnzca belirli sistemlere ynelik uygulamalar
gelitirilebiliyordu. Oysa internet sayesinde birok farkl sistem birbirine balanr hale
gelmitir. Artk sistemlerden bamsz uygulama gelitirmek gerekiyordu. Daha dorusu
interneti hedef alacak uygulama gelitirmek gerekiyordu. Programclar gelien internet
ortamna yabanc kalamazd. Bu ama dorultusunda Sun Microsystems isimli firma
nceleri OAK olarak anlan JAVA isimli programlama dilini ortaya kard. JAVA, dil olarak
C++ dilinin devam gibi dnlebilir. Ama ama tamamen farkldr. Zira Sun firmas
ortaya JAVA dili ile birlikte yeni bir uygulama gelitirme modelide sunmaktayd. Bu
programlama modelinde en byk hedef sistemler aras tanabilir kod yazmaktr. Yani
bir uygulamay hem Microsoft platformunda hemde Unix ve Linux platformlarnda
altrabilmek hedeflenmitir. Bylece gelitirilen uygulamalar iletim sistemi ve
ilemciden bamsz hale gelecektir.
Peki sistemler aras bu yksek tanabilirlik nasl olmaktadr? Cevab basit : Ara
Dil. Evet, JAVA dilinde yazlm kodlar derlendiinde kodlar makine komutlarn
evrilmeden ara kod denilen bytecode a evrilmektedir. Bytecodea evrilen program
altrldnda Java Sanal Makinesi devreye girer ve uygulamann altrld sisteme
zgn makine kodunu retir. Bu durumda Sun firmasnn bir ok sistemde alabilecek
Java Sanal Makinesi retmesi gerekiyordu. Nitekim zamanla gnmzde yaygn kullanlan
btn sistemlerde sorunsuz alabilecek Java Sanal Makineleri gelitirildi. Hatta u an
iin baz cep telefonlar ve eitli sim kartlarnda bile JAVA programlarn altrabilecek
Java Sanal Makineleri mevcuttur.

JAVA ile C++ dili her ne kadar birbirine ok benzer olsada ayn kategoride deildir.
Elmayla armutu kartrmamak gerekir. Eer JAVA m C++ m diye bir soru sorulursa
cevap her ikisi de olacaktr. nk ikisininde kullanm amac farkldr. Bir firma bir proje
iin hibir zaman bu iki dilden birisini semek durumunda kalmayacaktr. JAVA ile ayn
kefeye koyabileceimiz dil birazdan anlatacam C# dilidir.

C# Dili ve .NET Platformu

JAVAnn platform bamsz kod retmedeki baars su gtrmez bir gerektir. Bir
ok kurumsal dev projede JAVA dilinin ve J2EE platformunun olanaklarndan
faydalanlmas bunun en nemli gstergesidir. Gnmzde byk projelerde birden fazla
programlama dili kullanlabilmektedir. Ancak JAVAnn diller aras uyumlu almaya
destek verememesi JAVAnn bir eksiklii olarak grlmtr. Diller aras uyumlu alma
alannda en byk baary Microsoft firmas salamtr. Son dnemlerde sklkla
kullanlan COM teknolojisi bu uyumlulua bir rnektir. COM sayesinde farkl dillerde
yazlan yazlm paracklar dier bir uygulamada kullanlabilmektedir.

JAVAnn programlamadaki byk bir boluu doldurmas onun en byk rakibi


olan Microsoft firmasnn gznden kamad. En sonunda Microsoftun bir rn olan
Visual Studio yazlm gelitirme aracna JAVA y da ekleme karar ald. Visual J++ ad
altnda Windows platformuna entegre edilen JAVA dili bu platformda pek baarl olamad.
Bu oluumun baarl olmadn gren Microsoft yeni araylar iine girdi. Microsoft
bakasnn maln kendi rnne entegre etmek yerine kendi rnn gelitirmeye karar
verdi ve .NET yazlm gelitirme platformunu ortaya kard. .NET temel felsefe olarak
J2EE platformuna benzemektedir ancak .NETin derinliklerine daldka ok yeni
kavramlarla karlarz. Bu yeniliklerden en nemlisi diller aras uyumluluk tur. J2EE
platformunda sadece JAVA dili kullanlyorken .NET platformunda birok dil
kulanlabilmektedir. Bu dillerin says olduka fazladr. stelik Microsoft tarafndan .NET
platformu iin sfrdan yeni bir dil tasarlanmtr. Yap olarak C++ ve JAVA dilllerine
benzerlii ile bilinen bu dil Anders Hejlsberg tarafndan gelitirilen C# (C Sharp)tan
baka bir ey deildir..

JAVA, C++ diline nasl benziyorsa C# dilide C++ ve JAVAya benzemektedir.


Programlama modeli yine her ortamda da nesne ynelimlidir. Deien ey bu modelin
uygulan eklidir. C++ta kaynak kod derleyici tarafndan makine koduna, JAVAda
bytecodea C#ta ise IL(Intermediate Language-Ara Dil)a evrilmektedir. Burda
vurgulanmas gereken en nemli nokta JAVAda bytecode JAVA sanal makinesi tarafndan
yorumlanarak altrlrken, .NETte IL kodlar derlenerek altrlmaktadr. Hemen unu
da belirtelim ki, derleme ilemi yorumlama ileminden performans asndan daha
ndedir.

C# dil olarak C++ ve JAVAya ok benzemektedir. Bu yzden C# dilini konuurken


.NET platformunu gz nnde bulundurmalyz. Dilleri sadece birer ara olarak
grmemizde fayda var. sterseniz laf daha fazla uzatmadan JAVA/J2EE ve C#/.NETi
karlatrp benzerliklerini ve farkllklarn ortaya koyalm ardndan C# dier .NET
dillerinden ayran zellikleri inceleyip neden C# sorusuna cevap arayalm.

C# ile .NET mi JAVA ile J2EE mi?

Saf C# ve JAVA dilleri dnldnde birka nokta dnda bu iki dil birbirine
benzemektedir. Bu yzden karlatrma yaparken bu dillerin kullanldklar platformlarda
gz nnde bulundurmak gerekir. sterseniz madde madde her bir zellii iki platform
iin deerlendirelim.

1-) Mimari : .NET ve J2EE alma biimi olarak birbirine ok benzer. Her iki
platformda da uygulama kaynak kodu ara bir koda dntrlr. Aradaki en byk fark
bu ara kodun iletilmesi srasnda grlr. .NETte ara kod alma zamannda
derlendikten sonra altrlrken JAVAda yorumlanarak altrlr.

2-) alma Zaman(Runtime) Mimarisi : J2EE platformundaki Java Sanal


Makinesi ile .NET platformundaki CLR(Common Language Runtime) birimi edeerdedir.
JVM, bytecodeun iletilmesinden sorumlu iken CLR, IL kodlarnn iletilmesinden
sorumludur.

3-) Sistemler Aras Tanabilirlik : Teorik olarak C# ve JAVA ile yazlm


uygulamalar sistemden bamszdrlar. Gnmzde C# ile .NET ortamnda gelitirilen
uygulamalarn bir ok mobil cihazda ve Windows sistemlerinde kullanldn dnrsek
bu teorinin yava yava geree dnt grlebilir. Yakn bir gelecekte .NET
altyapsnn Linux versiyonunun da kaca bilinmektedir. JAVA ise bu konuda kendisini
oktan kantlam durumdadr.

4-) Diller Aras Uyumluluk : J2EE platformunda sadece JAVA dili kullanlrken
.NET ortamnda C#,C++,VB.NET ve hatta JAVA dili bile kullanlabilmektedir. stelik farkl
dillerde yazlm paracklar dier bir dilde sorunsuzca kullanlabilmektedir. Bu sayede
btn programclarn .NET platformunda rahat programlama yapabilmesi salanmtr.
.NET uyumlu herhangi bir dilde gelitirilen btn uygulamalar ayn ara koda
dntrld iin .NET dilleri arasnda byk performans farkllklar meydana gelmez.

5-) Web Servisi Kullanm : Web Servisleri datk yapda gelitirilen


uygulamalarn temel paras olmutur. zellikle iletiimin XML tabanl olmas web
servislerinin nemini gstermektedir. Her iki dil ile web servislerine erimek mmkn
olsada C# ile bir web servisini kullanmak olduka kolaydr. C# ve .NETin web servislerine
kolay erimesi bir avantaj olarak grlebilir.
6-) Bellek Ynetimi : C#ta aynen JAVAda olduu gibi kullanlan nesneleri
toplama programcnn grevi deildir. Kullanlmayan gereksiz nesneler gereksiz nesne
toplaycs tarafndan zaman geldiinde bellekten silinirler. Buna ramen C#
programclar isterse bellei kendileri de ynetebilir. Yani C# dilinde bellek adreslerini
tutan gstericiler(pointer) hala kullanlabilmektedir. JAVA dilinde bu imkan yoktur. C#
JAVA dan ayran en byk fark budur. Zira gsterici kullanm sayesinde geriye dnk
uyumlulukta salanabilmektedir. rnein parametre olarak bir gsterici alan sistem
fonksiyonunu C#ta kullanmak mmkndr.

7-) Veri Tipleri : C# dilinin temel felsefesi hereyin bir nesne olmasdr. Temel
veri trleride dahil olmak zere herey birer nesne olarak tanmlanr. C# ve JAVA
salad temel veri trleri bakmndan birbirlerine ok yakndr.

8-) Tekrar Kullanlabilirlik : Nesne ynelimli programlama modelinin en nemli


zellii gelitirilen snflarn paketlenerek sonradan tekrar tekrar farkl uygulamalarda
kullanlabilmesidir. C# ta snflar isim alanlar(namespace) ierisinde paketlenerek dier
uygulamalar iinde kullanlabilir. Javada ise snflar package dediimiz bir kavramla
paketlenir. Sonu olarak her iki dilde eit oranda bu zellii desteklemektedir. Ancak
C#ta snflarn organizasyonu daha estetik bir ekilde dzenlenmektedir.

9-) Kontrol Mekanizmalar : Kodlarn iinde en ok grlen bloklar olan


for,while ve if gibi yaplar her iki dilde de vardr. C#ta JAVA dilinde olmayan ayrca
foreach dngs bulunmaktadr. foreach dngs ile koleksiyon tabanl nesnelerin
elemanlar arasnda tek ynde rahata dolalabilmektedir.

10-) Tretme ve ok Biimlilik : Nesne ynelimli programlama modelinin C++


dilinden beri kullanlan mekanizmalar olan tretme ve ok biimlilik her iki dilde de
mevcuttur. C++tan farkl olarak C# ve Javada sadece tekli tretme mevcuttur.

11-) stisnai Durumlar Ynetme : Uygulamlarn en byk dman olan


istisnai durumlarn(exceptions) her iki dilde de ele aln biimi hemen hemen ayndr.

12-) Snf Ktphanesi : Veritaban ve dosya ilemleri gibi burada


sayamayacamz bir ok temel ii yapan snflar .NET ve J2EE platformunda mevcuttur.
Gerek bu snflarn organizasyonu gerekse de snflarn kullanl biimi bakmndan .NET
platformunun daha avantajl olduunu syleyebiliriz.

Btn bu maddeler bir btn olarak ele alndnda C#n JAVAdan bir kademe
nde olduu grlmektedir. Bu durum elbette proje yneticilerinin seimlerini
etkilemektedir. Microsoft faktrnde gz nnde bulundurursak C# ve .NETin gelecekte
ok i yapacan sylemek iin mneccim olmaya gerek yok. Bu arada JAVAnn halen
yaygn bir ekilde kullanldn da gzard etmemeliyiz. Bu durum C# ve JAVAnn
seiminde sadece teknik zelliklerin deil ayn zamanda Windows ve Linuxte olduu gibi
sosyal etkenlerinde rol bulunduunu gsteriyor.

Buraya kadar sylediklerimden belki yle bir soru iareti domu olabilir : C# m
JAVA m sorusunu C# m C++ m eklinde sorsak neler deiir? Cevap : ok ey
deiir. Evet C#n JAVA ile olan ilikisi C++ ile olan ilikisinden tamamen farkldr. C# ile
JAVAy ancak saf dil olarak karlatrabiliriz. Yani dilin sentaksndan bahsediyorum. Bu
iki dilin kullanld ortam farkldr. Birinde bir sisteme zgn makine kodu retilirken
dierinde sistemden bamsz ara bir kod oluturulmaktadr. Bu durumda C++ ve C# bir
btn olarak karlatrmay kiisel olarak doru bulmuyorum. nk ikisi farkl
kategorilerde yaryor. Eer bir gn .NETin rettii ara koddaki komutlar ile alan
mikroilemci gelitirilirse o zaman belki C# ile C++ karlatrabiliriz. Peki C# m C++?
Cevap : Her ikiside. Eer irketiniz Intel ilemciler iin bir iletim sistemi gelitiriyorsa
elbette C++ ve C dilleri seilmelidir. irketiniz datk yapda ok geni bir alma a
olan bir uygulama gelitiriyorsa o zaman C# ve .NETi semeniz daha doru olacaktr. Bu
seim bir projede hangi dilin kullanlacan deerlendirmek iindi. e bir de programclar
asndan bakalm. Bir programcnn hem C++ hem C# hemde JAVA bilmesine gerek var
m? Bence gerek var yada yok. Kesin bir cevab verilemez bu sorunun. Daha dorusu bir
programc ihtiya dahilinde herhangi bir programlama dilini kullanabilmelidir. Ancak unu
da unutmayalm ki iyi bir programc ok sayda programlama dili bilen demek deildir. yi
bir programc .NET platformunda olduu gibi programlama dilinden bamsz kod
retebilmelidir.

Dier .NET Dilleri ve C#

Daha ncede dediim gibi .NET paltformunda bir ok programlama dilini


kullanabiliriz. Bu dillerin en nemlileri C#, VB.NET, C++.NET ve J# dilleridir. Bu dillerden
bir tanesinin zel bir konumu vardr. Tahmin edeceiniz gibi bu dil C#tr. C# .NET
platformu iin sfrdan gelitirilmi yeni bir dildir. Dier diller ise eski versiyonlar
deitirilerek .NETe uyumlu hale getirilmitir. zellikle Visual Basic dilinin devam gibi
grnen VB.NET dilinde bir ok radikal deiiklik yaplmtr. rnein VB dili nesne
ynelimli programlama tekniini destekler hale getirilmitir. Bu eklentilerin ok baarl
oloduu sylenemez. nk bu ekildeki zoraki eklentiler dilin en bata tasarlanma
amacna uygunluunu ortadan kalkmaktadr. Bu amala Microsoft, hem nesne ynelimli
programlama tekniine tam destek veren, C++ dilinin gl zelliklerinden yoksun
olmayan ve ayn ekilde Visual Basic dilinin kolaylndan esinlenerek C# dilini kard.

Peki .NET dilleri arasnda C# tercih etmemize neden olacak baka neler var? Her
eyden nce C# renilmesi kolay bir dildir. Az sayda anahtar szck iermesine ramen
bir ok olana programcnn hizmetine sunmutur. C# nesne ynelimli programlama
diline tam destek verdii iinde seilebilir. C#ta deiken kavram neredeyse kalkmtr.
Bunda btn temel veri trleri de dahil olmak zere btn snflarn Object diye
adlandrlan bir snftan tretilmesinin etkisi vardr. C# dili g ve hzllk arasndaki
dengeye estetik bir ekilde korumaktadr. Temsilci ve olaylarla VBdeki olay mantna
benzer bir model sunarken ayn zamanda gstericileri kullanmaya imkan vererek C++
dilinin gl zelliklerinden yoksun brakmamtr. .NET snf ktphanesinin byk bir
ksm C# ile gelitirilmitir. Yani bu ktphaneyi en etkin biimde C# ile kullanabiliriz.
Dahas C# dili .NETin alma mimarisi de gznnde bulundurularak sfrdan tasarland
iin .NETin btn olanaklarndan en etkin biimde C# ile faydalanabiliriz.

C# iin sylenebilecek son sz : C#, modern programlama tekniklerine tam


destek veren, internet ann gerektirdii tm yazlm bileenlerini gelitirmeye izin
veren, hzl ve etkin bir ekilde kodlama yaplabilen, C++ ve JAVAnn gzel ynlerini alp
geriye dnk uyumluluu JAVAda olduu gibi gzard etmeyen bir programlama dilidir.
Sonu

nternetin ve haberleme teknolojisinin ok ileri bir seviyede olduu bir dnemde


internet zerinde kullanlabilecek yazlm bileenlerini programlamak son derece nem
kazanmtr. Her ne kadar C# ve JAVA ncesi dillerle herey yaplabiliyor olsada projelerin
boyutlarnn bymesi bu dillerin artk yetersiz olduunun bir gstergesidir. zellikle yeni
nesil i uygulamalarnda C# ve JAVA, C++tan bir adm nde grnyor. Tabi bu durum
C++ dilinin kt olduunu gstermez. Nitekim C# ve JAVA dillerinin her ikiside C++ dilini
rnek almtr. Deien tek ey gnn ihtiyalardr. Ayn zamanda C# dili JAVA, C+
+.NET, VB.NET ve J# gibi diller nnde de bir adm nde grnyor.
MD5 ile Veri ifreleme

Bu makalemizde herhangi bir string ifadenin nasl MD5 ile ifreleneceini reneceiz. Bu
srada web.config, Panel Nesnesi, Stored Procedure gibi konulara da deineceiz.

Aada verdiim rnek, ou zaman kullandmz Kayt Formu ile Login Formundan
oluuyor. Kayt olurken, email adresi ve parola bilgileri soruluyor. Bunun sonrasnda
parola bilgisi MD5 algoritmas ile ifrelenip veritabanna veriler yazlyor.

Login Formumuzda ise, ayn veriler istenerek, yine parolamz MD5 algoritmas ile
veritabanna gnderiliyor. Yani SQL'deki "Select" cmlesi aracl ile kontrolmz
yapyoruz.

rneimize gemeden nce rneimiz ierisinde kullandmz Panel nesnemizin baz


zelliklerini inceleyelim.

Height = Panelimizin ykseklii (pixel cinsinden)


Width = Panelimizin genilii (pixel cinsinden)
BackColor = Panelimizin arkafon rengi
BackImageUrl = Panelimizin arkasnda resim gstermek istiyorsak
BorderColor = Panelimizin snr izgisinin rengi
BorderWidth = Panelimizin snr izgisinin genilii (pixel cinsinden)
Font = Panelimizin ierisinde gsterilecek metinlerin Font ad
Visible = Panelimizin grntlenme ayar (true/false deerleri alr)

imdi de veritabanna balanmak amal kullandmz balant satrmz nasl


kullandmza bakalm.

Klasik ASP ierisinde veritabanna balanmak istediimizde bunu ou zaman asp


dosyamzn ierisine yazyorduk. Veya baka bir sayfaya yazp, onu kullanacamz
sayfaya dahil ediyorduk. Hatrlarsanz bu ynteme "Include File" yntemi deniyordu. Bu
durum gvenlik asndan birok ak ortaya kartmak ile beraber, yetersiz de kalyordu.

.Net'te ise bu skntlar atlatld. imdi projemiz ile ilgili birok veriyi saklayabileceimiz,
gvenli bir dosyaya kavutuk. te bu dosyann ad web.config

Web.config dosyasnn ayrntlarn burada ileyemeyeceim. Sadece veritaban balant


satrmz nasl web.config sayfamza yazmamz gerektiini ve aspx dosyamzdan nasl
arldn gstereceim.

rnein web.config dosyamzn ierii:

<configuration>
<appSettings>
<add key="strConn"
value="server=localhost;uid=dtuser;pwd=dtpass;database=dotnet" />
</appSettings>
</configuration>

Gelelim aspx dosyamzdan nasl arabileceimize:

string dbConnStr = ConfigurationSettings.AppSettings["strConn"];


Sanrm artk konumuza dnebiliriz. lgili tm aklamalar kod satrlar arasnda
anlatmaa altm. Ayrca CodeBehind ynetimi kullanarak kodladm. Bu yntemden de
ksaca bahsetmek gerekirse, CodeBehind yntemi ile kodumuz ile grselliimizi tamamen
ayryoruz. Bylelikle tasarm deiiklii gibi durumlarda hibir sknt ekmiyoruz. rnei
incelediinizde durumu da farkedeceksiniz.

Fakat ncelikle, veritabanamzn yapsn, stored procedure ve web.config dosyamzn ilgili


kodlarn verelim.

Tablomuz:

registerUser

user_id int (IDENTITY)


user_email varchar 255
user_password binary 16

Stored Procedure:

sp_ins_regUser

CREATE PROCEDURE sp_ins_regUser

@user_email varchar(255),
@user_password binary(16)

AS

INSERT INTO
registerUser
(user_email, user_password)
VALUES
(@user_email, @user_password)
GO

sp_sel_loginCheck

CREATE PROCEDURE sp_sel_loginCheck

@uemail varchar(255),
@upwd binary(16)

AS

SELECT
user_id
FROM
registerUser
WHERE
user_email = @uemail AND
user_password = @upwd
GO

Web.config

<configuration>
<appSettings>
<add key="strConn"
value="server=localhost;uid=dtuser;pwd=dtpass;database=dotnet" />
</appSettings>
</configuration>

lk nce grsel arayzmn bulunduu, kiinin kayt olduu sayfa olan:

register.aspx

<%@ Page Language="c#" Inherits="registerForm.regForm" Src="register.aspx.cs"%>


<html>
<body>
<asp:Panel id="register" runat="server">
<form id="regForm" method="post" runat="server">
<table cellspacing="0" cellpadding="3" border="0">
<tr>
<td colspan="2">Kayt Formu</td>
</tr>
<tr>
<td><b>E-posta Adresiniz</b></td>
<td><asp:TextBox id="emailAdr" runat="server"
MaxLength="255"></asp:TextBox></td>
</tr>
<tr>
<td><b>Parolanz</b></td>
<td><asp:TextBox runat="server" MaxLength="10" id="parola"
TextMode="Password"></asp:TextBox></td>
</tr>
<tr>
<td align="right" colspan="2"><asp:Button id="btnOk"
OnClick="doRegister" runat="server" text="Formu Gnder"/></td>
</tr>
</table>
</form>
</asp:Panel>
<asp:Panel id="registerStatus" runat="server">
<asp:Label id="lblInfo" runat="server"></asp:Label>
</asp:Panel>
</body>
</html>
Bu sayfann kodlarn ileyen:

register.aspx.cs

using System;
using System.IO;
using System.Web.UI; //web textbox larna ulaabilmemiz iin gereken class
using System.Security.Cryptography; //md5 iin gerekli class
using System.Text; //UTF fonksiyonu iin gerekli class
using System.Data; //veritaban ilemleri iin gerekli class
using System.Data.SqlClient; //veritaban ilemleri iin gerekli class
using System.Configuration; //web.config dosyamzdan veri okuyabilmek amal class

namespace registerForm
{
public class regForm : System.Web.UI.Page
{
//kodlamada kullanacamz nesnelerimizi tanmlyoruz.
protected System.Web.UI.WebControls.TextBox emailAdr;
protected System.Web.UI.WebControls.TextBox parola;

protected System.Web.UI.WebControls.Panel register;


protected System.Web.UI.WebControls.Panel registerStatus;

protected System.Web.UI.WebControls.Label lblInfo;

public void Page_Load(Object Src, EventArgs E)


{
//sayfa yklendiinde panellerimizin grntlenme ayarlarn
yapyoruz.
//form ekran ilk olarak grntlenecek.
register.Visible = true;
registerStatus.Visible = false;
lblInfo.Text = "";
}

//Formu Gnder butonuna tklandnda alan fonksiyonumuz


protected void doRegister(object sender, System.EventArgs e)
{
//girilen verileri alyoruz.
string txtEmailAdr = emailAdr.Text;
string txtParola = parola.Text;

//ilem sonucu gstermek amal ikinci panelimizi grnr


klyoruz.
register.Visible = false;
registerStatus.Visible = true;

try
{
//parolanz ifrelenmesi iin fonksiyona gnderiyoruz.
//ifrelenmi verimiz byte haline gelecei iin
deikenimizi
//byte olarak tanmlyoruz.
byte[] encyrptedPassword =
md5Password(txtParola);

//veritabanna Email adresini ve ifrelenmi Parolay


kayt ediyoruz.
SqlConnection conn = new
SqlConnection(ConfigurationSettings.AppSettings["strConn"]);
conn.Open();
SqlCommand sc = new SqlCommand ();
sc.Connection = conn;
sc.CommandType = CommandType.StoredProcedure;
sc.CommandText = "sp_ins_regUser";

sc.Parameters.Add("@user_email",
SqlDbType.VarChar, 255, "user_email");
sc.Parameters["@user_email"].Value = txtEmailAdr;
sc.Parameters.Add("@user_password",
SqlDbType.Binary, 16, "user_password");
sc.Parameters["@user_password"].Value =
encyrptedPassword;

sc.ExecuteNonQuery();
conn.Close();

//try-catch blouna soktuumuz ilemimizde bir


sorun kmad ise
//ziyaretimizi bilgilendiriyoruz.
lblInfo.Text = "Kayt ileminiz baar ile
gerekletirilmitir";
}
catch
{
//veritabannda bir hata olutuysa ziyaretimizi
bilgilendiriyoruz.
lblInfo.Text = "Kayt ileminiz srasnda bir hata
olutu. Ltfen tekrar deneyiniz.";
}
}

byte[] md5Password(string pass)


{
//md5 ifrelenmesi iin verimizin byte haline gelmesi gerekli.
//veri 8-bit eklinde dntrlmesi iin ilk nce UTF
fonksiyonuna gnderiliyor.
UTF8Encoding encoder = new UTF8Encoding();
//md5 ifrelemesi iin nesnemizi oluturuyoruz.
MD5 md5 = new MD5CryptoServiceProvider();
//verimizi md5 ile altryoruz.
//dikkat ederseniz UTF fonksiyonundan dnen deeri GetBytes
ile alabildik.
byte[] donenDeger =
md5.ComputeHash(encoder.GetBytes(pass));
//ifrelenmi deerimizi geri gnderiyoruz.
return donenDeger;
}

}
}

Kullanc ad, parola verilerinin girildii grsel sayfa olan:

login.aspx

<%@ Page Language="c#" Inherits="loginForm.Login" Src="login.aspx.cs"%>


<html>
<body>
<asp:Panel id="loginStatus" runat="server">
<asp:Label id="lblInfo" runat="server"></asp:Label>
</asp:Panel>

<asp:Panel id="pnlLogin" runat="server">


<form id="loginForm" method="post" runat="server">
<table cellspacing="0" cellpadding="3" border="0">
<tr>
<td colspan="2">Siteye Giri</td>
</tr>
<tr>
<td><b>E-posta Adresiniz</b></td>
<td><asp:TextBox id="emailAdr" runat="server"
MaxLength="255"></asp:TextBox></td>
</tr>
<tr>
<td><b>Parolanz</b></td>
<td><asp:TextBox id="parola" runat="server"
MaxLength="10" TextMode="Password"></asp:TextBox></td>
</tr>
<tr>
<td align="right" colspan="2"><asp:Button id="btnLogin"
OnClick="doLogin" runat="server" text="Formu Gnder"/></td>
</tr>
</table>
</form>
</asp:Panel>
</body>
</html>

login.aspx dosyamz ileyen sayfamz:

login.aspx.cs

using System;
using System.IO;
using System.Web.UI; //web textbox larna ulaabilmemiz iin gereken class
using System.Security.Cryptography; //md5 iin gerekli class
using System.Text; //UTF fonksiyonu iin gerekli class
using System.Data; //veritaban ilemleri iin gerekli class
using System.Data.SqlClient; //veritaban ilemleri iin gerekli class
using System.Configuration; //web.config dosyamzdan veri okuyabilmek amal class

namespace loginForm
{
public class Login : System.Web.UI.Page
{
//kodlamada kullanacamz nesnelerimizi tanmlyoruz.
protected System.Web.UI.WebControls.TextBox emailAdr;
protected System.Web.UI.WebControls.TextBox parola;

protected System.Web.UI.WebControls.Panel pnlLogin;


protected System.Web.UI.WebControls.Panel loginStatus;

protected System.Web.UI.WebControls.Label lblInfo;

public void Page_Load(object sender, System.EventArgs e)


{
//sayfa yklendiinde panellerimizin grntlenme ayarlarn
yapyoruz.
//form ekran ilk olarak grntlenecek.
pnlLogin.Visible = true;
loginStatus.Visible = false;
lblInfo.Text = "";
}

//Formu Gnder butonuna tklandnda alan fonksiyonumuz


protected void doLogin(object sender, System.EventArgs e)
{
//girilen verileri alyoruz.
string uid = emailAdr.Text;
string pwd = parola.Text;

//ilem sonucu gstermek amal ikinci panelimizi grnr


klyoruz.
pnlLogin.Visible = false;
loginStatus.Visible = true;

//parolanz ifrelenmesi iin fonksiyona gnderiyoruz.


//ifrelenmi verimiz byte haline gelecei iin deikenimizi
//byte olarak tanmlyoruz.
byte[] encyrptedPwd = md5Password(pwd);

//veritabanna ilgili verileri gndererek kontrolmz yaparz.


SqlConnection conn = new
SqlConnection(ConfigurationSettings.AppSettings["strConn"]);
conn.Open();
SqlCommand sc = new SqlCommand ();
sc.Connection = conn;
sc.CommandType = CommandType.StoredProcedure;
sc.CommandText = "sp_sel_loginCheck";
sc.Parameters.Add("@uemail", SqlDbType.VarChar, 255,
"uemail");
sc.Parameters["@uemail"].Value = uid;
sc.Parameters.Add("@upwd", SqlDbType.Binary, 16, "upwd");
sc.Parameters["@upwd"].Value = encyrptedPwd;

try
{
//Elimizdeki verilerle altrdmz SP'mizden geri bir
kolon, bir satr dnd
//iin SqlCommand nesnesinin ExecuteScalar()
metodunu kullanyoruz.
//user_id uanda bizim iimize yaramyor, fakat nasl
ekildiini gstermek amac ile
//bu satr da kodumuza ekledim.
string user_id = sc.ExecuteScalar().ToString();
//Email ve parola doru ise bilgilendiriyoruz.
lblInfo.Text = "Hogeldiniz ";
}
catch
{
//Email ve parola yanlsa tekrar girmesini istiyoruz.
lblInfo.Text = "Yanl E-posta Adresi/Parola. Ltfen
bilgilerinizi kontrol edip tekrar deneyiniz.";
}
conn.Close();
}

byte[] md5Password(string pass)


{
//md5 ifrelenmesi iin verimizin byte haline gelmesi gerekli.
//veri 8-bit eklinde dntrlmesi iin ilk nce UTF
fonksiyonuna gnderiliyor.
UTF8Encoding encoder = new UTF8Encoding();
//md5 ifrelemesi iin nesnemizi oluturuyoruz.
MD5 md5 = new MD5CryptoServiceProvider();
//verimizi md5 ile altryoruz.
//dikkat ederseniz UTF fonksiyonundan dnen deeri GetBytes
ile alabildik.
byte[] donenDeger =
md5.ComputeHash(encoder.GetBytes(pass));
//ifrelenmi deerimizi geri gnderiyoruz.
return donenDeger;
}

}
}
C# ve GDI+ Kullanlarak Yaplan DXBALL Oyunu

Bu yazida anlatacagim oyun, bazilarinin DXBall, bazilarinin Alleyway diye bildigi bir ok
ismi olan bir oyun.

Oyunun tm dosyalari burada verilmeyecktir ancak .NET ile yeni bir proje ailip .cs
dosyalari kopyalanirsa, oyun alisacaktir. Ayrica oyunda kullanilan top,blok sekilleri iin
gerekli olan resimleri de istediginiz gibi seebilirsiniz. Top resminin dosya adi tp.bmp,
bloklarin dosya adi brick.bmp, alttaki cubuk resminin dosya adi ise blk.bmp olmak
zorundadir.'dir. Oyunu normal haliyle alistirmak istiyorsaniz download edebilirsiniz.
(Bilgisayarda .NET ve Framework 1.1 kurulu olmak zorunda! )

Programi derleyip alistirdiginizda oyunun ekran grntsnn asagidaki gibi oldugunu


greceksiniz.

Oyunun kaynak kodunu indirmek iin tiklayin.

nemli: Siniflarin neler oldugunu uzun uzun paragraflar halinde anlatmaktansa kodun
yaninda komut satirlariyla anlatilacaktir.
Simdi adim adim oyunu aiklayalim;

o Ilk olarak Top.cs dosyamiz var. top sinifimizda, en nemli metot olan move
metodunda topun koordinatlarina bakilir ve koordinatlara gre ne tarafa
hareket ettirilecegi belirlenir.

Top.cs:

using System;

using System.Drawing;

using System.Drawing.Imaging;

namespace alleyway

public class Top

public Point pos; //topun koordinatlarini tutmaya yarayacak.

private Bitmap tp=null; //topun resmi iin gerekli.

public int Xhareket=4; //topun x'de hareket hizini burada belirleyecegiz.

public int Yhareket=4; //topun y'de hareket hizini burada belirleyecegiz.

public Top(int x,int y)

pos.X = x; //ana formdan gelen topun nerede baslatilacagi bilgisi

pos.Y = y; // burada x ve y koordinatlari olarak girilir.

if (tp==null) //eger resim yklenmediyse ykleme islemi yapilacak.

tp = new Bitmap("tp.bmp");

public Rectangle GetFrame()

Rectangle myRect = new Rectangle(pos.X, pos.Y, tp.Width, tp.Height);


return myRect; //top nesnemizin konumunu dikdrtgen olarak belirlememize yarar.

} // bu sayede top ile bloklarin arpisip arpismadigini daha kolay

//anlayacagiz.

public void Draw(Graphics g)

g.DrawImage (tp,pos.X,pos.Y,tp.Width ,tp.Height ); //top nesnesi ekrana

//izdirilir. X,y koordinatlarindan sonra ebatlari parametre olarak girilir.

public void Remove(Top t)

Yhareket=-Yhareket;

pos.X += Xhareket;

pos.Y += Yhareket;

public void Move(int hak,Grup grp,Top t,Rectangle r, Rectangle rblok)

//topun pencere icinde duvarlara ve cubuga carptika simetrik olarak sekmesini

//burada saglayacagiz.

if(t.GetFrame().IntersectsWith(rblok)) //eger top bloka arptiysa,

Yhareket=-Yhareket; // topun y ynn ters cevir

} // bylelikle sekmeyi sagla.

//top ekrandaysa,

if(pos.X > 539 || pos.X < 0)

//topun x hareketini ters cevir

Xhareket = -Xhareket;
}

// top yukari carparsa

if(pos.Y < 0)

//y hareketini degistir

Yhareket = -Yhareket;

}// yanarsa,

else if(pos.Y > 500)

//top durur

Xhareket = 0;

Yhareket = 0;

//hakki 1 azalt

hak -= 1;

// top koordinatlarini degistir

pos.X += Xhareket;

pos.Y += Yhareket;

o Blok.cs sinifi ise alt taraftaki ynlendirecegimiz cubuktur.

Blok.cs:

using System;

using System.Drawing;

using System.Drawing.Imaging;

namespace alleyway
{

public class Blok

public Point pos; //x ve y koordinatlarini belirlemek iin kullanilacak.

static Bitmap Cubuk = null; //ubuk resmi iin kullanilacak.

int inc = 6; //ubugun srkleme hizini belirleyecek

int LastposX = 0; //su anda son pozisyon olmadigindan ikisi de sifirlanir.

int LastposY = 0;

public Blok(int x, int y)

pos.X = x; //x konumu verilir.

pos.Y = y; /y konumu verilir.

if (Cubuk == null) //ubuk ekranda yoksa,

Cubuk = new Bitmap("blk.bmp"); //ubuk ekrana izdirilir.

public Rectangle GetFrame()

Rectangle myRect = new Rectangle(pos.X, pos.Y, Cubuk.Width, Cubuk.Height); //top


sinifindaki islevi grr.

return myRect;

public void Draw(Graphics g)

Rectangle destR = new Rectangle(pos.X, pos.Y, Cubuk.Width, Cubuk.Height); //ubuk


hareketlerinde kullanilacak.

Rectangle srcR = new Rectangle(0,0, Cubuk.Width, Cubuk.Height);


g.DrawImage(Cubuk, destR, srcR, GraphicsUnit.Pixel);

LastposX = pos.X;

LastposY = pos.Y;

public void MoveLeft(Rectangle r)

if (pos.X <= 0) //eger pencerenin en solundaysa hareket etmeyecek, degilse sola dogru
hareketine devam edecektir.

return;

pos.X -= inc;

public void MoveRight(Rectangle r)

{ //eger pencerenin en sagindaysa hareket etmeyecek, degilse saga dogru hareketine


devam edecektir.

if (pos.X >= r.Width - Cubuk.Width)

return;

pos.X += inc;

o Brick.cs sinifi ise patlatilacak bloklari temsil eder. Burada sadece basit
zellikleri tutlur. Bloklari kontrol eden Grup sinifinda tm bloklari ayni anda
kontrol edildigini greceksiniz. Grup sinifinda tm bloklari tutan bir matris
bulunmaktadir.

Brick.cs:

using System;
using System.Drawing;

using System.Drawing.Imaging;

namespace alleyway

public class Brick

public int yukseklik,genislik,basx,basy; //bloklarin zellikleri burada tutulur.

public bool vuruldu=false; //top tarafindan vurulup vurulmadigi buradan anlasilacaktir.

public Brick(int yuk,int gen,int startx,int starty)

this.yukseklik=yuk;

this.genislik=gen;

this.basx=startx;

this.basy=starty;

this.vuruldu=false; //yeni yaratildigi iin vurulmadi oalarak isaretlenir.

o Grup.cs sinifinda ise blok kontrol yapilir.

Grup.cs:

using System;

using System.Drawing;

using System.Drawing.Imaging;

namespace alleyway

public class Grup

{
Bitmap br=null;

public Brick[,] yapi; //brick sinifinda nesneleri tutan matrisimiz burada yaratiliyor.

int sut=5; //bloklarin stun ve satir sayilari bu kisimda girilir.

int sat=8;

public Grup()

reset(); //vurulmus duurmda olan bloklar varsa bunlari da vurulmadi olarak isaretleyen
ve ilk haline dndren metod agrilir.

public void Draw(Graphics g)

for (int i=0;i<SAT;I++)< font>

{ // bu i ie for dngleri blmnde bloklar tek tek dolasilarak

for (int j=0;j< izdirilmez) yapilir(ekrana grnmez varsa olan vurulmus>

{ // vurulmayanlar ise ayni sekilde ekrana izdirilir.

if (yapi[i,j].vuruldu==false)

Brick temp= (Brick) yapi[i,j];

g.DrawImage(br,temp.basx,temp.basy,br.Width,br.Height);

public void reset(){ //tm bloklar tekrar olusturulur.

yapi = new Brick[sat,sut];

if (br==null)

{
br = new Bitmap("Brick.bmp");

for (int i=0;i< olarak vurulmadi bloklar dolasilarak matris>

for (int j=0;j<SUT;J++)< font>

yapi[i,j]=new Brick(br.Height,br.Width,(i) * 65 +20, (j * 35) + 50);

yapi[i,j].vuruldu=false;

o Form1.cs,oyunun ana formudur yani ekranimizdir. Bu formda esas nemli


olan yerler aiklanacaktir.

Form1.cs:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Threading;

using System.Runtime.InteropServices;

namespace alleyway

public class Form1 : System.Windows.Forms.Form


{

public int Hak=3; //ka hakkimiz oldugunu belirleriz.

int puan=0; //puan baslangita sifirdir.

private bool flag = true;

private Blok blok = new Blok(275, 490); //alttaki ubugun yeri belirlenir.

private Top top = new Top(250, 300); // topun konumu belirlenir.

private Grup grup=new Grup();

private System.Windows.Forms.Timer timer1;

private System.ComponentModel.IContainer components;

public Form1()

InitializeComponent();

timer1.Start(); //top hareketleri ve ekran degisimleri bu timer sayesinde


belirlenir. Her 50 salisede ekran tekrar

//izdirilir.

SetStyle(ControlStyles.UserPaint, true);

SetStyle(ControlStyles.AllPaintingInWmPaint, true);

SetStyle(ControlStyles.DoubleBuffer, true);

protected override void Dispose( bool disposing ) //bu kodlari .net kendisi yaratir.

if( disposing )

if (components != null)

components.Dispose();

}
}

base.Dispose( disposing );

#region Windows Form Designer generated code

///

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

///

private void InitializeComponent()

this.components = new System.ComponentModel.Container();

this.timer1 = new System.Windows.Forms.Timer(this.components);

// timer1 ezlliklerini burada tanimlariz.

this.timer1.Enabled = true;

this.timer1.Interval = 50;

this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

// Form1 iin yapilan degisiklier buradadir.

this.AutoScaleBaseSize = new System.Drawing.Size(6, 16);

this.ClientSize = new System.Drawing.Size(550, 500);

this.Font = new System.Drawing.Font("Comic Sans MS", 8.25F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)
(0)));

this.KeyPreview = true;

this.Location = new System.Drawing.Point(150, 200);

this.MaximizeBox = false;

this.Name = "Form1";

this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

this.Text = "PatLat";
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);

this.Load += new System.EventHandler(this.Form1_Load);

this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

#endregion

[STAThread]

static void Main()

Application.Run(new Form1());

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

Graphics g = e.Graphics;

g.FillRectangle(Brushes.Black, 0, 0, this.ClientRectangle.Width, ClientRectangle.Height);

blok.Draw(g); //oyunumuzdaki tm nesneler ekrana izdirilir.

top.Draw (g);

grup.Draw(g);

private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

{ //bu kisimda tusa basilinca ubugun hareket ettirilmesi gereklestirilmistir.


Case yapisi iinde sag saol hareketleri

//yapilir.

string result = e.KeyData.ToString();

Invalidate(blok.GetFrame());

switch (result)

case "Left": //sol tusuna basildiysa sola git


blok.MoveLeft(ClientRectangle);

Invalidate(blok.GetFrame()); //tekrar blogu izdir.

break;

case "Right": //sag tusuna basildiysa saga git

blok.MoveRight(ClientRectangle);

Invalidate(blok.GetFrame());//tekrar blogu izdir.

break;

default:

break;

private void timer1_Tick(object sender, System.EventArgs e)

{ //timer 'in her tikinde top ve bloklar kesisti mi? kontrol yapilir ve kesisme
varsa o blok vuruldugu iin ekrandan silinir.

flag=true;

for (int i=0;i<8;i++)

for (int j=0;j<5 ;j++)

Rectangle r_brick = new


Rectangle(grup.yapi[i,j].basx,grup.yapi[i,j].basy,grup.yapi[i,j].genislik,grup.yapi[i,j].yuks
eklik);

if(top.GetFrame().IntersectsWith(r_brick))

if (grup.yapi[i,j].vuruldu==false)

grup.yapi[i,j].vuruldu=true;

top.Remove(top); //ekrandan topun silinmesi.


puan=puan+10; //blok vuruldu, puani arttir.

flag=false;//yanmadigimizi belirtmek iin flag false yapilir

if (flag) //flag true ise yandi demektir.

top.Move (Hak,this.grup,this.top,ClientRectangle, blok.GetFrame ());

if (top.pos.Y>500)

timer1.Stop(); //hareketi durdur.

Hak--; //hakki 1 azalt

if (Hak==0) //eger hak sifir ise,

Form3 form3=new Form3(puan); //oyun bitti ekranini gster.

form3.ShowDialog(this);

if (form3.DialogResult==DialogResult.OK) // O ekranda tekrar oynaya basilirsa,

Hak=3; //hakki 3'e ikar,

puan=0; //puani sifirla ve tekrar baslat.

top.pos.X=265;

top.pos.Y=300;

blok.pos.X=275;

blok.pos.Y=490;

grup.reset();

top.Xhareket=-top.Xhareket;
Invalidate();

timer1.Start();

else //hak sifir olmadiysa,

Form2 form2=new Form2(Hak); //ka hakki oldugunu, puanini gster,oyuna devam


et

form2.ShowDialog(this);

top.pos.X=250;

top.pos.Y=250;

blok.pos.X=275;

blok.pos.Y=490;

top.Xhareket=-top.Xhareket;

Invalidate();

timer1.Start();

flag=true;

Invalidate();

o Simdi kodunu greceginiz iki form ise oyun bitince ve yaninca gsterilen
formlar oldugundan aiklanacak bir blm iermemektedirler.
Oyun Bitince gsterilen form:

Form3.cs:
using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

namespace alleyway

///

/// Summary description for Form3.

///

public class Form3 : System.Windows.Forms.Form

int ppuan;

private System.Windows.Forms.Label label1;

private System.Windows.Forms.Label label2;

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Label label3;

private System.Windows.Forms.Button OK;

///

/// Required designer variable.

///

private System.ComponentModel.Container components = null;

public Form3(int puan)

//

// Required for Windows Form Designer support


//

ppuan=puan;

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

///

/// Clean up any resources being used.

///

protected override void Dispose( bool disposing )

if( disposing )

if(components != null)

components.Dispose();

base.Dispose( disposing );

#region Windows Form Designer generated code

///

/// Required method for Designer support - do not modify


/// the contents of this method with the code editor.

///

private void InitializeComponent()

this.label1 = new System.Windows.Forms.Label();

this.label2 = new System.Windows.Forms.Label();

this.OK = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.label3 = new System.Windows.Forms.Label();

this.SuspendLayout();

//

// label1

//

this.label1.Font = new System.Drawing.Font("Bookman Old Style", 15.75F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)
(0)));

this.label1.Location = new System.Drawing.Point(48, 8);

this.label1.Name = "label1";

this.label1.Size = new System.Drawing.Size(144, 32);

this.label1.TabIndex = 0;

this.label1.Text = "Oyun Bitti!..";

//

// label2

//

this.label2.Font = new System.Drawing.Font("Bookman Old Style", 15.75F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)
(0)));

this.label2.Location = new System.Drawing.Point(8, 48);

this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(112, 24);

this.label2.TabIndex = 1;

this.label2.Text = "Puaniniz:";

//

// OK

//

this.OK.DialogResult = System.Windows.Forms.DialogResult.OK;

this.OK.Location = new System.Drawing.Point(24, 88);

this.OK.Name = "OK";

this.OK.TabIndex = 2;

this.OK.Text = "Baslat";

this.OK.Click += new System.EventHandler(this.button1_Click);

//

// button2

//

this.button2.Location = new System.Drawing.Point(136, 88);

this.button2.Name = "button2";

this.button2.TabIndex = 3;

this.button2.Text = "Yeter";

this.button2.Click += new System.EventHandler(this.button2_Click);

//

// label3

//

this.label3.Font = new System.Drawing.Font("Bookman Old Style", 15.75F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)
(0)));

this.label3.Location = new System.Drawing.Point(120, 48);

this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 24);

this.label3.TabIndex = 4;

this.label3.Click += new System.EventHandler(this.label3_Click);

//

// Form3

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.BackColor = System.Drawing.Color.SkyBlue;

this.ClientSize = new System.Drawing.Size(234, 122);

this.ControlBox = false;

this.Controls.Add(this.label3);

this.Controls.Add(this.button2);

this.Controls.Add(this.OK);

this.Controls.Add(this.label2);

this.Controls.Add(this.label1);

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

this.MaximizeBox = false;

this.MinimizeBox = false;

this.Name = "Form3";

this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

this.Load += new System.EventHandler(this.Form3_Load);

this.ResumeLayout(false);

#endregion

private void Form3_Load(object sender, System.EventArgs e)

{
this.label3.Text = ppuan.ToString();

private void button2_Click(object sender, System.EventArgs e)

Application.Exit();

o Yaninca gsterilen form

Form2.cs:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

namespace alleyway

///

/// Summary description for Form2.

///

public class Form2 : System.Windows.Forms.Form

int hhak;

private System.Windows.Forms.Label label2;

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Label label1;


///

/// Required designer variable.

///

private System.ComponentModel.Container components = null;

public Form2(int hak)

//

// Required for Windows Form Designer support

//

hhak=hak;

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

///

/// Clean up any resources being used.

///

protected override void Dispose( bool disposing )

if( disposing )

if(components != null)

{
components.Dispose();

base.Dispose( disposing );

#region Windows Form Designer generated code

///

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

///

private void InitializeComponent()

this.label2 = new System.Windows.Forms.Label();

this.button1 = new System.Windows.Forms.Button();

this.label1 = new System.Windows.Forms.Label();

this.SuspendLayout();

//

// label2

//

this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));

this.label2.Location = new System.Drawing.Point(176, 32);

this.label2.Name = "label2";

this.label2.Size = new System.Drawing.Size(40, 40);

this.label2.TabIndex = 5;

//
// button1

//

this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F,


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));

this.button1.Location = new System.Drawing.Point(232, 16);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(88, 40);

this.button1.TabIndex = 4;

this.button1.Text = "Devam";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// label1

//

this.label1.Font = new System.Drawing.Font("Comic Sans MS", 16F,


System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));

this.label1.Location = new System.Drawing.Point(24, 0);

this.label1.Name = "label1";

this.label1.Size = new System.Drawing.Size(136, 80);

this.label1.TabIndex = 3;

this.label1.Text = "Yandiniz!.. Kalan Hak =";

//

// Form2

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.BackColor = System.Drawing.Color.SkyBlue;

this.ClientSize = new System.Drawing.Size(330, 79);

this.ControlBox = false;
this.Controls.Add(this.label2);

this.Controls.Add(this.button1);

this.Controls.Add(this.label1);

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

this.MaximizeBox = false;

this.MinimizeBox = false;

this.Name = "Form2";

this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

this.Load += new System.EventHandler(this.Form2_Load);

this.ResumeLayout(false);

#endregion

private void Form2_Load(object sender, System.EventArgs e)

label2.Text=hhak.ToString();}

private void button1_Click(object sender, System.EventArgs e)

this.Close();

}
C# ile Yazc kts Alma lemleri

C# ile Windows i uygulamas gelitiriyorsanz programnzn mutlaka yazc kts


alma blm olacaktr. Bu makalede C# ile nasl yazc kts alnabileceinin
temelleri zerinde duracam.

.NET snf ktphanesi her alanda olduu gibi yazc kts alma ile ilgili bir takm snflar
salamtr. PrintDocument snf yaz kts alma ile ilgili en temel snftr. Bu yazda bu
snfn zelliklerini, olaylarn ve metotlarn ayrntl bir ekilde inceleyip tek sayfal yada
ok sayfal yazc ktsnn nasl alnabileceini gstereceim. Ayrca yazc kts alma ile
ok yakndan ilgili olan PrintPreview, PageSetupDialog ve PrintDialog gibi snflarda
inceleyeceiz.

PrintDocument Snf

Bu snf programlarmza yazc kts alma desteini eklemek iin kullanabileceimiz en


temel yapdr. Bu snf trnden bir nesne yaratldnda kt alma ile ilgili hemen her tr
bilgiye erimemiz mmkndr.

PrintDocument YaziciCiktisi = new PrintDocument();

eklinde bir tanmlama yaptmzda varsaylan yazc(default printer) ile allmaktadr.


Bir dkman yazcya gndermek iin PrintDocument snfnn Print() metodu kullanlr.
Print() metodu arld anda PrintPage olay meydana gelir. Bu olay yakalayan kontrol
yazcya gnderilecek dkman zerinde ilemler yaparak ktnn eklini belirlemelidir.
Her bir sayfa iin ayrca PrintPage olay meydana gelecei iin her bir olay iinde doru
sayfalar yazcya gndermek iin bir takm ilemler yapmak gerekecektir. Aksi halde her
defasnda birinci sayfay yazcya gnderme ihtimalimiz vardr. Ksacas PrintPage olay
olmadan yazcya kt bilgilerini gnderemeyiz. Bu yzden ilk olarak PrintPage olayn ve
bu olaya ait argmanlar ieren PrintPageEventArgs snfn inceleyelim.

nce PrintPage olaynn argmanlarn ieren PrintPageEventArgs snfnn ye


elemanlarn inceleyelim, ardnda bir konsol uygulamasndan yazcya nasl bir dkman
gndereceimizi gstereceim.

PrintPageEventArgs snfnn ye elemanlar :

Graphics : Yazcya gnderilecek dkman bilgilerini belirleyen grafik nesnesidir. Yazcya


gnderilecek bilgilerin tamam bu nesne ierisinde belirtilecektir. Not : Graphics snf
GDI+ ktphanesinin en nemli snfdr.

Cancel : kt alma ileminin iptal edilip edilemeyecei ile ilgili bilgi veren bool trnden
bir elemandr. Eer deeri true ise kt alma ilemi iptal edilecektir.

HasMorePages : Yazcya gnderilecek ktnn birden fazla sayfa kaplad durumlarda


PrintPage olayna ilikin metotta bu zelliin true olarak deitirilmesi gerekir. Bylece
bundan sonraki PrintPage olaylarnda bu deiken kontrol edilerek dier sayfalarn ktya
gnderilmesi ile ilgili ilemler yaplr.

MarginBounds : Yazcya gnderilen kt dkmannn en ve boyutlarn temsil eden


Rectangle trnden bir zelliktir. Rectangle snfda GDI+ ktphanesinin bir parasdr.
Bu zellikte yazcya gnderilecek ktnn sadece zerine izim yaplabilen ksm belirtilir.

PageBounds : Yazcya gnderilen dkmann tamamnn en ve boy deerlerini tutan


yine Rectangle snf trnden bir elemandr.
PageSettings: lgili dkmana ait sayfa ayarlarn tutan ve PageSettings snf
trnden bir elemandr. PageSettings snfnn Color, Landscape, Margins, PaperSize,
PaperSource, PrinterResolution gibi sayfa ile ilgili bilgi tutan ye zellikleri bulunmaktadr.

imdi basit bir rnekle yazcya kt gnderelim. rneimizde varsaylan yazcnza, sol
st kesi (20,20) koordinatlarnda eni ve boyu 100 olan bir drtgen ieren sayfay
gndereceiz. Gnderilecek sayfadaki drtgeni izmek iin tahmin edeceiniz zere
Graphics nesnesini kullanacaz.

using System;
using System.Drawing.Printing;
using System.Drawing;

class Printer
{
static void Main()
{
PrintDocument PD = new PrintDocument();
PD.PrintPage += new PrintPageEventHandler(OnPrintDocument);

try
{
PD.Print();
}
catch
{
Console.WriteLine("Yazc kts alnamyor...");
}
finally
{
PD.Dispose();
}
}

private static void OnPrintDocument(object sender, PrintPageEventArgs e)


{
e.Graphics.DrawRectangle(Pens.Red,20,20,100,100);
}
}

Yukardaki program derleyip altrdnzda hi bir uyar eer verilmeden sisteminize bir
yazc bal OnPrintDocument() metodunda hazrlanan ierik yazcya gnderilecektir.
Eer sisteminize bal bir yazc yoksa doal olarak catch bloundaki kod alacaktr.

izilen drtgen nesnesinin kadn neresine baslacan biz belirliyoruz. MarginBounds


zelliini kullanarak izilecek ieriin doru noktaya izilmesini salayabiliriz. Bu zellik
sizin yazc ayarlarnz ile ilgili olduu iin programlama yolu ile kod ierisinden
deitirilemez. Yani bu zellik "read only" bir zelliktir. Dikkat edilmesi gereken dier bir
noktada yazcya gnderilecek ieriin PageBounds zellii ile belirtilen drtgenin dna
tamamasdr. Bu yzden izimleri yaplrken bu zellik baz alnmaldr.

Yukarda yazdmz basit programda eksiklik bulunmaktadr. Bu eksiklik izilecek


drtgenin tek bir sayfaya smad durumlarda grlr. Sz gelimi eer drtgenin
yksekliini 2000 yaparsak yazcdan sadece ilk kada san blm kacaktr. Birden
fazla sayfas olan ktlar yazcya gndermek iin PrintPageEventArgs snfnn
HasMorePages zellii kullanlr. Bu zellik OnPrintDocument() metodu ierisinde true
deerine ekilerek kt alma ileminin devam ettii belirtilmelidir. Ayrca her bir sayfann
ieriide metot her arldnda farkl bir biimde oluturulaca iin programcnn bu
ayrm da kodlamas gerekmektedir. rnein ykseklii 2000 pixel olan bir dikdrtgeni
tek sayfada bastramayacamz iin ilk sayfaya smayan dier blmleri paralayarak
her bir sayfaya sacak ekilde ayarlamalyz. Bu ilem iin PrintPageEventArgs snfnn
HasMorePages deikenini kullanacaz.

Hemen dier blmlere gemeden nce birden fazla sayfal yazc kts alma ilemine
rnek verelim. Bu rnekte bir text dosyasnn ieriini yazcya nasl gnderebileceimizi
inceleyeceiz. Tabi burda yaznn birden fazla sayfada olup olmadnn kontroln
yapmamz gerekir. Yazlar yazc ktsna gndermek iin Graphics snfnn DrawString
metodunu kullanacaz. Bu metot grafik arayzne belirli bir fontta ve font byklnde
yaz yazmamz salar. nce rnei inceleyelim ardndan rnek zerinde biraz
konuacaz.

using System;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;

class Printer
{
private static StreamReader dosyaAkimi;

static void Main(string[] args)


{
dosyaAkimi = new System.IO.StreamReader("C:\\Print.txt");

PrintDocument PD = new PrintDocument();


PD.PrintPage += new PrintPageEventHandler(OnPrintDocument);

try
{
PD.Print();
}
catch
{
Console.WriteLine("Yazici iktisi alinamiyor...");
}
finally
{
PD.Dispose();
}
}

public static void OnPrintDocument(object sender,PrintPageEventArgs e)


{
Font font = new Font("Verdana", 11) ;
float yPozisyon = 0 ; int LineCount = 0 ;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;

string line=null;

float SayfaBasinaDusenSatir = e.MarginBounds.Height / font.GetHeight() ;


while (((line=dosyaAkimi.ReadLine()) != null) && LineCount <
SayfaBasinaDusenSatir)
{
yPozisyon = topMargin + (LineCount * font.GetHeight(e.Graphics));
e.Graphics.DrawString (line, font, Brushes.Red, leftMargin,yPozisyon);

LineCount++;
}

if (line = = null)
e.HasMorePages = false ;
else
e.HasMorePages = true ;

}
}

Yukardaki program herhangi bir text formatndaki dosyay yazcya gnderek kt


almanz salayacaktr. Dosyann ieriini yazcya gnderirken ktnn ne ekilde olaca
tamamen programlama yolu ile bizim tarafmzdan yaplmaktadr. rnein ktnn yaz
fontunu GDI+ ktphanesinin bir snf olan Font ile yaz renginide yine GDI+
ktphanesinin Brushes snfnn ye elemanlar ile rahatlkla deitirebiliriz.

Yukardaki rnek uygulamada en nemli ksm dosya ieriinin yazcy gnderilmesi


srasnda grlr. Dosya ieriinin birden fazla sayda sayfa iermesi durumunda dosya
akmndan bir sayfaya sacak kadar satr okunmaldr. Eer dosya akmnn sonuna
gelinmediyse HasMorePages zellii true yaplarak OnPrintDocument metodunun
yeniden arlmas gerekir. Kaynak koddanda grdnz zere dosya akmndan okunan
satr null deereeit olduunda yani dosyann sonuna gelindiinde HasMorePages zeliii
false yaplarak Print() metodunun icras sonlandrlmtr.

Bir dier nemli nokta ise yazcya gnderilecek her bir sayfada ka satrn bulunacann
belirlenmesidir. Sayfa bana den satr says, sayfann yazcya gnderilecek
blmnn yksekliinin yani e.MarginBounds.Height 'in ktya gnderilecek yazya
ait fontun yksekliine blm ile elde edilir. Sayfa bana en satr says elde
edildikten sonra herbir sayfann ierii while dngs yardm ile hazrlanr. Okunan satr
says null deere eit olmayana kadar ve okunan satr says sayfa bana den satr
says olana kadar dngye devam edilir. Dng ierisinde PrintPageEventArgs olay
argmanlarn ieren snfn Graphics nesnesine DrawString() metodu yardmyla dosya
akmndan okunan satr yazlr. Bir sonraki satrn kt ekrannn neresinden balayacan
tutmak iin ise her bir satr okunduunda yPozisyon'u kullanlan font'un ykseklii kadar
artrlr. Btn bu ilemleri yaptktan sonra HasMorePages zellii ayarlanr ki sonraki
sayfalar ktya gnderilsin. Eer dosya sonuna gelinmise artk baslacak sayfa yok
demektir ve HasMorePages zellii false olarak belirlenir.

Not : Dosya akmnn neden OnPrintDocument() metodunun iinde tanmlanmadn


merak ediyor olabilirsiniz. Bunun sebebi OnPrintDocument() metodunun her bir sayfa iin
yeniden arlmasdr. Eer dosya akmn bahsi geen metotta tanmlam olsaydk her
defasnda dosya akm batan okunaca iin hi bir zaman dosya akmnn sonuna
gelemeyecektik ve her defasnda sonsuza dek ilk sayfay ktya gndermi olacaktk. Bu
yzden dosya akmn global dzey diyebileceimiz bir noktada yani ana snfmn bir ye
elaman olacak ekilde tanmladk.

Aklnza taklm olabilecek dier bir nokta ise yazcnn renk ayarlardr. Eer yazcnz
renkli kt almay desteklemiyorsa DrawString() metoduna parametre olarak getiimiz
Brushes.Red parametresinin bir nemi olmayacaktr. Bu yzden dkmanlar yazcya
gndermeden yazcnn renkli basky desteleyip desteklemediini kontrol etmek en akllca
yntemdir. Bu ekildeki bri kontrol iin PrintDocument snfnn PrinterSettings zellii
kullanlabilir. Bu zellik varsaylan yazcnz ile ilgili bir takm ayarlar yapsnda barndran
zelliklere sahiptir. rnein varsaylan yazcnzn renkli baky destekleyip
desteklemediini kontrol etmek iin SupportsColor zelliini aadaki gibi
kullanabilirsiniz. Not : SupportsColor zellii bool trndendir.

using System;
using System.Drawing.Printing;
using System.Drawing;

class Printer
{
static void Main()
{
PrintDocument PD = new PrintDocument();
PD.PrintPage += new PrintPageEventHandler(OnPrintDocument);

if ( PD.PrinterSettings.SupportsColor )
{
//renkli bask ayarlar
}
else
{
//renksiz bask ayarlar
}

private static void OnPrintDocument(object sender, PrintPageEventArgs e)


{
....
}
}

PrinterSettings yolu ile elde edebileceimiz dier nemli zellikler aada listelenmitir.

CanDuplex : bool trnden olan bu deiken yazcnn arkal nl kt almay


destekleyip desteklemediini belirtir.

Copies: short trnden olan bu deiken yazcya gnderilecek dkmann ka kopya


karlacn belirtir. Eer 10 sayfalk bir dkman iin bu zellii 5 olarak girerseniz 50
adet kadnz yazcya yerletirmeyi unutmayn.

CanDuplex : bool trnden olan bu deiken yazcnn arkal nl kt almay


destekleyip desteklemediini belirtir.

Duplex : Duplex enum sabiti trnden olan bu deiken arkal nl bask zelliini
belirler. Duplex numaralandrmas Default,Sizmplex,Horizontal ve Vertical olmak zere
drt tane yesi vardr.

IsDefaultPrinter : PrinterName ile belirtilen yazcnn bilgisayarnzdaki varsaylan


yazc(default printer) olup olmadn belirtir.

IsValid : PrinterName ile belirtilenin gerekten sisteminize ait bir yazc olup olmadn
belirtir.
PaperSizes : Yazc tarafndan desteklenen sayfa ebatlarnn PaperSizeCollection
trnden bir koleksiyon nesnesi ile geri dner. Bu koleksiyondaki her bir eleman
System.Drawing isim alannda bulunan PaperSize trndendir. PaperSize snfnn
Width(sayfa eni), Height(sayfa boyu),Kind(sayfa tr) gibi zellikleri bulunmaktadr.

PaperSources : Yazc tarafndan desteklenen sayfa kat alma


kaynaklarn PaperSourceCollection trnden bir koleksiyon nesnesi ile geri dner. Bu
koleksiyondaki her bir eleman System.Drawing isim alannda bulunan PaperSource
trndendir. PaperSource snfnn Kind zellii PaperSourceKind numaralandrmas
trnden bir nesne olup kat kaynann tipini belirtir.Bu numaralandrmann baz
semboleri unlardr : Envelope, Cassette, Custom, Manuel, TractorFeed.

PrintToFile : ktnn herhangi port yerine bir dosyaya yazdrlp yazdrlmayacan tutan
bool trnden bir deiken. Bu deiken daha ok birazdan greceimiz PrintDialog
ekrannn grntlenmesi srasnda deitirilip kullanlr.

kt n-zleme Penceresi

Profesyonel uygulamalarn tamamnda yazcya kt gndermeden nce kullancya n


izleme imkan salanr. .NEt ortamnda program gelitiriyorsanz Windows'un standart n
izleme penceresini programlama yolu ile grntlemeniz son derece kolaydr. Bu ekrann
grntlenmesi iin System.Drawing isim alannda bulunan PrintPreviewDialog snf
kullanlr. Bu snf ile ilikilendirilmi PrintDocument nesnesinin PrintPage olayna ilikin
metot altrlarak n-izleme penceresindeki ierik elde edilir.

Bir PrintPreviewDialog nesnesi oluturulduktan sonra nesnenin Document zelliine


PrintDocument trnden bir nesne atanr. Ve ardndan PrintPreviewControl trnden olan
nesne zerinden Show() yada ShowDialog() metotlar kullanlarak n izleme ekran
gsterilir.

n izleme ktsnn grntlendii pencereyi elbette PrintDocument snfnn Print()


metodunu armadan nce gstermeliyiz. Daha nce yaptmz ve dosya ieriini
yazcya gnderen uygulmann Main() metodunu aadaki gibi deitirerek n izleme
ekranndan ktya gnderilecek ierii grntleyelim.

static void Main(string[] args)


{
dosyaAkimi = new System.IO.StreamReader("C:\\Print.txt");

PrintDocument PD = new PrintDocument();


PD.PrintPage += new PrintPageEventHandler(OnPrintDocument);

PrintPreviewDialog pdlg = new PrintPreviewDialog();


pdlg.Document = PD;
pdlg.ShowDialog();

try
{
PD.Print();
}
catch
{
Console.WriteLine("Yazici iktisi alinamiyor...");
}
finally
{
PD.Dispose();
}
}

Program yeni haliyle derleyip altrdmzda ilk nce kt n izleme ekran aadaki
gibi gsterilecektir. Not : ktya gnderilecek dosyann yolu rneimiz iin "C:\Print.txt"
eklinde olmaldr.

Sayfa Dzenleme Ekran (PageSetupDialog Snf)

Dkman ktya gndermeden nce gnderme ileminin hangi yazc ayarlar ile
yaplacan belirlemek iin genellikle sayfa dzenleme ekran gsterilir. Bu ekranda kat
tipinden, yazcnn kat kaynana kadar bir ok zellii deitirmeniz mmkndr. Bu
ekranda yaplan btn deiiklikler PrintDocument snfnn PrinterSettings zelliine
aktarlr. Sayfa dzenleme ekrana System.Drawing isim alannda bulunan
PrintSetupDialog snf ile gerekletirilir. Bu snfnn kullanm PrintPreviewDialog
snfnn kullanm ile nerdeyse ayndr. Bu yzden ayrca aklmaya gerek duymuyorum.

Son olarak yazc n izleme ekranndan nce sayfa dzenleme ekrannn gsterilmesini
salamak iin uygulamamazn Main() metodunu aadaki gibi deitirin ve altrn.

static void Main(string[] args)


{
dosyaAkimi = new System.IO.StreamReader("C:\\Print.txt");

PrintDocument PD = new PrintDocument();


PD.PrintPage += new PrintPageEventHandler(OnPrintDocument);
PrintDialog pdiyalog = new PrintDialog();
pdiyalog.Document = PD;
pdiyalog.ShowDialog();

PrintPreviewDialog pdlg = new PrintPreviewDialog();


pdlg.Document = PD;
pdlg.ShowDialog();

try
{
PD.Print();
}
catch
{
Console.WriteLine("Yazici iktisi alinamiyor...");
}
finally
{
PD.Dispose();
}
}

Program derleyip altrdnzda karnza ilk kacak grnt aadaki ekran olacaktr.

Bu rnekle birlikte yazc kts alma ile ilgili temel ilemlerin anlatld yazmzn sonuna
geldik. .NET teki yazc kts alma ilemleri bu anlattklarmla snrl deildir. Ancak bu
yazda anlatlanlar bu konuya ok hzl bir giri yapmanz salamtr. lerleyen yazlarda
grmek dileiyle.

Kaynaklar :

MSDN Yardm Dkmanlar


Dzenli fadeler(Regular Expressions) Nedir?

Regular expression bir metni dzenlemek yada metin ierisinden belli kurallara uyan alt
metinler elde etmek iin kullandmz bir dildir. Bir regular expression, string tipindeki
karakter topluluuna uygulanr. Sonu olarak substringler oluur yada orjinal metnin bir
ksmn ieren deitirilmi yeni metinler elde edilir.

Regular Expressionlarda Kullanlan zel Karakterler ve Etkileri


Regular expression desenleri tanmlamada kullanlan zel karakterleri rnekleri ile
anlatrsak sanrm regular expressionlar daha tand ve kolay gelebilir.

1.) . Karakteri
Tek bir karakteri temsil eder(yeni satr karakteri hari).
CSharp.edir eklindeki bir desen CSharpnedir, CSharpNedir, CSharpSedir, CSharp3edir
gibi stringleri dndrebilir.

2.) [] Karakterleri
Bir arrayi yada aral temsil eder.
CSharp[SNY]edir deseni, CSharpSedir, CSharpNedir ve CSharpYedir stringlerini
dndrr.
CSharp[a-z]edir eklindeki kullanm aralk belirtmeye yarar.
CSharp[0-9]edir eklindeki klanlm ise saysal aralk belirtmeye yarar.

3.) ? Karakteri
Kendinden nceki karakterin stringte olmas yada olmamasn salar.
CSharpn?edir deseni CSharpedir yada CSharpnedir dndrr.

4.) \ Karakteri
Kendinden sonraki zel karakterin stringe dahil edilmesini salar.
CSharpnedir\? deseni CSharpnedir? Stringini dndrr. (Eer \ karakterini
kullanmam olsaydk CSharpnedi yada CSharpnedir dnerdi.)

5.) * Karakteri
Kendinden nceki karakterin yada stringin hi olmamas yada istedii sayda olmasn
salar.
CSharpnedir* deseni, CSharpnedi, CSharpnedir, CSharpnedirr, CSharpnedirrr, ...
dndrr. CSharp(nedir)* deseni ise CSharp, CSharpnedir, CSharpnedirnedir, ...
dndrr.

6.) {} Karakterleri
Kendinden nce gelen karakterin belirtilen sayda tekrar etmesini salar.
C{4}Sharpnedir deseni, CCCCSharpnedir stringini dndrr.

7.) ^ Karakteri
Satr ban ifade eder.
^CSharpnedir deseni, satr banda CSharpnedir stringi varsa bunu dndrr.

8.) $ Karakteri
Satr sonunu ifade eder.
CSharpnedir$ deseni, satr sonunda CSharpnedir stringi varsa bunu dndrr.
Basit Bir Tarih Deseni Yapalm
imdi iin pratiine gelelim ve adm adm tarih deseni oluturalm. Daha sonra ise
oluturduumuz bu tarih desenini bir konsol programnda kullanalm.

Tarih desenimiz bir string ierisindeki, GG/AA/YYYY formatlarndaki tarihleri yakalayacak


yapda olsun.

nce desenimizin GG yani tarihin gn belirtilen ksmn tanmlayalm :

(0?[1-9])
// 1, 2, .., 9, 01, 02, ..., 09 gibi yazlm gnleri tanmlar.

([12][0-9])
// 10, 11, ..., 29 gibi yazlm gnleri tanmlar.

(3[01])
// 30, 31 gnlerini tanmlar.

// Bu tanm OR (|) ilemiyle


// birletirirsek gn tanmn elde ederiz.

// Gn tanm :
((0?[1-9])|([12][0-9])|(3[01]))

imdi desenimizin AA yani tarihin ay belirtilen ksmn tanmlayalm :

(0?[1-9])
// 1, 2, .., 9, 01, 02, .., 09 gibi yazlm aylar tanmlar.

(1[0-2])
// 10, 11, 12 aylarn tanmlar.

// Bu iki tanm OR ilemiyle


// birletirirsek ay tanmn elde ederiz.

// Ay Tanm :
((0?[1-9])|(1[0-2]))

imdi desenimizin YYYY yani tarihin yl belirtilen ksmn tanmlayalm :

([12][0-9][0-9][0-9])
//1000 ile 2999 yllar arasndaki tm yllar ierir.

Ve son olarak tanmladmz gn, ay ve yl desenlerini / ile birletirelim :

((0?[1-9])|([12][0-9])|(3[01]))(/)(0?[1-9]|1[0-2])(/)([12][0-9][0-9][0-9]))

Basit Bir Test Program Yazalm


imdi elde ettiimiz tarih desenini test edebileceimiz basit bir konsol program yazalm. Ek
bilgi olarak ? eklindeki bir ifadeyi desenin nne ilave ederseniz, bir desen grubu ifade
etmi olursunuz ve birka deseni ayn anda kontrol edebilirsiniz.
using System;

using System.Text.RegularExpressions;

class Test

public static void Main()

// Regular Expression iin bir desen (pattern) tanmlyoruz :

string tarihDeseni=@"(?((0?[1-9])|([12][0-9])|(3[01]))(/)(0?[1-
9]|1[0-2])(/)([12][0-9][0-9][0-9]))";

// Regular Expression'umuzu tanmlyoruz :

Regex benimRegex=new Regex(tarihDeseni);

// Kullancdan tarih ieren metni talep ediyoruz :

Console.WriteLine("Ltfen iinde tarih olan bir metin


giriniz :");

// Tarih arayacamz metni konsoldan alyoruz :

string metin=Console.ReadLine();

// Metin ierisindeki tarihleri (birden fazla olabilir)


Collection nesnesine atyoruz :

MatchCollection benimMatchCollection=benimRegex.Matches(metin);

// Metin iindeki herbir tarihi ekrana yazdryoruz :

foreach(Match benimMatch in benimMatchCollection)

Console.WriteLine(benimMatch.Groups["tarih"]);

Console.Read();

}
Bir Web Sitesindeki E-Mail Adreslerini Yakalamak (Dzenli fadeler 2)

Gene u skc dzenli ifadeler deil mi? Bu makalede dzenli ifadelerin ne kadar
etkileyici olduunu bir rnek zerinde anlatmaya alacam.
Web sitelerinin birebir kopyasn kendi bilgisayarnza kopyalayan ( Teleport gibi)
programlar bilirsiniz. nce bir sayfann kaynak kodunu indirir. indeki linkleri ve resim
dosyalarn belirler. Sonra sra bu link ve resim dosyalarna gelir.

Hi elinizdeki kaynak kodun linklerini nasl ayklayacanz dndnz m?


te dzenli ifadeler burada gerekten harikalar yaratr.
Fazla uzatmadan rneimize geelim...

E-Mail Yakalayc

imdi yapacamz rnekte nce bir web sitesinin kaynak kodunu indirip, ierisindeki e-
mail linklerini elde edeceiz.
ncelikle sayfann kaynak kodunu indirelim
Bunun iin iki basit metod yazdm. lki sayfann adresini kullancdan alyor, ikincisi
sayfaya balanp kaynak kodu indiriyor :

// Adresi Alan Metod :


private string AdresiAl()
{
string adres="http://" + txtAdres.Text;
return adres;
}

// Sayfann Kaynak Kodunu Dndren Metod :


private string KaynakAl(string adres)
{
lblStat.Text="Siteye Balanyor...";
WebResponse benimResponse=null;
try
{
WebRequest benimWebRequest=WebRequest.Create(adres);
benimResponse=benimWebRequest.GetResponse();
}
// Eer internet balants yoksa yada site adresi yanl ise :
catch(WebException e)
{
lblStat.Text="Siteye Balanamyor.";
return null;
}
// Site ierii stream olarak alnyor :
Stream str=benimResponse.GetResponseStream();
StreamReader reader=new StreamReader(str);
string kaynak=reader.ReadToEnd();
// Tm ierik kk harfle dndrlyor.
//Daha fazla kontrol yapmamak iin bir nlem
return kaynak.ToLower();
}

Sayfann kaynak kodunu indirdikten sonra iindeki e-mail linklerini bulup bir diziye atan
bir baka fonksiyon daha yazdm. ncelikler e-mail linkini yakalayan deseni (pattern)
aklamaya alalm.

Bildiiniz gibi e-mail linkleri


<a href="mailto:aaa@bbb.ccc"> gibi ifade edilir.

O zaman desenimiz (href=) ifadesi ile balamaldr.


Ardndan (') yada (") karakterleri gelebilir.

"(href=)((')|(""))"

Sonra "mailto:" ifadesi gelir :

"(href=)((')|(""))(mailto:)"

"mailto:" ifadesinden sonra istediimiz ifade yani e-mail adresi gelir. Bunu "mail"
isminde bir grup tanmlayarak elde edeceiz.

"(href=)((')|(""))(mailto:)(?<mail>(.*))"
// (.*) ifadesi kendinden sonra gelen desene kadar her karakteri alan bir desendir.

imdi desenimizi sonlandralm :

"(href=)((')|(""))(mailto:)(?<mail>(.*))((')|(""))"

Ksaca, "mailto:" ile trnak karakterleri arasndaki her ifade bizim iin mail grubuna dahil
oldu.

imdi E-mail adreslerini dizi eklinde dndren metodumuzu yazalm :


// Sayfann iindeki mail adreslerini dizi eklinde dndren metod :
private string[] MailAl(string kaynak)
{
lblStat.Text+= "Kaynak kod alnd... " + "Mailler ayrtrlyor... ";
// Desenimiz :
string mailDeseni=@"(href=)((')|(""))(mailto:)(?<mail>(.*))((')|(""))";
int i=0;
// Regular Expressionumuzu tanmlyoruz :
Regex benimRegex=new Regex(mailDeseni);
Match str=benimRegex.Match(kaynak);
// Oluturduumuz deseni sitenin kaynak kodunda karlatryoruz :
MatchCollection mailCol=benimRegex.Matches(kaynak);
string[] mail=new string[mailCol.Count];
// Bulunan her e-mail adresini mail[] dizisine atyoruz :
foreach(Match mailMatch in mailCol)
{
mail[i]=mailMatch.Groups["mail"].ToString();
i++;
}
return mail;
}

imdi Yakala butonuna baslnca icra edilecek olay kodunu yazalm :

// imdi e-mail yakalamak iin bu yazdmz metodlar button_Click olay ile


birletirelim :
private void btnYakala_Click(object sender, System.EventArgs e)
{
lblStat.Text="";
if(txtAdres.Text=="")
{
MessageBox.Show("Ltfen Bir Adres Girin !");
}
else
{
// Sitenin Adresini alyoruz :
string adres=AdresiAl();
// Sitenin Kaynak Kodunu alyoruz :
string kaynak=KaynakAl(adres);
// E-Mail adreslerini alyoruz :
if(kaynak!=null)
{
string[] mail=MailAl(kaynak);
lblStat.Text+="lem sona erdi." + mail.Length + " tane mail adresi
yakaland.";
foreach(string yakalananMail in mail)
{
// Her e-mail adresi listbox'a giriliyor :
lbxEmail.Items.Add(yakalananMail);
}
}
}
}
Aklama

Baz sitelerde frameset kullanldndan sayfada e-mail linki grlse bile programmz
bunlar dndrememekte. Bu sayfalarn framelerinin linkleri verilerek e-mail adresleri
elde edilebilir.
Yine baz sitelerde linkler javascript kodu ile eriildiinden bu adreslerde programmz
tarafndan eriilememektedir.
C# ile Taskbarda alan Program Hazrlamak

Bu makalemde size NotifyIcon ve ContextMenu kullanarak bir taskbara yerleen program


nasl yaplr, onu gstereceim. Daha fazla uzatmadan hemen kodlarmz yazmaya
balayalm.

lk olarak Visual Studio'yu aalm ve yeni bir proje yaratalm. Bu projenin adna istediiniz
gibi bir isim verebilirsiniz. Projemiz "C# Windows Application" olmaldr.

Projemizi yarattktan sonra Add / New Item diyerek yeni bir Icon ekleyelim. Iconumuzun
Build Action' mutlaka "Embedded Resource" olmal. Daha sonra Form1'n kod ksmna
gecelim.

Snfmzn iine

private NotifyIcon notifyicon;


private ContextMenu menu;

kodlarn ekleyelim. Formumuza iki kere tklayalm ve aadaki metotlar kaynak


kodumuza ekleyelim.

private void Form1_Load(object sender, System.EventArgs e)


{
notifyicon = new NotifyIcon(); //Yeni bir NotifyIcon tanmladk

notifyicon.Text = "NotifyIcon Ornegimiz"; //Mouse ile uzerine geldiimizde olusacak


yaz

notifyicon.Visible = true; //Gorunur ozelligi

notifyicon.Icon = new Icon("Icon1.ico"); //Iconumuzu belirledik

menu = new ContextMenu(); //Yeni bir ContextMenu tanmladk

menu.MenuItems.Add(0, new MenuItem("Goster", new


System.EventHandler(Goster_Click))); //Menuye eklemeler yapyoruz.

menu.MenuItems.Add(1, new MenuItem("Gizle", new


System.EventHandler(Gizle_Click)));

menu.MenuItems.Add(2, new MenuItem("Kapat", new


System.EventHandler(Kapat_Click)));

notifyicon.ContextMenu = menu; //Menumuzu notifyiconun menusu olarak tanmladk


}

protected void Goster_Click(object sender, System.EventArgs e)


{
Show(); //Formumuzu normal ebatlara getirecek
}

protected void Gizle_Click(object sender, System.EventArgs e)


{
Hide(); // Formumuzu minimize edecek
}

protected void Kapat_Click(object sender, System.EventArgs e)


{
Close(); //Formumuzu kapatacak
}

Evet, imdi programmz alstrmaya hazrz. E o zaman alstralm ve sonucu grelim.


Gorduunuz gibi programmz alt. Program kapatalm. O da ne! Iconumuz hala
taskbarda duruyor. Peki bunu nasl dzelteceiz? Hemen cevap verelim. Kaynak
kodumuzun biraz stlerine bakyoruz ve u satrlar goruyoruz:

protected override void Dispose( bool disposing )


{
if( disposing )
{
if(components ! null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

Bu satrlar aadaki gibi deitirdiimizde progrm kapatldnda taskbar daki icon da


silinecektir.

protected override void Dispose( bool disposing )


{
if( disposing )
{
this.notifyicon.Dispose();;
components.Dispose();
}
base.Dispose( disposing );
}

Ve bir sorunumuz daha var. Programmz atmz anda Form1 de gzukyor. Peki
Form1 gzkmeden sadece Iconumuzun gzkmesini nasl salayacaz? Bunun da
ozm var. Biraz daha yukarlara bakp

InitializeComponent();

satrndan bir sonraki satra su kodlar koyuyoruz:

this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;

Bunlar yaptktan sonra yapmamz gerek bir deiiklik daha var. O da Goster_Click ve
Gizle_Click'i su sekilde deitirmek:

protected void Goster_Click(object sender, System.EventArgs e)


{
this.WindowState = FormWindowState.Normal; //Formumuzu normal ebatlara getircek
}

protected void Gizle_Click(object sender, System.EventArgs e)


{
this.WindowState = FormWindowState.Minimized; // Formumuzu minimize edecek
}

Ve imdi hersey tamam. Programmz artk calsmaya hazr durumda. Hemen caltrp
sonucu grebiliriz.

Umarm herkes iin faydal bir yaz olmustur. Benim iin kod yazmak yaz yazmaktan
daha kolay, bunu herkesin tatmasn isterim :)) Yeni yazlarda gorusmek dileiyle
hoakaln.
"Singleton" Tasarm Deseninin(Pattern) C# ile Gerekletirilmesi

Yazlm mhendisliinin sanatsal yn ar olan "design pattern" kavramn bir oumuz


mutlaka duymuuzdur, ama rutin ilerimizden kendimizi boa karp bir trl inceleme
frsat bulamamzdr, Bu ve bundan sonraki bir ka makalelik dizide size
kendi terminolojik yaps iinde deyimlemi olan "design pattern" yani "desen tasarm"
kavramn aklamaya alacam. Elbette aklamalarm en ok bilinen tasarm desenleri
ile destekleyeceim. Bu konudaki ilk makalede en basit ve en popler tasarm
desenlerinden biri olan "Singleton" deseninden bahsedip "pattern design" sanatna daha
farkl bir bak asyla yaklamanz salamaya alacam. O halde ie basit tanmlarla
balayalm.

"Design Pattern" Nedir ?

Bildiiniz zere gnmzde yazlm mhendislii alannda en fazla ses getiren kurgu
yazlmn gerek dnya ile olan ilikisinin salanabilmesidir. Bu iliki elbette nesne
ynelimli programlama teknii ile salanmaktadr. Nesne ynelimli programlama teknii
bilgisayar uygulamalarn soyut bir olgudan kararak insanlarn daha kolay
alglayabilecei hale getirmitir. yle grnyorki, makro dzeyde gerek hayat
modelleme ile balayan bu iliki mikro dzeydede byk ses getirecektir. Nitekim son
yllarda gelitirilen yapay sinir alar ile makinelerin alma sistemlerinin gn getike
insanlarn veya canllarn alma ekline yaklat grlmektedir. Artk bilgisayarlardan
sadece verilen komutlar yerine getirmek deil, belirli olaylar ve durumlar karsnda baz
hkmlere varabilmeleride istenmektedir. Burada vurgulamak istediim nokta udur :
bizler yazlm mhendisleri veya programclar olarak gerek hayat ne kadar iyi
modelleyebiliyorsak o kadar baarl saylrz. Peki "desgin pattern" konusu nerede
devreye girmektedir? te benimde gelmek istediim nokta budur; "desgin patterns" bir
modelin tasarmn ustaca tasarlanmasn salayacak eitli desenlerin oluturulmasn ve
bu desenlerin ihtiya dahilinde herhangi bir modelin inaasnda kullanlabilmesini salar.
"Design pattern" kavram bir kurallar topluluundan ziyade bir ii nasl ve en gzel ne
ekilde yapabileceimiz gsteren yntemler topluluudur. yleki iyi bir yazlm
modelleyicisiyseniz kendi tasarm desenlerinizi oluturabilir ve bunlar dier ustalarn
kullanmna sunabilirsiniz. Tasarm desenleri tecrbe ile oluturulan yaplardr.
Bazlar olmazsa olmaz yaplar olmasna ramen bazlar tamamen yazlmn sanatsal
ynn gstermek iin tasarlanmtr . rnein bu yazmn ana konusunu belirleyen
"Singleton" tasarm deseni yllardan beri bir ok kii tarafndan kullanlmtr. Sizde bu
yazda bu desenin amacn ve nasl uygulandn rendiinizde eminimki projelerinizde
mutlaka kullanacaksnz. Hemen unuda belirteyimki bu tasarm deseni sizi uzaya
gtrmeyecektir, bu yzden beklentilerinizi biraz daha azaltmanzda fayda var.

O halde "design pattern" yada "tasarm deseni" ni u ekilde tanmlayabiliriz : Bir tasarm
problemini en basit ve en efektif bir ekilde zme kavuturacak yntemdir.

"Design Pattern" Kaynaklar

"Design Pattern" konusunda yazlm en gzel ve en popler kaynaklardan biri Erich


Gamma, Richard Helm, Ralph Johnson ve John Vlissides tarafndan kaleme alnm
"Design Patterns: Elements of Reusable Object-Oriented Software" kitabdr. Bu kitapta
en popler tasarm desenleri anlatlm ve bu desenlerin eitli uygulamalarna yer
verilmitir. "Desgin pattern" guru'lar olarak anlan bu 4 kii "Gangs Of Four(GOF)" olarak
ta bilinmektedir. Zaten bahsi geen kitapta anlatlan tasarm desenlerine de genel olarak
GoF tasarm desenleri denilmektedir. Bu yaz ile balayan yaz dizisinde GOF olarak anlan
tasarm desenlerini sizlere aktarp eitli kullanm alanlarn aklayacam.
GOF tasarm desenleri genel olarak 3 ana grup altnda incelenir. Bu gruplar ve herbir
gruptaki tasarm desenlerinin isimleri aada verilmitir.

1 - Creatinal Patterns Bu desenler bir yada daha fazla nesnenin oluturulmas ve


ynetilmesi ile ilgilidir. rnein bu yazda anlatacam ve bir uygulamann mr boyunca
belirli bir nesneden sadece bir adet bulunmasn garantileyen Singleton deseni bu gruba
girmektedir. Bu gruptaki dier desenler ise

Abstract Factory
Builder
Factory Method
Prototype

olarak bilinmektedir. Bu desenlerin bir ounu ilerleyen yazlarmda ele alacam.


imdilik sadece bir giri yapyoruz.

2 - Behavioral Patterns Bu gruptaki desenlerin amac belirli bir ii yerine getirmek iin
eitli snflarn nasl birlikte davranabileceinin belirlenmesidir. Bu gruptaki desenler ise
aadaki gibidir.
Chain of responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State
Strategy
Template method
Visitor

3 - Structural Patterns Bu gruptaki desenler ise eitli nesnelerin birbirleri ile olan
ilikileri temel alnarak tasarlanmtr. Bu gruptaki tasarm desenleri ise unlardr:
Adapter
Bridge
Composite
Decorator
Faade
Flyweight
Proxy

Bu giri bilgisinden sonra imdi nesnelerin yaratlmas ile ilgili grup olan "Creatinal
Patterns" grubunda bulunan "Singleton" desenini aklamaya baalayabiliriz.

Singleton Deseni

Singleton deseni bir programn yaam sresince belirli bir nesneden sadece bir
rneinin(instance) olmasn garantiler. Ayn zamanda bu desen, yaratlan tek
nesneye ilgili snfn dndan global dzeyde mutlaka eriilmesini hedefler. rnein bir
veritaban uyglamas gelitirdiinizi dnelim. Her programc mutlaka belli bir anda
sadece bir balant nesnesinin olmasn isteyecektir. Bylece her geretiinde yeni bir
balant nesnesi yaratmaktansa varolan balant nesnesi kullanlarak sistem
kaynaklarnn daha efektif bir ekilde harcanmas salanr. Bu rnekleri dahada artrmak
mmkndr. Siz ne zaman belli bir anda ilgili snfn bir rneine ihtiya duyarsanz bu
deseni kullanabilirsiniz.

Peki bu ilemi nasl yapacaz.? Nasl olacakta bir snftan sadece ve sadece bir nesne
yaratlmas garanti altna alnacak? Aslnda biraz dnrseniz cevabn hemen
bulabilirsiniz! zm gerekten de basit : statik ye elemanlarn kullanarak.

Singleton tasarm desenine gemeden nce snflar ve nesneler ile ilgili temel bilgilerimizi
hatrlayalm. Hatrlayacanz zere bir snftan yeni bir nesne oluturmak iin yapc
metot(constructor) kullanlr. Yapc metotlar C# dilinde new anahtar szc kullanlarak
aadaki gibi arlabilmektedir.

Snf nesne = new Snf();

Bu ekilde yeni bir nesne oluturmak iin new anahtar szcnn temsil ettii
yapc metoduna dardan eriimin olmas gerekir. Yani yapc metodun public olarak
bildirilmi olmas gerekir. Ancak "Singleton" desenine gre belirli bir anda sadece bir
nesne olabilecei iin new anahtar szcnn ilgili snf iin yasaklanmas gerekir yani
yapc metodun protected yada private olarak bildirilmesi gerekir. Eer bir metodun
varsaylan yapc metodu(default constructor- parametresiz yapc metot) public olarak
bildirilmemise ilgili snf trnden herhangi bir nesnenin snfn dnda tanmlanmas
mmkn deildir. Ancak bizim isteimiz yalnzca bir nesnenin yaratlmas olduuna gre
ilgili snfn iinde bir yerde nesnenin oluturulmas gerekir. Bunu elbette statik bir
zellik(property) yada statik bir metotla yapacaz. Bu statik metot snfn kendi iinde
yaratlan nesneyi geri dn deeri olarak bize gnderecektir. Peki bu nesne nerde ve ne
zaman yaratlacaktr? Bu nesne statik metodun yada zelliin iinde yaratlp yine snfn
private olan elemanna atanr. Tekil olarak yaratlan bu nesne her istendiinde eer nesne
zaten yaratlmsa bu private olan elemann referasna geri dnmek yada nesneyi yaratp
bu private deikene atamak gerekmektedir. Sanrm bu deseni nasl
uygulayabileceimizi kafanzda biraz canlandrdnz. O halde daha fazla uzatmadan
desenimizi uygulamaya geirelim.

Singleton Deseninin 1. versiyonu


public class SingletonDeseni
{
private static SingletonDeseni nesne = new SingletonDeseni();

private SingletonDeseni()
{

public static SingletonDeseni Nesne


{
get
{
return nesne;
}
}
}

Yukardaki snf rneinde SingletonDeseni snf bellee yklendii anda statik olan
SingletonDeseni nesnesi yaratlacaktr. Bu nesne yaratlnn new anahtar szc ile
yapldna dikkat edin. Eer siz Main() gibi bir metodun iinden bu nesneyi yaratmaya
kalksaydnz derleme aamasnda hata alrdnz. nk public olan herhangi bir yapc
metot bulunmamaktadr. Ayrca
Siz Main() gibi bir metodun iinden yaratlan bu nesneye

SingletonDeseni nesne = SingletonDeseni.Nesne;


eklinde erimeniz mmkndr. Bylece yukardaki deyimi her kullandnzda size geri
dnen nesne, snfn bellee ilk yklendiinde yaratlan nesne olduu garanti altna
alnm oldu. Dikkat etminiz gereken dier bir nokta ise nesneyi geri dndren zelliin
yalnzca get blounun olmasdr. Bylece bir kez yaratlan nesne harici bir kaynak
tarafndan hi bir ekilde deitirilemeyecektir.

Yukardaki SingletonDeseni snfn aadaki gibi de yazmamz mmkndr.

Singleton Deseninin 2. versiyonu

public class SingletonDeseni


{
private static SingletonDeseni nesne = new Singleton();

private SingletonDeseni()
{

public static Singleton Nesne()


{
return nesne;
}
}

Dikkat ederseniz iki snfn tek fark oluturulan nesneye erime biimidir. lk versiyonda
nesneye zellik zerinden eriilirken ikinci versiyonda metot zerinden eriilmektedir.
Deimeyen tek nokta ise her iki eriim aracnn da statik olmasdr.

Yukardaki her iki versiyonda da biz yaratlan nesneyi

SingletonDeseni nesne = SingletonDeseni.Nesne;

yada

SingletonDeseni nesne = SingletonDeseni.Nesne();

eklinde istediimizde nesne zaten yaratlm durumda olmaktadr. Oysa bu snf daha
efektif bir hale getirerek yaratlacak nesnenin ancak biz onu istediimizde yaratlmasn
salayabiliriz. Bu durumu uygulayan Singleton deseninin 3 versiyonunu olarak aada
grebilirsiniz.

Singleton Deseninin 3. versiyonu

public class SingletonDeseni


{
private static SingletonDeseni nesne;

private SingletonDeseni()
{

public static Singleton Nesne()


{
if(nesne == null)
nesne = new SingletonDeseni();

return nesne;
}
}

Grdnz zere nesne ilk olarak snf bellee yklendiinde deilde o nesneyi ilk defa
kullanmak istediimizde yaratlyor. lgili nesneyi her istediimizde yeni bir nesnenin
yaratlmamas iinde

if(nesne == null)

eklinde bir koul altnda nesnenin yaratldna dikkat edin.

Not : 3.versiyonda nesneyi yaratan bir metot olabilecei gibi 1. versiyondaki gibi sadece
get blou olan zellikte olabilir.

Hereye ramen yukardaki 3 versiyonda baz durumlar iin tek bir nesnenin olumasn
garanti etmemi olabilirz. Eer ok kanall(multi-thread) bir uygulama gelitiriyorsanz
farkl kanallarn ayn nesneyi tekrar yaratmas olasdr. Ancak eer ok kanall
almyorsanz(ounlukla tek thread ile alrz) yukardaki sade ama z olan 3
versiyondan birini kullanabilirsiniz. Ama eer ok kanall programlama modeli sz konusu
ise ne yazkki farkl kanallarn ayn nesneden tekrar yaratmasn engelemek iin ekstra
kontroller yapmanz gerekmektedir. Ne yazkki diyorum nk bu yapacamz kontrol
performans byk lde drmektedir.

O halde ok kanall uygulamalarda kullanabileceimiz Singleton desenini yazalm.

Singleton Deseninin 4. versiyonu

public class SingletonDeseni


{
private static SingletonDeseni nesne;

private static Object kanalKontrol = new Object;

private SingletonDeseni()
{

public static Singleton Nesne()


{
if(nesne == null)
{
lock(kanalKontrol)
{
if(nesne == null)
{
nesne = new SingletonDeseni();
}
}
}

return nesne;
}
}
Yukardaki desendeki pf nokta lock anahtar szcnn kullanmdr.Eer nesne ilk defa
yaratlcaksa yani daha nceden nesne null deere sahipse lock anahtar szc ile
iaretlenen blok kitlenerek baka kanallarn bu bloa erimesi engellenir.
Bylece kilitleme ilemi bittiinde nesne yaratlm olaca iin, kilidin kalkmasn
bekleyen dier kanal lock blouna girmi olsa bile bu bloktaki ikinci if kontrol nesnenin
yeniden oluturulmasn engelleyecektir. Bylece ok kanall uygulamalar iinde tek bir
nesnenin olumasn ve bu nesneye eriimi garanti altna alan Singleton desenini
tasarlam olduk.

Son olarak lock anahtar szcn kullanmadan ok kanall uygulamalar iinde tek bir
nesneyi garanti altna alacak deseni yazalm. Aada Singleton desenin 5. versiyonu
bulunmaktadr.

Singleton Deseninin 5. versiyonu

public class SingletonDeseni


{
private static SingletonDeseni nesne = new SingletonDeseni ();

private static SingletonDeseni()


{

private SingletonDeseni()
{

public static SingletonDeseni Nesne


{
get
{
return nesne;
}
}
}

Bu versiyonun birinci versiyondan tek fark yapc metodunda statik olmasdr. C# dilinde
statik yapc metotlar bir uygulama domeninde ancak ve ancak bir nesne yaratldnda
yada statik bir ye eleman referans edildiinde bir defaya mahsus olmak zere altrlr.
Yani yukardaki versiyonda farkl kanallarn(thread) birden fazla SingletonDeseni nesnesi
yaratmas imkanszdr. nk static ye elemanlar ancak ve ancak bir defa altrlr.

Son versyion basit ve kullanl grnmesine ramen kullanmnn baz sakncalar vardr.
rnein Nesne zellii dnda herhangi bir statik ye elemannz var ise ve ilk olarak bu
statik ye elemann kullanyorsanz siz istemediniz halde SingletonDeseni nesnesi
yaratlacaktr. Zira yukarda da dediimz gibi bir statik yapc metot herhangi bir statik
ye eleman kullanld anda altrlr. Dier bir sakncal durumda birbirini aran
statik yapc metotlarn arlmas srasnda elikilerin oluabileceidir. rnein her
static yapc metot ancak ve ancak bir defa altrlr dedik. Eer altrlan bir static
metot dier bir statik metodu aryor ve bu statik metotta ilkini aryorsa bir eliki
olacaktr.

Ksacas eer kodunuzun eliki yaratmayacandan eminseniz 5. deseni kullanmanz


doru olacaktr. Eer ok kanall uygulama gelitiriyorsanz 4. versiyonu, ok kanall
uygulama gelitirmiyorsanzda 3. versiyonu kullanmanz tavsiye edilmektedir.
Singleton deseni konulu makalenin sonuna gelmi bulunmaktayz. Eer ileride bir gn
yukardaki desenlerin birini kullanma ihtiyac hissederseniz hangi deseni ne amala
kullandnz bizimle paylarsanz seviniriz.

Bir dier "Creational Patterns" deseni olan "Abstract Factory" desenini anlatacam yazda
grmek zere.
XP Stilinde Kontroller ile alma

Bu yazmzda Windows Form kontrollerinin veya nesnelerinin Windows XP stili


grnmlerini nasl elde edebileceimizi greceiz.

Microsoft Framework v1.1 de bu zellik henz pratik bir ekilde yok. Bu yzden yolumuz
biraz uzun.

Elde edeceimiz bu grnm Windows Xp den nceki iletim sisteminde haliyle


grnmeyecek, o iletim sisteminin default haliyle grnecektir(mesela butonlar nceki
iletim sistemlerinde gri renkli grnyordu).

Herhangi bir karklk kmamas iin ynergeleri beraber takib edelim.

Hemen ilem admlarmza balayalm:

Microsoft Visual Studio.NET i an.

File/New/Project i tklayn.

Alan Pencerede Project Type alannda Visual C# Project seili olsun.

Ayn pencerede Templates alannda Windows Application seili olsun.

Ayn pencerede Name alanna XPStyle yazn.

Ayn pencerede Location alannda mevcut yolun sonundaki klasr isminide XPStyle
yapn.

Projenin almas iin Okey butonuna tklayn.

imdi Form1.cs[Design] grnmne sahipsiniz.

Formumuza ; Button, radioButton, checkBox, textBox, progressBar ve trackBar


ekleyin.

Button, radioButton, ve checkBox nesenelerinin Properties penceresinde Flat Style


ksmn System yapn.

Derleri iin bunu yapmaya gerek yok.

Menden File/Save All tklayn ve Menuden Build/Build Solutin tklayn.

Elimizde mevcut bir grnm olutu, Projeyi bu haliyle altrrsanz(Debug/Start),

Form elemanlarnda XP Stilini gremeyeceksiniz,

Mesela Buton hala aadaki gibi gri renkte grnecek.


imdi XP Stil grnmn elde etmek iin ynergeleri izleyin:

Menden, Project/Add Class tklayn.

Alan pencerede Templates ksmnda XML File(herhangi bir .cs dosyas da olabilir)
sein.

Ayn pencerede Name ksmndaki alan tamamen temizleyin.

[Proje Ad].exe.manifest yazm biiminde XPStyle.exe.manifest yazn.

Bu projenin adn XPStyle olarak belirlemitik

Dosyamzn olumas iin OK butonuna tklayn.

Oluturduumuz XPStyle.exe.manifest adl dosyay an ve iine aadaki kodlar


yaptrn.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity version="1.0.0.0" processorArchitecture="X86"


name="Microsoft.Winweb.<Executable Name>" type="win32"/>

<description>.NET control deployment tool</description><dependency>

<dependentAssembly>

<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls"


version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df"
language="*" />

</dependentAssembly>

</dependency>

</assembly>
NOT: < > karakterlerinin < ve > haline dnmesi sz konusu olabilir. Bu yzden bu
kodlar nce bir NotePad e yaptrn sonra buradan Select All deyip tekrar kopyalayn ve
XPStyle.exe.manifest dosyamza yaptrn.

Bu kodda <Executable Name> ksmna Projemizin ad olan XPStyle yazn

Yeni hal: name="Microsoft.Winweb.XPStyle" eklinde olacak.

Menden File/Save All tklayn ve Menuden Build/Build Solutin tklayn.

Microsoft Visual Studio.NET i indirin ve projenizin bulunduu klasre gein

Bu klasrn iinde XPStyle.exe.manifest dosyasn greceksiniz.

Bu dosyay kopyalayp, Obj klasrnn iine girin, buradan da Debug klasrne tklayp
iine girin ve dosyay buraya yaptrn.

alma esnasnda faydalanmak ii bu dosyay bin\debug klasrne de kopyalayabilirsiniz

Microsoft Visual Studio.NET i an

Menden, File/Open/File tklayn.

Alan pencerede Obj\Debug klasrne ulan.

Buradan XPStyle altrlabilir dosyanz sein ve Open butonuna tklayn.

Alan XPStyle.exe dosyasnn iindeyken sa tklayn.

Alan menuden Add Resource tklayn.

Alan pencereden import butonuna tklayn.

Alan pencreden Files of type alannda All Files sein.

Grnen dosyalardan XPStyle.exe.manifest dosyasn seip Open butonuna tklayn.

Alan Custom Resource Type penceresinde Resource Type alanna RT_MANIFEST yazn
ve Okey butonuna tklayn.

XPStyle.exe(101-Data) dosyas ald. Bu dosyadayken Properties penceresinden ID


alannn 101 olan deerini 1 yapn

Menden File/Save All tklayn ve Menuden Build/Build Solutin tklayn.

Bu dosyay kapatn.

Projeyi altrn.

Karnzda aadaki gibi XP stilli bir pencere greceksiniz.


Saylar Yazya evirme rnei

Bu yazda bir saynn yazya nasl evirebileceimiz hakknda bir yol gstereceim, dil
olarak C# kullanlacaktr. ncelikle belirteyim ki programlama ve C# konusunda ok
yeniyim. Hemen hemen tm bildiklerimi bu siteye borluyum.

Aadaki kodda bulunan Oku fonksiyonu kendisine string olarak gnderilen tam sayy
yazya evirmektedir. Kodun alma mant yledir.

oku fonksiyonuna gnderilen string bana "0" eklemek suretiyle nce 15 haneye
tamamlanr, sonra yeni string 3 erli kmeler halinde 5 eit paraya blnr ve her bir
l kme tek tek
rakam dizisine yklenir. Bylece 5 elemanl rakam dizisinin her bir elemannda 3
karakterli bir string ykl olur.

1.Aama

saymz 32313234 olsun. ilk olarak saymzn hane saysn bana 0 eklemek sureti ile 15
e karrz.
Bylece yeni stringimiz 000000032313234 eklini alr.

2.Aama

Stringimiz 3 erli kmeler halinde 5 eit paraya blnr.

1. kme : 000
2. kme : 000
3. kme : 032
4. kme : 313
5. kme : 234

3.aama

her bir kme 5 elemanl rakam isimli araya yklenir ve sonuta

rakam[0] = "000"
rakam[5] = "234"

olur

rakam[5][0]="2" 5. kmenin yzler basama;


rakam[5][1]= "3" 5. kmenin onlar basama;
rakam[5][2]= "4" 5. kmenin birler basama;

olur.

4.aama

10 elemanl yzler, onlar, birler string dizileri tanmlanr ve i leri doldurulur.

rn:
yuzler.SetValue("ikiyuz",2);
onlar.SetValue("otuz",3);
birler.SetValue("drt",4);

yani yuzler[2]+onlar[3]+birler[4] = ikiyzotuzdrt olur.

int x =Convert.ToInt16(rakam[5][0].ToString()); yzler

int y =Convert.ToInt16(rakam[5][1].ToString()); onlar

int z =Convert.ToInt16(rakam[5][2].ToString()); birler

yuzler[x]+onlar[y]+birler[z] = ikiyzotuzdrt

bir dng ile her bir kmeye bu ilemi uygularsanz, 1 ve ikinci kmlerin btn elemanlar
sfr olduu iin sonuta

otuzdrt
yzonu
ikiyzotuzdrt

elde edersiniz

5.Aama

hane isimli 5 li array tanmlanr ve elemanlar trilyon, milyar, milyon, bin ve sonuncusu da
bo olacak ekilde ayarlanr. ayn dng ierisinde her bir kmenin sonuna eklenir

string sonuc = "";

for(int i = 0 ; i < 5;i++)

{
sonuc = sonuc +

yuzler[Convert.ToInt16(rakam[i][0].ToString())]+

onlar[Convert.ToInt16(rakam[i][1].ToString())]+

birler[Convert.ToInt16(rakam[i][2].ToString())]+

hane[i];

Burada ayarlanmas gereken durum eer bir kmenin btn elemanlar sfrsa (yukardaki
gibi) hanenin gzkmemesi gerekir. Yani

000 = yuzler[0]+onlar[0]+birler[0]+hane[0] dersek sonu trilyon olur bu durumda


if(rakam[0].ToString()!= "000")

hane.SetValue("trilyon ",0);

if(rakam[1].ToString()!= "000")

hane.SetValue("milyar ",1);

if(rakam[2].ToString()!= "000")

hane.SetValue("milyon ",2);

if(rakam[3].ToString()!= "000")

hane.SetValue("bin ",3);

yani rakam[0] (trilyon kmesi) "000" deilse hane[0] = "trilyon" olsun demeliyiz.

Yanlz bir sorun daha var. eer say 1000 ise fonksiyon bize hakl olarak "birbin" i
dndrr. Bir milyar var, Bir Milyon var ama bir bin ve bir yz yok. Ben bu sorunu
BirSorunu isimli fonksiyonla hallettim.

Aadaki kodu inceleyebilirsiniz.

using System;

namespace numbereader

{
public class SayiOkuma
{

privatestring[ ] yuzler =newstring[10];


private string[ ] onlar =new string[10];
private string[ ] birler =new string[10];
private string[ ] hane = new string[5];
private string[ ] rakam =newstring[5];
// arraylar tanmlyoruz

public SayiOkuma()

// ilerini dolduruyoruz

yuzler.SetValue("dokuzyz",9);
yuzler.SetValue("sekizyz",8);
yuzler.SetValue("yediyz",7);
yuzler.SetValue("altyz",6);
yuzler.SetValue("beyz",5);
yuzler.SetValue("drtyz",4);
yuzler.SetValue("yz",3);
yuzler.SetValue("ikiyz",2);
yuzler.SetValue("yz",1);
yuzler.SetValue("",0);

onlar.SetValue("doksan",9);
onlar.SetValue("seksen",8);
onlar.SetValue("yetmi",7);
onlar.SetValue("altm",6);
onlar.SetValue("elli",5);
onlar.SetValue("krk",4);
onlar.SetValue("otuz",3);
onlar.SetValue("yirmi",2);
onlar.SetValue("on",1);
onlar.SetValue("",0);

birler.SetValue("dokuz",9);
birler.SetValue("sekiz",8);
birler.SetValue("yedi",7);
birler.SetValue("alt",6);
birler.SetValue("be",5);
birler.SetValue("drt",4);
birler.SetValue("",3);
birler.SetValue("iki",2);
birler.SetValue("bir",1);
birler.SetValue("",0);

hane.SetValue("",0);
hane.SetValue("",1);
hane.SetValue("",2);
hane.SetValue("",3);
hane.SetValue("",4);
/* ilk olarak bu arrayn elemanlarn bo olarak ayarlyoruz eer kme elemanlar
000 deilse trilyon,milyar,milyon bin deerleri ile dolduruyoruz
*/

public string oku(string sayi)

int uzunluk = sayi.Length;


if(uzunluk > 15)

return "Hata girilen deerin uzunluu en fazla 15 olmal";


// uzunluk 15 karakterden fazla olmamal. si

try
{

long k = Convert.ToInt64(sayi);

catch(Exception ex)
{

return ex.Message.ToString();

sayi = "000000000000000"+sayi;
sayi = sayi.Substring(uzunluk,15);

rakam.SetValue(sayi.Substring(0,3),0);
rakam.SetValue(sayi.Substring(3,3),1);
rakam.SetValue(sayi.Substring(6,3),2);
rakam.SetValue(sayi.Substring(9,3),3);
rakam.SetValue(sayi.Substring(12,3),4);

if(rakam[0].ToString()!= "000")
hane.SetValue("trilyon ",0);
if(rakam[1].ToString()!= "000")
hane.SetValue("milyar ",1);
if(rakam[2].ToString()!= "000")
hane.SetValue("milyon ",2);
if(rakam[3].ToString()!= "000")
hane.SetValue("bin ",3);

string sonuc = "";

for(int i = 0 ; i < 5;i++)

sonuc = sonuc + yuzler[Convert.ToInt16(rakam[i][0].ToString())]+


birsorunu(onlar[Convert.ToInt16(rakam[i][1].ToString())]+birler[Convert.ToInt16(rakam[i][2].ToStrin

return sonuc;

privatestring birsorunu (string sorun)

string cozum = "";


if (sorun == "birbin ")
cozum = "bin ";

else
cozum = sorun;

return cozum;
}

Herkese kolay gelsin. Bu arada dileyene DLL i gnderebilirim. yi almalar.


C#ta Temsilci (Delegate)ve Olay(Event) Kullanm

Bu yazmda sizlere C#ta delegate(delege veya eli) ve event(olay) kavramlarndan


bahsedeceim ve elbette bunlar kullanmann yararlarn anlatacam. Kukusuz .Net
Framework ile birlikte gelen en byk yeniliklerden biri delege ve event kullanmdr. Bu
yan ile .Net Framework dier uygulama gelitirme ortamlarnn bir ksmndan daha stn
niteliklere sahip olmaktadr. imdi delege nedir biraz ondan bahsedelim. Delege basit
anlamda dnrsek araclk yapandr. Burada ise delege araclk yapan metod olarak
karmza kar. Yani baka bir metodun tetiklenmesine yardm eden metottur. Bu sayede
metodlarn tetiklenmesi dinamik olarak gerekleir. Olay(event) ise her zaman belki
farknda olmadan kullandmz kontroller gibidir. Yalnz delege ile olay arasndaki fark
delegelerin "invoke" edilmesi olaylarn ise "raise" edilmesidir. Daha basit olarak ifade
edersek olaylar delegelerin zel bir halidir. Delegeler olmadan olaylarn bir anlam yoktur.
Aslnda bir rnekle bunlarn nasl kullanldn aklarsam daha iyi anlalacaktr. imdi
ayn kaynamasn dnn. ay kaynad anda haberdar olmak istiyoruz ancak ayn
banda da beklemek istemiyoruz. Bu yzden bizi haberdar edecek zil alma metodunu
ayn kaynama metoduna balyoruz. Ve ay kaynad anda zil alma metodu da
otomatik olarak tetiklenmi oluyor. Delege ile olayn implementasyonunu aada
gstereceim ve bunlarla ilgili bir program de koyarak anlalmasn kolaylatracam.
nk bazen programlarla anlatmak istediklerimizi daha iyi anlatrz.

I. Olayn(event) yapl: Mousen tklanmas, form zerindeki bir tua baslmas, form
zerindeki bir linkin tklanmas vs bunlarn hepsi birer olaydr aslnda. imdi mouse
tklanmas ile ilgili bir kodu inceleyelim:

private void FareTikla()


{
// Buraya mouseun sol tklanmas durumunda yaplmas gereken

// ilemler gelecek.
}

// Burada fareye sol tkland zaman alacak olan metodu balyoruz. Bu ilemi de
doal olarak delegelerle yapyoruz. Buradaki '+=' operatrne dikkat ettiniz mi? Bu '+='
operatr fareye sol tklanmas olay karsnda raise edilecek eventi balamamza
yaryor.

Mouse.MouseClicked += new MouseClickedEventHandler(FareTikla);

// imdi de fare sol tkland zaman alacak olan metodu devreden karyoruz. Bu
sayede fare sol tkland zaman hi bir metot //devreye girmeyecektir. Yani farenin sol
tklanmasna herhangi bir tepki verilmeyecektir.

Mouse.MouseClicked -= new MouseClickedEventHandler(FareTikla);

II. Delegenin yapl: Delege kullanlaca zaman tek bana da kullanlabildii gibi
olaylara balanarak da kullanlabilmektedir. Bu yzden ilk nce olay(event) anlarsak
delegenin anlalmas daha da kolaylaacaktr. imdi basit bir delege nasl tanmlanr ona
bakalm.

// Tanmladmz delege double tipinde parametre alyor


// ve int tipinde deer dndryor.

public delegate int myDelegate(double D);

// Delegenin temsil edecei metodu yazalm.

public int ReturnInt(double D)

//Buraya metod alnca yaplmas gerekecek olan kod gelecek

// imdi de delegenin bir rneini yaratalm.

public void amethod(


{

myDelegate aDelegate = new myDelegate(ReturnInt);

//imdi de delegenin temsil ettii metodun nasl altrlacan salayan kodu yazalm.

aDelegate(3333);

imdi bu delege ve olay yaps bizim ne iimize yarayacak derseniz; yle bir senaryo
retelim: Birden fazla formda ayn anda altmz ve bu formlarn da birbirinin ayn
olduunu dnelim(ekilsel olarak tabii ki) ve bu formlardan herhangi birinin zerindeki
bir tua basld zaman btn formlarda hangi formun tklandna dair bir yaz yazmasn
isteyelim.

Bunu eer uzun yoldan yapmak isterseniz tek tek btn formlar iinde birer tane
deiken tanmlayp onu kontrol etmeniz gerekirdi. Sonra da tek tek dier formlara mesaj
gnderilmesini salamak gerekirdi. Bu ekilde yapmak uzun ve zahmetli bir i olurdu.

kinci yntem ise delege(temsilci) yapsn kullanmaktr. imdi her formumuz iin bir tane
forma mesaj yazacak olan bir metod olmal ve bu metod hangi formdaki yazdrma
tuunun tetiklendiini belirtmek iin bir tane de parametre almal. imdi de yukarda
anlattmz senaryonun kodunu inceleyelim.

Ana formumuz iinde tanmladmz delege ve olay yapsna bakalm. Burada delegemiz
tamsay(int) bir parametre alyor. Bu parametre sayesinde hangi formdaki tua baslarak
bu delegenin harekete geirildiini anlayabileceiz. Olaymza bakacak olursak olaymzn
bir st satrda tanmlanan delege tipinde olduunu grebiliriz.

sayac deikeni ise forma numara vermek iin tanmlanm bir deiken oluyor.

private int sayac = 0;

public delegate void userDelegate(int formNo);

public event userDelegate userEvent;


Yeni form oluturma tuuna baslnca ise yeni form oluturulacak ve bu formun iindeki
etikete yazma metodu olaya eklenecek.

sayac = sayac+1;

FrmUser frmUser=new FrmUser(sayac,this);

this.userEvent += new userDelegate(frmUser.writeFormNo);

Olaylara dorudan baka snflar altndan eriilebilse de bu yntem pek doru bir yol
olmayaca iin olaymz bir metodun iinde kamufle ederek kullanyoruz. O yzden
olaymz metodTetikle adnda bir metodun iinde kamufle ederek kullanyoruz. Baka bir
formdan iinden bu metod arld an otomatik olarak olaymz tetikleyip btn
formlara(ana formumuz hari) hangi formdan tua baldn yazacak.

public void metodTetikle(int formNo)


{
userEvent(formNo);
}

Bir de imdi olaydan belli bir delegenin karlmas ilemi var deil mi? yle ya yaratlan
formlardan bir tanesi kapatlrsa yazdrma metodunun tetiklenmesi istisnaya (exception)
yol aar. Bu yzden bu formun metodunun listeden karlmas gerekir. Aadaki kod bu
ii yaparak bizi istenmeyen hatalardan korumu olur.

public void elemanCikart(FrmUser frmUser)


{
this.userEvent -= new userDelegate(frmUser.writeFormNo);
}

Yukardaki kodun tamam ana formumuz iinde yer alan kodlard. imdi de ana formda
tua baslnca oluturulan formun iinde koda bakalm.

Formlara yaz yazdrmak iin tua bastmzda ana formumuzdaki metodTetikle


metodunu ararak olayn tetiklenmesini salyoruz.

private void btnActive_Click(object sender, System.EventArgs e)

form1.metodTetikle(formNo);

Ancak her formun iinde forma mesaj yazacak olan ksm aadaki metoddakigibidir.
imdi diyeceksiniz, niye ayn form iindeki metodu baka bir formu kullanarak
aryorsunuz. Ama buradaki fark ekrana mesaj yazacak olan form saysnn bir tane
olmamasdr. N tane forma ayn anda mesaj yazdrmak istediimiz iin bir baka snfta
veya formda tanmlanm olan bir olay tetikleyerek bu ii yapyoruz. Aksi halde N tane
formu tek tek dolamamz gerekirdi. Bu ise performans kaybna yol at gibi daha byk
programlarda kod karmaasna yol aabilmektedir.

public void writeFormNo(int tetiklenenNo)


{
lblAciklama.Text="Tua Baslan Form Numaras:"+tetiklenenNo;
}
Galiba bir tek sonradan oluturulmu bir form kapatlnca ana formumuzdaki delege
kartma metodunun nasl arlaca kald. Onu da sonradan oluturulan formumuzun
Dispose metodu iine aadaki gibi yazarsak hi bir ekilde hatayla karlamayz.

form1.elemanCikart(this);

Evet yukarda delege ve olayn nasl bir arada kullanldn basit bir rnek zerinde
anlatm oldum. Yukarda delege ve olayn bir arada kullanld rnek program buraya
tklayarak indirebilirsiniz.

Son olarak iyi anlayamadnz veya kafanza taklan ksmlar iin mail adresim
aytacozay@msakademik.net
C# ile "Bitmap to Binary" ve "Bitmap nceltme" Algoritmas

Bu yazda monochrome(siyah beyaz) Bitmap resimlerinin binary(0,1) formata


dntrlmesi ve dntrlen binary resim zerinde inceltme yapma algoritmasnn ne
ekilde uygulandna ilikin rnek uygulama vereceim.

Yazdm rnek uygulamann rnek ekran ktlar aadaki gibidir.

Siyah Beyaz formatndaki A4.bmp resminin ilk grnts binary formatndaki halidir,
ikinci grnt ise bu binary bilgilerin inceltilmesinden elde edilmitir.
Siyah Beyaz formatndaki B4.bmp resminin ilk grnts binary formatndaki halidir,
ikinci grnt ise bu binary bilgilerin inceltilmesinden elde edilmitir.

Not : ki resim arasndaki fark gremiyorsanz ekrannza biraz daha uzaktan a ekilde
bakn.

Yukardaki resim dosyalarn projedeki harfler klasrnde bulabilirsiniz.

Projeye ait kaynak dosyalar indirmek iin tklaynz.

Kaynak kodlarla ilgili her trl sorunuzu bana iletebilirsiniz.


Ref ve Out Anahtar Szcklerinin Kullanm

Bu yazda C#'n nemli iki anahtar kelimesi olan ve deer trleride dahil olmak zere
btn veri trlerini referans yolu ile metotlara aktarmamz salayan ref ve out'un
kullanmn gstereceim.

C# dilinde temel olarak iki veri tr vardr. Bunlardan birincisi referans trleri ikincisi
ise deer trleridir. Referans trleri bir ifade(metot arm, atama ifadesi vs.) iinde
kullanld zaman nesnenin bellekteki adresi zerinden ilem yaplr. Yani nesnenin
btn verisi ayrca kopyalanmaz. Deer trlerinde ise durum daha farkldr. Deer
trleri yani int, byte,bool gibi veri trleri herhangi bir ifade iinde kullanlrsa deikenin
yeni bir kopyas karlr ve ilemler bu yeni kopya zerinden gerekletirilir. Dolaysyla
orjinal nesnenin deeri hi bir ekilde deitirilemez. Asl konumuza gemeden nce
deikenlerin referans yolu ile aktarmnn ne demek olduunu ve bu iki tr arasndaki
fark daha iyi anlamak iin basit bir rnek vermekte fayda gryorum.

Aadaki programdaki gibi x ve y gibi iki int trnden deikenimiz olsun. Bu


deikenlerin deerlerini deitirmek(swap) iin Degistir() isimli bir metot yazmak
istediimizi dnelim. Bu metot ilk akla gelebilecek ekilde aadaki gibi yazlr.

using System;

namespace ConsoleApplication2
{
class Class1
{
static void Main()
{
int x = 10;
int y = 20;

Degistir(x,y);

Console.WriteLine("X = " + x.ToString());


Console.WriteLine("Y = " + y.ToString());
}

static void Degistir(int x, int y)


{
int temp = x;
x = y;
y = temp;
}
}
}

Yukardaki program derleyip altrdmzda x ve y deikenlerinin deerlerinin


deitirilmediini ve ayn deerde kaldklarn grrz. Bunun sebebi Degistir()
metoduna gelen x ve y deikenleri ile Main() metodunda tanmlam olduumuz x ve y
deikenlerinden tamamen bamsz yeni deikenler olmasdr. Dolaysyla Degistir()
metodunda yaptmz deiiklikler orjinal deikenlerimizi hi bir ekilde
etkilememitir. Deikenlerin bu ekilde aktarlmasna "deer yolu ile aktarma" yada
"pass by value" denilmektedir.

Yukardaki program aadaki gibi biraz deitirip x ve y deikenleri bir snf


araclyla metota gnderirsek deitirme ilemini yapabiliriz.

using System;

namespace ConsoleApplication2
{
class C
{
public int deger;
public C(int x)
{
deger = x;
}
}

class Class1
{
static void Main()
{
C x = new C(10);
C y = new C(20);

Degistir(x,y);

Console.WriteLine("X = " + x.deger.ToString());


Console.WriteLine("Y = " + y.deger.ToString());
}

static void Degistir(C x, C y)


{
int temp = x.deger;
x.deger = y.deger;
y.deger = temp;
}
}
}

Bu progrm derleyip altrdmzda x ve y nesnelerinin deger ye elamanlarnn yer


deitirildiini greceksiniz. Yer deitirmeyi yapabilmemizin sebebi x ve y
deikenlerinin referans yolu ile metoda geirilmesidir. Yani Degistir() metodundaki x
ve y deikenleri ile Main() metodundaki x ve y deikenleri bellekteki ayn blgeyi
temsil etmektedirler. Dolaysyla Degistir() metodunda yaptmz bir deiiklik Main()
metodundaki deikene de yansyacaktr. Nesnelerin metotlara bu ekilde aktarlmasna
ise "referans yolu ile aktarm" yada "pass by reference" denilmektedir.

Bir referans tipi olan string tr ile ilgili nemli bir istisna vardr. string
referans tr olmasna ramen metotlara string trnden deikenler
geirilirken deer tiplerinde olduu gibi kopyalanarak geirilirler. Yani int
trnden bir deiken ile string trnden bir deiken metotlara deer yolu ile
aktarlrlar. Bunu test etmek iin birinci programdaki int tr yerine string
trn kullanabilirsiniz.

Ref Anahtar Szc

Yukarda denildii gibi deer tipleri(int, double, byte vs.) metotlara kopyalanarak
geirilirler yani deikenin birebir yeni bir kopyas oluturulur. Ancak baz durumlarda
deer tiplerini de referanslar ile metotlara geirmek isteyebiliriz. C ve C++ dillerinde
deer tiplerini referans yolu ile geirmek iin gstericilerden faydalanr. Yani metotlara
deikenlerin adresleri geirilir. C# ta bu ilemi yapmak iin gsterici yerine yeni bir
anahtar szck olan ref kullanlr. ref anahtar szc deer trlerinin metotlara
referans yolu ile geirilmesini salar. Referans trleri zaten referans yolu ile geirildii
iin bu trler iin ref anahtar szcn kullanmak gereksizdir. Ancak kullanm
tamamen geerli klnmtr.

ref szc metot armnda ve metot bildiriminde ayn anda kullanlmaldr. Yani
metot bildiriminde ref ile birlikte kullanlan bir deiken, metot arlrken ref ile
arlmaldr. Yukarda yazdmz birinci program ref szcnn kullanm ile yeniden
dzenlersek Degistir() metodunun istediimiz ekilde almasn salayabiliriz.

using System;

namespace ConsoleApplication2
{
class Class1
{
static void Main()
{
int x = 10;
int y = 20;

Degistir(ref x,ref y);

Console.WriteLine("X = " + x.ToString());


Console.WriteLine("Y = " + y.ToString());
}

static void Degistir(ref int x, ref int y)


{
int temp = x;
x = y;
y = temp;
}
}
}

Bu program derleyip altrdmzda x ve y deikenlerinin deerlerinin deitirildiini


greceksiniz. nk Degistir() metoundaki x ve y deikenleri ile Main() metodundaki x
ve ye deikenleri ayn bellek blgesindeki deeri temsil etmektedirler. Birinde yaplan
deiiklik dierinide etkilemektedir. Yani ilk durumdan farkl olarak ortada iki deiken
yoktur, tek bir deiken vardr.

Unutmamamz gereken nokta metot armnn da ref anahtar szc ile birlikte
yaplmas zorunluluudur. Eer Degistir() metodunu Degistir(ref x, ref y) yerine
Degistir(x,y) eklinde arm olsaydk derleme aamasnda

Argument '1': cannot convert from 'int' to 'ref int'


Argument '2': cannot convert from 'int' to 'ref int'

hatalarn alrdk.

ref szcnn kullanm ile ilgili dier bir nemli nokta ise ref ile kullanlacak
deikenlere mutlaka deer atanm olma zorunluluudur. Herhangi bir deer
verilmemi deikeni ref ile de olsa kullanamayz. Kullandmz takdirde ise derleme
aamasnda "Use of unassigned local variable" hatasn alrz. Bu durum ref szcnn
bir kst olarak dnlebilir. Ancak birazdan greceimiz out szc ile bu kst
ortadan kaldrabileceimizi greceiz.

Out Anahtar Szc

Out anahtar szcnn kullanm amac ref anahtar szcnn kullanm ile tamemen
ayndr. Yani out ile de deer tipleri referans yolu ile aktarlr. Aralarndaki tek fark out
ile kullanlacak deikenlere ilk deer verme zorunluluunun olmamasdr. Yani ref
szcnn kullanmndaki kst, out ile birlikte ortadan kaldrlmtr. out anahtar
szcn genellikle bir metottan birden fazla geri dn deeri bekliyorsak kullanrz.

Yukardaki Degistir() metodunu out ile kullanlabilecek ekilde deitirdiimizde x ve y


deikenlerine ilk deer verme zorunluluumuz kalkacaktr.

ref ve out szcklerinin C# dilinde kullanlmasnn kk bir fark olsada IL dilinde ref
ve out ayn ekilde implemente edilmitir. ILDASM arac ile Degistir() metodunun hem
ref hemde out versiyonlarnn bildiriminin aadaki gibi olduunu grrz.

.method private hidebysig static void Degistir(int32& x, int32& y) cil managed


{
.maxstack 2
.locals init (int32 V_0)
IL_0000: ldarg.0
IL_0001: ldind.i4
IL_0002: stloc.0
IL_0003: ldarg.0
IL_0004: ldarg.1
IL_0005: ldind.i4
IL_0006: stind.i4
IL_0007: ldarg.1
IL_0008: ldloc.0
IL_0009: stind.i4
IL_000a: ret
}

Bu durum ref ve out szcklerinin kullanmndaki farkn C# derleyicisi ile snrl


olduunu gstermektedir. Yani CLR ile ilgili bir fark deildir.

Yazy bitirmeden nce out anahtar szcnn kullanmna bir rnek vermek istiyorum.
ki saydan byk olanna geri dnen bir metot yazmak istediimizi dnelim. Ayn
zamanda da bu iki saydan birincisinin mi ikincisinin mi byk olduunuda bu metotla
renmek istiyoruz. Her metodun tek bir geri dn deeri olabileceine gre klasik
yntemlerle bunu ideal(!) bir ekilde gerekletiremeyiz. Bunun iin ilk deer
verilmemi yeni bir parametreyi daha Max() isimli metoda gndereceiz. Bu parametre
metot iinde deitirilerek kendisini aran metoda iletilecektir.

using System;

namespace Out
{
class Class1
{
static void Main()
{
bool b;

int max = Max(9,2,out b);

Console.WriteLine(b);
}

static int Max(int x,int y, out bool b)


{
if(x > y)
b = true;
else
b = false;

return Math.Max(x,y);
}
}
}

Yukardaki ilemi ref anahtar szc ile de yapabilirdik ancak bir metodun iinde
deeri belirlenecek bir deikene ilk deer vermek gereksiz ve mantkszdr. Dolaysyla
bir metodun birden fazla deer geri vermesini istediimiz durumlarda out anahtar
szcn kullanmamz daha okunabilir ve daha dzenli programclk asndan
nemlidir.

Bir sonraki yazda grmek zere...


Abstract Factory Tasarm Deseni(Design Pattern)

Singleton deseni ile baladm "design pattern" yaz dizisine "Abstract Factory" deseni ile
devam ediyoruz. Bu yazda "Creational" desenler grubunun en nemli ve en sk kullanlan
deseni olan Abstract Factory(Soyut Fabrika) tasarm deseninin C# ile ne ekilde
uygulandn bir rnek zerinden gstereceim.

lk yazmda da bahsettiim gibi "Creational" grubundaki desenler bir yada daha ok


nesnenin eitli ekillerde oluturulmas ile ilgili desenlerdir. Bu kategoride ele alnan
"Abstract Factory" ise birbirleriyle ilikili yada birbirlerine bal olan nesnelerin
oluturulmasn en etkin bir ekilde zmeyi hedefler. Bu hedefe ulamak iin soyut
snflardan(abstract class) veya arayzlerden(interface) youn bir ekilde
faydalanmaktadr. "Abstract Factory" deseninin ana temas belirli snflarn ierdii ortak
arayz soyut bir snf yada arayz olarak tasarlamaktr. Bylece nesneleri reten snf,
hangi nesnenin retilecei ile pek fazla ilgilinmesi gerekmez. lgilenmesi gereken nokta
oluturaca nesnenin hangi arayzleri destekledii yada uyguladdr. Bahsi geen
mekanizmalarla deseni oluturduumuz anda alma zamannda hangi nesnenin
oluturulmas gerektiini bilmeden nesnelerin oluturulmasn ynetebiliriz.

Eer bir nesne oluturacaksanz ve tam olarak hangi nesnenin oluturulacana bir switch
yada if deyimi ile karar veriyorsanz muhtemelen her nesneyi olutruduunuzda ayn
switch yapsn kullanmak zorunda kalacaksnz. Bu tr tekrarlar nlemek iin "Abstarct
Factory" deseninden faydalanlabilir. Bu elbetteki nesnelerin ortak bir arayz uygulam
olma zorunluluunun getirdii bir faydadr.

imdi de gerek dnyadan bir rnek vererek "Abstract Factory" deseninin hangi
durumlarda kullanabileceimizi ve soyut fabrika mantn netletirelim. Bir CD srcs
dnn. CD srcs kendisine srlen CD leri okumakla sorumludur. Hi bir zaman
srlen CD nin ekli ve biimiyle ilgilenmez. Ama srlen CD nin okunabilmesi iin de
belirli artlarn yerine getirildiini farzeder. Yani siz CD srcsne CD olmayan ama CD
ye benzeyen bir cisim yerletiriseniz onu da okumaya alr.(eer CD srcnz
bozulmazsa!) nk okumaya alt cismin ne olduu ile pek ilgilenmez CD srcs.
Buradaki rnekte CD srcsnn okuma yapabilmesi iin gereken artlar bir soyut
fabrika snf ile modelleyebiliriz. Kare yada daire eklindeki gerek CD ler ise bu soyut
fabrika snf tarafndan belirlenen artlar destekleyen gerek nesnelerdir. CD
srcsnn kendisi ise soyut fabrika tarafndan belirlenen standartlar erevesi
ierisinde CD nin ne tr bir CD olduundan bamsz bir ekilde bilgiyi okuyan birimdir.
Bu, "abstract factory" desenindeki client yani istemci snfa denk der ki bu snf
nesnelerin yaratlmasndan sorumludur.

Bu giri bilgilerinden sonra "abstract factory" deseninin temel zelliklerini ksaca


zetleyelim.

"Abstract Factory", nesneleri oluturan bir snftr. Oluturulan bu nesneler


birbirleriyle ilikili olan nesnelerdir. Dier bir deyile ayn arayz uygulam olan
nesnelerdir.

retilen nesnelerin kendisiyle ilgilenilmez. lgilenilen nokta oluturulacak


nesnelerin salad arayzlerdir. Dolaysyla ayn arayz uygulayan yeni
nesneleri desene eklemek ok kolay ve esnektir.

Bu desende retilecek nesnelerin birbirleriyle ilikili olmas beklenir.

UML Modeli

Aadaki ekil "abstract factory" tasarm deseninin yapsal UML diagramn


gstermektedir. emadaki her bir ekil desendeki bir snf modellemektedir. Ayrca
desendeki snflar arasndaki ilikilerde detayl bir ekilde gsterilmitir.
Yukarda emay ksaca aklamakta fayda var. emadan da grlecei zere "abstract
factory" deseninde 3 ana yap vardr. lk yap nesnelerin oluturulmasndan sorumlu
soyut ve gerek fabrikalar, ikinci yap soyut fabrikadan treyen gerek fabrikalarn
rettii rnleri temsil eden soyut ve gerek rn snflar, son yap ise herhangi bir
rn, kendisine parametre olarak verilen soyut fabrikalar kullanarak reten
istemci(client) snfdr.

SoyutFabrika snf gerek fabrikalarn uygulamas gereken arayz temsil eder. Bu snf,
btn metotlar soyut olan snf olabilecei gibi bir arayz de olabilir. Uygulamanzn
ihtiyacna gre dilediinizi kullanabilirsiniz. SoyutFabrika snfnda rn1 ve rn2'nin
retilmesinden sorumlu iki tane metot bulunmaktadr. Dolaysyla btn gerek
fabrikalarn hem rn1'i hemde rn'yi rettii kabul edilmektedir. Her bir rnn ortak
zelliklerini belirlemek ve ana yapda toplamak iin SoyutUrun1 ve SoyutUrun2 snflar
oluturulur. Bu snflarda herhangi bir rne zel bilgi bulunmamaktadr. Asl bilgi bu
soyut rnlerden treyen GercekUrun snflarnda bulunmaktadr. Her bir fabrikann
rettii rnleri modelleyen snflarda yukardaki ekilde gsterilmitir. Asl nemli mesele
ise gerek fabrikalarn retimden sorumlu metotlarnn ne ekilde geri dneceidir.
Yukardaki emadan da grlecei zere bu metotlar retecei rnn soyut snfna
dnmektedir. Yani retim sonucunda geri dnen gerek rn nesnesi deildir. emada
Client olarak gsterilen snfn yaps ise u ekildedir : Client snf yapc metoduna bir
soyut fabrika nesnesi alr. Ve soyut fabrikann retimden sorumlu metotlarn kullanarak
soyut rnleri retir. Dikkat ederseniz Client snf hangi gerek fabrikann retim
yaptndan ve retilen rnn gerek zelliklerinden haberi yoktur. Client sadece soyut
fabrikann ierdii temel zelliklerin farkndadr. Bunu emadaki kaln ve kesikli oklardan
grmek mmkndr.

Desenin C# ile Gerekletirilmesi

Yukardaki yapsal rnei verdikten sonra gerek bir rnek ile bu deseni nasl
gerekletirebileceimizi inceleyelim. Bu rnekte araba kasas ve araba lastii reten
farkl iki firmann retimi modellenmektedir.

nce rnei kabaca inceleyin, ardndan aklamalar okuyun.

using System;

namespace DesignPattern
{
abstract class SoyutArabaFabrikasi
{
abstract public SoyutArabaKasasi KasaUret();
abstract public SoyutArabaLastigi LastikUret();
}

class MercedesFabrikasi : SoyutArabaFabrikasi


{
public override SoyutArabaKasasi KasaUret()
{
return new MercedesE200();
}

public override SoyutArabaLastigi LastikUret()


{
return new MercedesLastik();
}
}

class FordFabrikasi : SoyutArabaFabrikasi


{
public override SoyutArabaKasasi KasaUret()
{
return new FordFocus();
}

public override SoyutArabaLastigi LastikUret()


{
return new FordLastik();
}
}
abstract class SoyutArabaKasasi
{
abstract public void LastikTak(SoyutArabaLastigi a );
}

abstract class SoyutArabaLastigi


{
}

class MercedesE200 : SoyutArabaKasasi


{
public override void LastikTak(SoyutArabaLastigi lastik)
{
Console.WriteLine( lastik + " lastikli MercedesE200");
}
}

class FordFocus : SoyutArabaKasasi


{
public override void LastikTak(SoyutArabaLastigi lastik)
{
Console.WriteLine( lastik + " lastikli FordFocus");
}

class MercedesLastik : SoyutArabaLastigi


{

class FordLastik : SoyutArabaLastigi


{

class FabrikaOtomasyon
{
private SoyutArabaKasasi ArabaKasasi;
private SoyutArabaLastigi ArabaLastigi;

public FabrikaOtomasyon( SoyutArabaFabrikasi fabrika )


{
ArabaKasasi = fabrika.KasaUret();
ArabaLastigi = fabrika.LastikUret();
}

public void LastikTak()


{
ArabaKasasi.LastikTak( ArabaLastigi );
}
}

class UretimBandi
{
public static void Main()
{
SoyutArabaFabrikasi fabrika1 = new MercedesFabrikasi();
FabrikaOtomasyon fo1 = new FabrikaOtomasyon( fabrika1 );
fo1.LastikTak();

SoyutArabaFabrikasi fabrika2 = new FordFabrikasi();


FabrikaOtomasyon fo2 = new FabrikaOtomasyon( fabrika2 );
fo2.LastikTak();
}
}
}

Yukardaki rnekte SoyutArabaFabrikasi snf iki metot iermektedir. Bu metotlar


SoyutArabaFabrikasi snfndan treyecek snflarn uygulamas gereken metotlardr.
nk metotlar abstract olarak bildirilmitir. Bu metotlar gerek fabrika snflarnn araba
kasas ve araba lastii retmesi gerektiinin belirtisidir. Zira grld zere
SoyutArabaFabrikasi snfndan treyen MercedesFabrikasi ve FordFabrikasi kendilerine
has lastikleri ve kasalar retmek iin soyut fabrika snfnn metotlarn kullanmaktadr.
Bu metotlar geri dn deeri olarak soyut rn snflarn temsil eden snflar
dndrmektedirler. rnein KasaUret() metodu her bir fabrika iin farkl rn retmesine
ramen her bir rn SoyutArabaKasasi snfndaki metotlar uygulad iin gerek rnler
birbirleyile ilikili hale gelir. Mercedes fabrikas KasaUret() metodu ile MercedesE200
rnn dndrmesine ramen Ford fabrikas ayn metotla FordFocus rnn
dndrmektedir. Ancak her iki fabrikann da rettii rn SoyutArabaKasasi snfndan
tredii iin herhangi bir eliki olmamaktadr.

SoyutArabaKasasi snfndaki LastikTak() snf fabrikadan retilen rnlerin birbirleriyle


kartrlmadan esnek bir ekilde nasl ilikilendirildiini gsterilmektedir. Bu metot
parametre olarak gerek lastik rn yerine soyut lastik rn alr. Dolaysyla herhangi
bir fabrikadan retilen lastik rn bu metoda parametre olarak geirilebilir.

FabrikaOtomasyon snf kendisine verilen bir soyut fabrika nesnesi zerinden kasa ve
lastik retir ve retilen lastii, lastiin gerek trn bilmeden retilen araba kasas ile
ilikilendirir. Dikkat ederseniz bu snf retimin yaplaca fabrikann hangi fabrika olduu
ve retilen rnlerin gerekte hangi rnler olduu ile ilgilenmez.

Son olarak tasarladmz btn bu snflar test edecek UretimBand snfn inceleyelim.
Bu snf ierisinde rnleri retilecek fabrikann soyut nesnesi oluturulur ve
FabrikaOtomasyonu nesnesine parametre olarak verilir. SoyutFabrika nesnesini alan
FabrikaOtomasyonu bu nesnenin standart retimden sorumlu metotlarn kullanarak kasa
ve lastik retir. Ardndan SoyutArabaKasasi snfnn LastikTak() metodunu kullanarak
kasa ve lastik rnlerini ilikilendirir.

Bu rnekte kullanlan soyut snflarn yerine arayzleride kullanmak mmkndr. Daha


nce de dediim gibi siz uygulamanzn durumuna gre herhangi birini seebilirsiniz.

Dier bir "Creational" deseni olan "Builder" desenini anlatacam yazda grmek
zere...
C# ile .NET Ortamnda Threading'e Giri

nsan vcudunda ayn anda bir ok i birlikte yaplr, mesela kalbimiz tm vcuda kan
pompalarken midemiz yediimiz bir eyi sindirmek iin gerekli enzimleri salglar:
Bilgisayarlarn zaman iinde ok hzl gelimeleri sonucunda insanlar bu aletlerden daha
fazla verim ve hz beklediler ve ortaya atlan birok zmden biri de i paracklarn
(threads) kullanmak olmutur.

paracklar ilk defa Ada programlama dilinde Amerikan ordusunun stratejik yazlmlar
iin kullanlmtr. Daha sonra C++ dilinde i paracklarn kullanmak iin ktphaneler
gelitirilmitir. Bu ktphaneler sayesinde zaman iinde C++ dilinde yazlm
programlarda i paracklarn kullanmak bir takm faydalar salamtr.

paracklarn .NET ortamnda nasl kullanacamz renmeden nce iin teorik


temellerini bilmek gerekir. Ayrca i paracklarn ne zaman ve nasl programlarmza
katmay da renmek daha salkl programlar gelitirmeye yardmc olacaktr.
Makalemizin kalan ksmn MSDN ktphanesindeki i paracklar konusunun ba
ksmlar oluturacaktr.

letim sistemlerinde ayn anda birden fazla programn almas gnmzde mmkn
hale gelmitir. Aslnda bir ilemcide ayn anda sadece bir ilem gerekleebilir. Fakat
balayan bir ilemin tamamn bitirmeden baka bir ilemin yaplmas ile multitasking
baarlabalir. Mesela bir taraftan Ms Word dier taraftan Ms Explorer ak olabilir.
lemlerin bir alt paras olan i paraklar (threadler) ayn zamanda bilgisayar
ortamnda yaplacak olan en kk grev birimleridir denilebilir. Bir ilem(process) iinde
birden fazla i parac bulunabilir. Her bir i parac iin hata ynetimi(expection
handler), ncelik izelgesi (scheduling priority) ve bir takm yaplar bulunur. Bir nceki
cmlede bahsettiimiz yaplar i parac hakknda iletim sisteminin tuttuu bilgilerdir.
Bu bilgiler ile i paracklarnn sorunsuz olarak altrlmas salanr.

.NET platformu ilemleri(process) daha kk bir birim olan application domain'lere


ayrr. Application domain'ler System.AppDomain sistem alanndaki snflar tarafndan
ilenirler. .NET'te bir veya daha fazla i parac birden farkl application domain iin
alabilir. Her ne kadar bir application domain sadece bir tane i parac ile almaya
balasa da zaman iinde birden fazla application domain ve i parac ayn application
domain iin alabilir. Ayrca tek bir i parac birden farkl application domain'ler
arasnda gidip gelebilir.

Eer bir iletim sistemi preemtive multitasking'i destekliyorsa bilgisayarda birden fazla
programn ayn anda alyormu hissi yaratlabilir. Bunun iin iletim sistemi her bir
ilemin belirli bir sre (time slicing) ilemciyi megul etme hakk tanr. lemci kullanm
sresi dolan ilem bekletilmeye alnr ve bu ilem hakkndaki bilgiler bir yere not edilir.
Sonra srada bekleyen (thread queue) baka bir ilemin belirli bir sre ilemciyi
kullanmasna izin verilir. kinci ilemin de sresi dolunca bu ilem hakknda bilgiler bir
yere kaydedilir ve tekrar kuyrua geri dner. Sonra sradaki dier ileme balanr... Ve bu
ekilde devam eder.

lemlerin ilemciyi kullanma aralklar iletim sistemine ve ilemciye gre deiir.


lemciyi kullanma aralklar o kadar kk ve ilemciler o kadar hzldr ki bir ok i
paracnn altrld bir iletim sisteminde ayn anda birden farzla programn alt
hissi kullancda uyanr.
Ne Zaman Birden Fazla Parac ile almal?
Eer gelitirdiimiz programlar kullanc ile sk sk etkileime geiyor ve kullanclara
sistemin cevabnn ok hzl olmas gerekiyorsa i paracklarn kullanmak yerinde
olacaktr. Eer sizin programnzda sadece bir i parac yeterli oluyorsa ve .NET
remoting veye XML Web servisleri kullanyorsanz yine i paracklarndan faydalanmak
suretiyle programnzn kullancya verecei tepkiyi daha ksa srede retebilirsiniz. Son
olarak youn bir biimde I/O ilemleri gerektiren programlarda i paracklarndan
faydalanmak uygun olacaktr.

oklu Paracklarnn Avantajlar

Birden fazla i parac kullanmakla hem programn kullancya olan cevap sresi
(Kullanc arayznde) ksalr hem de ayn anda arka planda verilerin hzlca ilenip
sonuca ulalmas salanr. Mesela biz bir taraftan Excel alma sayfasna verileri
giriyorken dier taraftan Excel alma sayfasnda tanmlanan formllere gre dier
hcrelerin deerlerini hesaplayp yazar.

Bir programda hem i paracklar kullanlr hem de bu program birden fazla ilemcisi olan
bir makinada altrlrsa kullanclarn programdan memnuniyetlerinde ok ileri seviyede
artlar olur. Gelitirdiimiz bir programda birden fazla i paras kullanmakla:

A zerinde, web sunucu ile yada veritaban ile veri alverii


ok uzun sren hesaplamal ilemleri
Farkl ncelikteki grevlerde. (Mesela yksek ncelikli i paracklar ile hemen
bitirilmesi gereken ilemler yaplrken dier i paraklar baka ileri yapabilir.)
Grafik arayznde kullancya daha hzl cevap verilirken arka planda dier veri
ileme ileri gerekleir.

oklu Paracklarnn Dezavantajlar

Mmkn olduunca az sayda i paracn ayn anda kullanmak tavsiye edilir. Bu ekilde
iletim sisteminin daha az kaynan kullanr ve performans artrabiliriz. Ayrca i
paracklar iin hem ek kaynak gereksimi hem de programda akma ihtimalleri vardr.
paracklar iin gerekli ek kaynaklar unlardr:

letim sistemleri ilemler, AppDomain nesneleri ve i paracklar hakknda


bilgileri tutmak zordundadrlar. Yani, ilemler, AppDomain nesneleri ve i
parklarnn oluturulmasnda kullanlabilir hafza snrlayc bir etken olabilir.
ok sayda i paracklar ile alma durumlarnda, ilemci i paracklarnn
gerektirdii ileri yapmaktan ok i paracklar arasnda gei iin megul olur.
Ayrca bir ilemin iinde ok sayda i parac varsa bu i paracklarnn
ilenmesi iin daha az sayda ans doacaktr.
Birden fazla i parac ayn anda ilemye almak ok karmak bir durum
yaratr ve bir ok hataya sebep olabilir.
Bir i parannn ii bittiinde onu yok etmek iin yine ok karmak kodlar
yazmak ve sonularn tahmin etmek gerekir.

Kaynaklar paylamak ve birden fazla ilem iin ayn anda kullanmaya almak sistemde
akmalara yol aabilir. Muhtemel akmalarn nne gemek iin senkronizasyon
yapmak veya paylalan kaynaklara eriimi kontrol altna almak gerekir. Ayn veya farkl
AppDomain'lerde eriimleri senkronize etmede baarszlk durumumda deadlock (ayn
anda iki i paracnn bo durduklar halde birbirlerini sonsuza kadar beklemleri)
problemi ortaya kabilir. Fakat sistemin salad senkronize nesneleri ile ayn kaynan
farkl farkl i paracklar tarafndan kullanlmas koordine edilebilir. Tabiki i
paracklarnn saysn azaltmak da kaynaklarn senkronize olarak kullanlmasn
kolaylatrr.

Senkronize edilmesi gereken kaynaklar unlardr:

Sistem kaynaklar (iletiim portlar gibi)


Birden fazla ilem tarafndan kullanlan kaynaklar.(dosya yneticileri)
Tek bir AppDomain'e ait (global, satic ve rnek veri alanlar) fakat farkl i
paracklar tarafndan kullanlan kaynaklar.

Paracklar ve Uygulama Tasarm

Genelde ksa srecek grevler ve zel olarak zamanlama gerektirmeyen i paracklar


iin ThreadPool snfn kullanmak en kolay yoldur. Fakat bir ok sebebten dolay
kendimize ait thread snfn yazmak daha iyi olacaktr. Bunun en nemli nedenleri
unlardr:

Eer zel ncelie sahip bir grev tanmlayacak ve kullanacaksak.


Eer uzun srebilecek bir i yapmak gerekiyorsa.
Eer i paracklarnz tek-i parac aparmanna koymak gerekiyorsa
(ThreadPool snfndaki tm i paracklar oklu-iparac apartmanna koyulur.)
Eer bir i parac iin sabit bir kimlik kullanmak gerekiyorsa .

leriki yazlarda .NET ortamnda C# ile i paracklarnn kullanmlarn daha detayl olarak
inceleyeceiz ve bir ok rnek kod zerinde duracaz.
C# ile lgili Sk Sorulan Sorular (SSS)

Bu yazda C# dili ilgili sk sorulan sorulara yant verilmitir.

Aadaki C# ile ilgili sk sorulan sorular www.msdn.com adresinde faaliyet


gsteren Microsoft Visual C# ekibi tarafndan hazrlanmtr.

S - 1 : DllImport niteliini neden altramyorum?

C - 1 : DllImport ile iaretlenen btn metotlar public static extern olarak


bildirilmelidir.

S - 2 : Yazdm switch ifadeleri farkl bir biimde alyor. Neden?

C - 2 : C# case bloklar iin "explicit fall through" zelliini desteklemez. Buna gre
aadaki kod paras geersizdir ve C#'ta derlenemez.

switch(x)
{
case 0:
// bir eyler yap
case 1:
// 0 case'indekine ek olarak bireyler daha yap
default:
// 0 ve 1 durumlarna ek olarak bireyler daha yap

break;
}

Yukardaki kodun verdii etkiyi C# ile aadaki gibi gerekletirrebiliriz. (Case' ler
arasndaki akn aka belirtildiine dikkat edin!)

class Test
{
public static void Main()
{
int x = 3;

switch(x)
{
case 0:
// bir eyler yap
goto case 1;
case 1:
// 0 case'indekine ek olarak bireyler daha yap
goto default;
default:
// 0 ve 1 durumlarna ek olarak bireyler daha yap
break;
}
}
}
S - 3 : const ve static readonly arasndaki farklar nelerdir?

C - 3 : static readonly elemanlar bulunduklar snfn ye elemanlar tarafndan


deitirilebilir(!), fakat const olan ye elamanlar asla deitirilemez ve derleme zaman
sabiti olarak ilk deerleri verilmelidir.

static readonly ye elemanlarnn deitirilebilmesini biraz aacak olursak, static readonly


yeyi ieren snf bu yeyi aadaki durumlarda deitirebilir :

- deiken ilk deer verilen durumda


- static yapc metotlar iinde

S - 4 : trace ve asssert komutlarn nasl gerekleyebilirim?

C - 4 : Metotlarla birlikte Conditional niteliini kullanarak gerekleyebiliriz.

class Debug
{
[conditional("TRACE")]
public void Trace(string s)
{
Console.WriteLine(s);
}
}

class MyClass
{
public static void Main()
{
Debug.Trace("hello");
}
}

Yukardaki rnekte Debug.Trace() metodu ancak ve ancak TRACE nilemci sebol


tanmlanmsa arlacaktr. Komut satrndan n ilemci sembollerini tanmlamak iin /D
parametresi kullanlabilir. Conditional nitelii ile bildirilen metotlarn geri dn deerinin
void olma zorunluluu vardr.

S - 5 : C#'ta dll oluturmak iin ne yapmalym?

C - 5 : Derleyicinin /target:library argmann kullanmanz gerekir.

S - 6 : checked isimli bir deiken tanmladmda neden derleme zamannda "syntax


error" hatas alyorum?

C - 6 : nk checked C#'ta bir anahtar szcktr.


S - 7 : Bir yapc metot iinde ar yklenmi baka bir yapc metot nasl arlr (this()
ve yapcmetotad() eklindeki armlar derlenmiyor)?

C - 7 : Dier bir yapc metot aadaki gibi arlabilir.

class B
{
B(int i)
{ }
}

class C : B
{
C() : base(5) //
B(5) i arr.
{ }

C(int i) : this() // C()


yi arr.
{ }

public static void


Main() {}
}

S - 8 : C#'ta Visual J++ ta bulunan instanceof operatrnn karl varmdr?

C - 8 : Evet, is operatr bunun karldr. Kullanm aadaki gibidir :

ifade is tr

S - 9 : C#'ta enum sabitleri nasl kullanlr.

C - 9 : enum trlerinin kullanmna bir rnek :

namespace Foo
{
enum Colors
{
BLUE,
GREEN
}

class Bar
{
Colors color;
Bar() { color = Colors.GREEN;}

public static void Main() {}


}
}
S - 10 : Geri dn deeri olmayan bir metot bildirimi yaptmda neden (CS1006) hatas
almaktaym?

C - 10 : Bir metodun geri dn deerini yazmadan bildirirseniz derleyici onu sanki bir
yapc metot bildiriyormusunuz gibi davranr. O halde geri dn deeri olmayan bir
metot bildirimi iin void anahtar szcn kullann. Aada bu iki kullanma rnek
verilmitir.

// Bu bildirim CS1006 hatas verir.


public static staticMethod (mainStatic obj)

// Bu metot ise istenildii gibi alr.


public static void staticMethod (mainStatic obj)

S - 11 : Her birinde farkl Main() metodu olan birden fazla kaynak kod dosyam var:
derleme srasnda hangi Main() metodunun kullanlacan nasl bildirebilirim?

C - 11 : Programnzn giri noktas(metodu) Main isimli herhangi bir parametre almayan


yada string trnden bir dizi parametresi alan geri dn deeri void yada int olan static
bir metot olmaldr.

C# derleyicisi programnzda birden fazla Main metodu bildirmenize izin verir fakat hangi
Main() metodunu kullanacanz derleme zamannda bildirmeniz gerekir. Main()
metodunu belirtirken Main metodunun bulunduu snfn tam yolunu belirtmeniz gerekir.
Komut satrndan kullanlan /main argman bu ie yarar.(rn : csc /main:MainSnf *.cs)

S - 12 : Console.WriteLine() metodu bir string iinde NULL karakteri grdnde ekrana


yazma ilemini durdururmu?

C - 12 : alma zaman iin string trleri NULL ile sonlandrlm trler deildir.
Dolaysyla bir string iine NULL karakteri gmebilirsiniz. Console.WriteLine() ve buna
benzer metotlar string deikeninin sonuna kadar ilem yaparlar.

S - 13 : C# ta "Multicast Delegate"(oklu temsilciler) bildirmek mmknmdr,


mmknse sentaks nasldr?

C - 13 : Btn temsilciler varsaylan olarak multicast olarak bildirilir. Dolaysyla Visual J+


+ taki gibi ayrca multicast anahtar szc yoktur.

S - 14 : Delegate/MulticastDelegate (Temsilciler) nasl bildirilir?

C - 14 : C# ta temsilci bildirimi iin sadece bir parametreye ihtiyacmz vardr : metot


adresi. Dier dillerden farkl olarak C# ta metodun adresi ayn zamanda bu metodun
hangi nesne zerinden de arlacan tutabilir, dier dillerde ise temsilcilern temsil
etttii metodu arabilmek iin ayrca nesnelere ihtiya duyulur. rnein
System.Threading.ThreadStart() metodunun kullanmna bakalm.
Foo MyFoo = new Foo();
ThreadStart del = new ThreadStart(MyFoo.Baz);

Bu, static ve instance metotlarnn ayn sentaks ile arlabileceini gstermektedir.

S - 15 : Yaptm windows pencere uygulamasn her altrdmda neden pop up


eklinde konsol ekran gsteriliyor.

C - 15 : Proje ayarlarnda "Target Type" zelliinin Console Application yerine Windows


Application olduuna emin olun. Eer komut satr derleyicisini kullanyorsanz /target:exe
argman yerine /target:winexe argmann kullann.

S - 16 : Gereksiz p toplaysnc(Garbage Collection) zorla armann bir yolu var m?

C - 16 : Evet; Btn referasnlar null deer atayn ve System.GC.Collect() statik


metodunu arn.

Yklmas(destruct) gereken nesneleriniz var ve GC nin bunu yapmadn dnyorsanz


nesneleri null deere atayarak onlarn sonlandrc metotlarnn arlmasn salayn ver
ardndan System.GC.RunFinalizers() metodunu arn

S - 17 : C#, C dilindeki makrolar destekliyormu?

C - 17 : Hayr, C# ta makro yoktur.

__LINE__ ve __FILE__ gibi C dilinde nceden tanmlanm baz makrolarn


System.Diagnostics isim alanndaki StackTrace ve StackFrame gibi COM+ ile ilgili
snflardan elde edilebileceini unutmayn. Fakat bunlar sadece Debug moddaki derleme
iin alacaktr.

S - 18 : C# derleyicisine baz dll leri referans vermememe ramen neden kendisi


referans verir.

C - 18 : "csc.rsp" dosyasnda bulunan btn assembly lere C# derleyicisi otomatik olarak


referans verir. Bu dosyann ierdii assembly leri /r argman ile belirtmek zorunda
deilsiniz. csc.rsp dosyasnn kullanmn komut satrndan /noconfig argmann belirterek
engelleyebilirsiniz.

Not : Visual Studio IDE si hi bir zaman csc.rsp dosyasn kullanmaz.

S - 19 : Delegate/MulticastDelegate (Temsilciler) nasl bildirilir?

C - 19 : Aada DllImport niteliinin kullanmna bir rnek verilmitir.

using System.Runtime.InteropServices;
class C
{
[DllImport("user32.dll")]
public static extern int MessageBoxA(int h, string m, string c, int type);

public static int Main()


{
return MessageBoxA(0, "Hello World!", "Caption", 0);
}
}

Yukardaki rnek kod ynetilmeyen(unmanaged) DLL deki doal(native) bir fonksiyonu


C# ta bildirmek iin minumum gereksinimleri gsterir.C.MessageBoxA() metodu static ve
extern szckleri ile bildirilmi, DllImport nitelii ile bu metodun user32.dll dosyasnda
MessageBoxA ismiyle uygulanm olduu belirtilmektedir.

S - 20 : COM+ runtime'nda tanmlanan bir arayz uygulamaya alyorum ancak


"public * Object GetObject{...}" almyor gibi. Ne yapmalym?

C - 20 : Managed C++'ta "Object * GetObject()"(object trnden gsterici) sentaks


geerlidir. C# ta ise "public Object GetObject()" biiminde kullanmak yeterlidir.

S - 21 : C# ablon(template) yaplarn destekliyormu?

C - 21 : Hayr, fakat bir tr ablon olan generics yaplarnn C# diline eklenilmesi


planlanmaktadr. Bu trler sentaks olarak ablonlara benzerler fakat derleme zaman
yerine alma zamannda oluturulurlar. Bu trlerle ilgili detayl bilgi iin tklayn.

S - 22 : Item zelliini kullandmda neden CS0117 hatas almaktaym?

C - 22 : C# zellikleri destekler ancak Item zelliinin snflar iin zel anlam vardr.
Item zellii aslnda varsaylan indeskleyici olarak yer alr. Bu imkan C# ta elde etmek
iin Item szcn atmak yeterlidir. Aada rnek program gsterilmitir.

using System;
using System.Collections;

class Test
{
public static void Main()
{
ArrayList al = new ArrayList();
al.Add( new Test() );
al.Add( new Test() );
Console.WriteLine("First Element is {0}", al[0]);
}
}

WriteLine metodunda .Items[0] 'n kullanlmadna dikkat edin.


S - 23 : Herhangi bir fonksiyonumu "out int" parametresi alacak ekilde tasarlmaya
alyorum. Bu metoda gndereceim int deikenini nasl bildirmeliyim?

C - 23 : Deiken bildirimi int trnden yapmalsnz fakat bu deikeni fonksiyona


parametre olarak gnderirken aadaki gibi "out" anahtar szcn de kullanmalsnz.

int i;
foo(out i);
foo metodu aadaki gibi bildirilmitir.
[return-type] foo(out int o) { }

S - 24 : C++'taki referanslara benzer bir yap C#' ta varmdr? (r : void foo(int &x)
gibi )

C - 24 : C#'ta bunun karl ref parametreleridir.

class Test
{
public void foo(ref
int i)
{
i = 1;
}

public void bar()


{
int a = 0;
foo(ref a);
if (a == 1)

Console.WriteLine("It
worked");
}

public static void


Main() {}
}

Not: Metot armnda da ref szcnn kullanldna dikkat edin!

S - 25 : C#'ta inout argmanlar nasl bildirilir?

C - 25 : inout'un C# taki karl ref'tir. rnein :

public void MyMethod (ref String str1, out String str2)


{
...
}
Bu metot aadaki biimde arlmaldr.

String s1;
String s2;
s1 = "Hello";
MyMethod(ref s1, out s2);
Console.WriteLine(s1);
Console.WriteLine(s2);

Not : Hem metot arm hemde metot bildirimi srasnda ref szcnn kullanldna
dikkat edin.

S - 26 : Ykc metotlar(destructors) ve GC C#'ta ne ekilde alr?

C - 26 : C# ta sonlandrc metotlar vardr ve kullanm aadaki gibidir. (Bu sonlandrc


metotlar C++ taki ykc metotlara benzer, tek fark arlaca garanti altna
alnmamtr.)

class C
{
~C()
{
// your code
}

public static void Main() {}


}

Bu metotlar object.Finalize() metodunu ar yklerler ve GC nesneyi yok ederken bu


metodu kullanr.

S - 27 : Derleme srasnda neden "CS5001: does not have an entry point defined -
tanmlanm giri noktas yok- " hatasn alyorum?

C - 27 : Bu hata en ok Main metodunu main eklinde yazdnzda karnza kar. Giri


noktas olan bu Main metodunun bildirimi aadaki gibi olmaldr :

class test
{
static void Main(string[] args) {}
}

S - 28 : Visual J++ ta "synchronized" olarak bildrilen metotlar C# diline nasl tarm?

C - 28 : Orjinal Visual J++ kodu:

public synchronized void Run()


{
// function body
}

C# diline tanm hali

class C
{
public void Run()
{
lock(this)
{
// function body
}
}

public static void Main() {}


}

S - 29 : Kanal(thread) senkronizasyonu(Object.Wait, Notift ve CriticalSection) C#'ta nasl


salanr?

C - 29 : lock ile iaretlemi bloklar bu ie yarar :

lock(obj)
{
// code
}

kod parasnn karl

try
{
CriticalSection.Enter(obj);
// code
}
finally
{
CriticalSection.Exit(obj);
}

S - 30 : Statik yapc metotlarn sentaks nasldr?

C - 30 : Aada MyClass adl snfn statik yaplandrcsnn bildirimi gsterilmitir.

class MyClass
{
static MyClass()
{
// initialize static variables here
}
public static void Main() {}
}

S - 31 : Bir zelliin get ve set bloklarn farkl eriim belirleyicileri ile bildirmek
mmknmdr?

C - 31 : Hayr, bir zelliin belirtilen eriim belirleyicisi ayn zamanda hem get hem de set
bloklarnnn eriim belirleyicisidir. Fakat yapmak istediinizi muhtemelen sadece get
blou olan yani readonly olarak bildirip set blounu private yada internal olan bir metot
yapacak ekilde gerekletirebilirsiniz.

S - 32 : Tek bir assembly de oklu dil desteini nasl salayabilirim?

C - 32 : Bu u an iin Visual Studio.NET tarafndan desteklenen bir zellik deildir.

S - 33 : C# dizi trnden olan zellikleri destekliyor mu?

C - 33 : Evet, aada buna bir rnek verilmitir:

using System;

class Class1
{
private string[] MyField;

public string[] MyProperty


{
get { return MyField; }
set { MyField = value; }
}
}

class MainClass
{
public static int Main(string[] args)
{
Class1 c = new Class1();

string[] arr = new string[] {"apple", "banana"};


c.MyProperty = arr;
Console.WriteLine(c.MyProperty[0]); // "apple"

return 0;
}
}
S - 34 : Birden fazla assembly ile oklu dil destei salanabilirmi?

C - 34 : Malesef u an iin IDE de bu desteklenmiyor. Bunu yapabilmek iin komut


satrndan projenizi /target:module argman ile derleyip modllere ayrmanz gerekir. Ve
oluturduunuz bu modlleri birletirmek iin yine komut satrndan al(alink) aracn
altrarak bu modllerin birletirilmesini salayn.

S - 35 : COM nesnelerine erimek iin opsiyonel olan parametreleri nasl simule


edebilirim?

C - 35 : Opsiyonel parametreler iin System.Reflection altnda bulunan Missing snf


kullanlr. Her bir parametre iin Missing.Value deeri kullanlabilir.

S - 36 : C++'taki varsaylan metot argmanlarnn bir karl C#'ta var m?

C - 36 : Varsaylan argman destei yoktur ancak ayn etkiyi metot ykleme ile rahatlkla
yapabilirsiniz.

Bu problem iin metot yklemeyi tercih etmemizin sebebi ileriki zamanlarda kaynak kodu
yeniden derlemeden varsaylan argman deitirme imkan vermesidir. C++ taki
varsaylan argmanlar derenmi kodun iine gmld iin sonradan bu argman
kaynak kodu derlemeden deitirmek mmkn deildir.

S - 36 : ie gemi bloklarda yada dnglerde hangi bloun sonlandrdldn belirtmek


iin kolay bir yol varmdr?

C - 36 : Bu iin en kolay yolu goto atlama deyimini aadaki gibi kullanmaktr.

using System;
class BreakExample
{
public static void Main(String[] args)
{
for(int i=0; i<3; i++)
{
Console.WriteLine("Pass {0}: ", i);
for( int j=0 ; j<100 ; j++ )
{
if ( j == 10) goto done;
Console.WriteLine("{0} ", j);
}
Console.WriteLine("This will not print");
}
done:
Console.WriteLine("Loops complete.");
}
}

S - 37 : C#'ta deterministik sonlandrmay nasl salayabilirim.


C - 37 : GC mekanizmas gerek anlamda deterministik yapda deildir. Yani ne zaman
gereksiz nesnelerin toplanaca kesin olarak belilenmemitir. Bu yzden kritik kaynaklara
sahip olan nesneleri tasarlamak iin IDisposable arayzn uygulam snflar
tasarlamakta fayda vardr. Aadaki tasarm deseni snf iin ayrlan kaynan blok
sonunda braklacan bildirmektedir.

using(FileStream myFile = File.Open(@"c:\temp\test.txt", FileMode.Open))


{
int fileOffset = 0;

while(fileOffset < myFile.Length)


{
Console.Write((char)myFile.ReadByte());
fileOffset++;
}
}

Ak, using blounun sonuna geldiinde myFile nesnesi zerinden Dispose() metodu
arlacaktr. Nesneleri bu ekilde using ile kullanabilmek iin ilgili snfn IDisposable
arayzn uygulamas gerektiini unutmayn.

S - 38 : C#'ta metotlar iin deiken sayda argman (vararg) destei varmdr?

C - 38 : params anahtar szc bir metodun deiken sayda parametre alabileceini


belirtir. Metot bildiriminde params anahtar szcnden sonra herhangi bir metot
parametresi bildirilemez. Ve bir metot iin sadece bir tane params anahtar szcnn
kullanmna izin verimitir. Aada params'n kullanma bir rnek verilmitir.

using System;

public class MyClass


{
public static void UseParams(params int[] list)
{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine(list[i]);
Console.WriteLine();
}

public static void UseParams2(params object[] list)


{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine((object)list[i]);
Console.WriteLine();
}

public static void Main()


{
UseParams(1, 2, 3);
UseParams2(1, 'a', "test");

int[] myarray = new int[3] {10,11,12};


UseParams(myarray);
}
}

kt

1
2
3

1
a
test

10
11
12

S - 39 : C#'ta string trnden bir deikeni int trne nasl dntrebilirim?

C - 39 : Aada bu duruma bir rnek verilmitir.

using System;

class StringToInt
{
public static void Main()
{
String s = "105";
int x =
Convert.ToInt32(s);
Console.WriteLine(x);
}
}

S - 40 : C# ile yazlm uygulamalardan kmak iin exit() gibi bir fonksiyon varmdr?

C - 40 : Evet, uygulamadan kmak iin System.Environment.Exit(int exitCode)


metodunu yada uygulamanz bir windows uygulamas ise Aplication.Exit() metotlarn
kullanabilirsiniz.

S - 41 : Btn assembly iin zel bir nitelik nasl belirtilir?

C - 41 : Global nitelikler en tepedeki using deyiminden sonra ve herhangi bir snf yada
isim alan bildiriminden nce yaplmaldr. rnek :

using System;
[assembly : MyAttributeClass]

class X {}

Not : IDE tarafndan yaratlan projelerde bu nitelik bildirimleri AssemblyInfo.cs


dosyasnda yaplmtr.

S - 42 : C# ile yazlm kodu klasik COM istemcilerinin kullanmna sunmak iin nasl
kayt(register) etmeliyim?

C - 42 : regasm aracn kullanarak eer gerekliyse type library leri oluturun. Snf
windows registery ye kayt edildikten sonra bu snfa COM istemcileri tarafndan sanki bir
COM bileeniymi gibi eriilebilir.

S - 43 : Birden fazla derlenecek kaynak kod ayn anda derlendiinde, altrlabilir


dosyann ismi nasl belirleniyor?

C - 43 : altrlabilir dosyann ad Main metodunun bulunduu kaynak dosyann ad ile


ayn olur. Komut satrndan /out argman ile altrlabilir dosyann adn kendiniz de
belirleyebilirsiniz. rnein:

C:\ csc /out:Uygulama.exe dosya1.cs dosya2.cs

komutu altrlabilir dosyann adn Uygulama.exe yapacaktr.

S - 44 : C#'ta String trnden nesneler nasl karlatrlr?

C - 44 : Gemite iki stringi == ve != operatrleri ile karlatrmak iin ToString()


metodu kullanlmalyd. u anda ise yine bu yntem geerli olmasna ramen string ler
== ve != operatr ile karlatrldklarnda deikenlerin referanslar yerine onlarn
deerleri karlatrlr.

Eer gerekten string deikenlerinin referanslarn karlatrmak istersek aadaki kodu


kullanabiliriz.

if ((object) str1 == (object) str2) { ... }

Aada string deikenlerinin nasl altna bir rnek verilmitir.

using System;
public class StringTest
{
public static void Main(string[] args)
{
Object nullObj = null;
Object realObj = new StringTest();
int i = 10;
Console.WriteLine("Null Object is [" + nullObj + "]\n" +
"Real Object is [" + realObj + "]\n" +
"i is [" + i + "]\n");

// Show string equality operators


string str1 = "foo";
string str2 = "bar";
string str3 = "bar";

Console.WriteLine("{0} == {1} ? {2}", str1, str2, str1 == str2 );


Console.WriteLine("{0} == {1} ? {2}", str2, str3, str2 == str3 );
}
}

kt

Null Object is []
Real Object is [StringTest]
i is [10]

foo == bar ? False


bar == bar ? True

S - 45 : C++'taki typedef komutunun yapt gibi farkl trler iin takma isimleri
kullanlabilirmi?

C - 45 : Tam olarak deil ama bir dosyada using deyimini aadaki gibi kullanarak
herhangi bir tre takma isim verebilirsiniz.

using System;
using Integer =
System.Int32; // takma
isimi

using deyiminin kullanm hakknda ayrntl bilgi iin C# standartlarn incelyin.

S - 46 : C#'ta snf ile yap arasndaki farklar nelerdir?

C - 46 : Snflar ve yaplar arasndaki farklarn listesi olduka fazladr. Yaplar snflar gibi
arayzleri uygulayabilir ve ayn ye elemanlara sahip olabilirler. Yaplar, snflardan bir
ok nemli noktada ayrlr; yaplar deer tipleri snflar ise referans tipleridir ve tretme
yaplar iin desteklenmez. Yaplar stack bellek blgesinde saklanr. Dikkatli programclar
bazen yaplar kullanarak uygulamann performansn artrabilirler. Mesela Point yaps iin
snf yerine yap kullanmak alma zamannda tahsis edilen bellek asndan olduka
faydaldr.

S - 47 : Bir karakterin ASCII kodunu nasl elde edebilirim?


C - 47 : char trden deikeni int trne dntrrseniz karakterin ASCII kodunu elde
edersiniz.

char c = 'f';
System.Console.WriteLine((int)c);

yada bir string deki herhangi bir karakter iin

System.Console.WriteLine((int)s[3]);

kodunu kullanabilirsiniz.

.NET ktphanesindeki Convert ve Encoding snflarnn yardmylada bu ilemi


gerekletirmek mmkndr.

S - 48 : Versiyonlama bak asyla arayz tretmenin snf tretmeye kar getirileri


nelerdir?

C - 48 : Versiyonlama bak asyla arayz tretmenin snf tretmesine gre daha az


esenek olduunu sylemek mmkndr.

Snflarda farkl versiyonlara yeni ye elemanlar rnein yeni metot eklemeniz


mmkndr. Bu metot abstract olmad srece yeni tretilen snflar bu metodun
fonksiyonalitesine sahip olacaktr. Arayzler uygulanm kodlarn tretilmesini
desteklemedii iin bu durum arayzler iin geerli deildir. Bir arayze yeni bir metot
eklemek snflara yeni bir abstract metot gibidir. Bu arayz uygulayan bir snf bu
metodu aynen uygulayp kendine gre anlamlandrmaldr.

S - 49 : C# koduna inline assembly yada IL kodu yazmak mmknmdr?

C - 49 : Hayr.

S - 50 : Bir metodu yada herhangi bir ye elemannn kullanmn sadece belirli bir isim
alan iin snrlayabilirmiyiz?

C - 50 : sim alanlar iin bir kslama yaplamaz nk isim alanlar koruma amal olarak
kullanlmamaktadr ancak internal eriim belirleyicisi ile bir trn sadece ilgili aseembly
dosyas iinde kullanlabilecek durumuna getirebiliriz.

S - 51 : try blou ierisinde return ile metodu sonlandrsam finally bloundaki kodlar
altrlr m?

C - 51 : Evet, finally bloundaki kodlar siz return ile metodu sonlandrsanzda try
blounun sonuna gelsenizde her zaman alacaktr. rnein :
using System;
class main
{
public static void
Main()
{
try
{
Console.WriteLine
("In Try block");
return;
}
finally
{
Console.WriteLine
("In Finally block");
}
}
}

programnda hem "In try block" hemde "In Finally block" yazs ekrana yazdrlacaktr.
Performans asndan return szcn try blounda yada finally bloundan sonra
kullanmann bir fark yoktur. Derleyici yukardaki durumda return ifadesinin sanki finally
blounun dndaym gibi davranr. Eer yukarda olduu gibi return deyimi herhangi bir
ifade ile kullanlmyorsa her iki durumdada IL olarak retilen kodlar ayndr. Fakat eer
return deyimi bir ifade ile kullanlyorsa try bloundaki return ifadesinde ekstradan store
ve load deyimlerinin IL de olaca aktr.

S - 52 : C# try-catch-finally vloklarn destekliyormu?

C - 52 : Evet destekliyor, aada bu bloklarn kullanmna bir rnek verilmitir.

using System;
public class TryTest
{
static void Main()
{
try
{
Console.WriteLine("In Try block");
throw new ArgumentException();
}
catch(ArgumentException n1)
{
Console.WriteLine("Catch Block");
}
finally
{
Console.WriteLine("Finally Block");
}
}
}
kt
In Try Block
Catch Block
Finally Block

S - 53 : Statik indeksleyici tanmlamak mmknmdr?

C - 53 : Hayr. Statik indeksleyici tanmalamaya izin verilmemitir.

S - 54 : Derleyiciyi /optimize+ argman ile altrdmzda ne gibi optimizasyonlar


yapar.

C - 54 : C# derleyicisini yazan taknn bu soruya verdii cevap:

Kullanlmayan lokal deikenleri atyoruz. (rnek, hi okunmayan lokal deikenler -


kendisine deer verilmi olsa bile-).
Hi bir ekilde eriilemyecek(unreachable) kodlar atyoruz.
try blou bo olan try/catch bloklarn kaldryoruz.
try blou bo olan try/finally bloklarn kaldryoruz.(normal koda evrlir)
finally blou bo olan try/finally bloklarn kaldryoruz.(normal koda evrlir)
Dallanmalarda dier dallanmalar optimize ediyoruz. rnein

gotoif A, lab1
goto lab2:
lab1:

kodu

gotoif !A, lab2


lab1:

koduna dntrlr.

We optimize branches to ret, branches to next instruction, branches to branches.


Dallanmalar "ret"'e, "next instruction" lara veya dier "branch" lara dntryoruz.

S - 55 : C# ile registry'ye nasl eriebilirim?

C - 55 : Microsoft.Win32 isim alanndaki Registry ve Registry snflarn kullanarak bu


alana erimek mmkndr. Aadaki program bir registry anahtarn okuyup deerini
yazdrmaktadr.

using System;
using Microsoft.Win32;
class regTest
{
public static void Main(String[] args)
{
RegistryKey regKey;
Object value;
regKey = Registry.LocalMachine;
regKey =
regKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
value = regKey.GetValue("VendorIdentifier");
Console.WriteLine("The central processor of this machine is: {0}.", value);
}
}

S - 56 : C# global sabitleri tanmlamak iin #define komutunu destekler mi?

C - 56 : Hayr. Eer C dilindeki aadaki koda benzer bir kullanm elde etmek istiyorsanz

#define A 1

bu kodu kullanabilirsiniz.

class
MyConstants
{
public
const int A =
1;
}

Bylece A makrosuna her erimek istediinizde MyConstants.A eklinde bir kullanma


sahip olursunuz.

MyConstants.A eklindeki kullanm ile 1 saysnn kullanm arasnda bir fark yoktur. Yani
ayn kod retilecektir.

S - 57 : Yeni bir proses altrp bu proesisin sonlanmasn nasl bekleyebilirim?

C - 57 : Aadaki kod argman olarak verilen altrlabilir program altr ve alan


bu programn kapatlmas iin bekler.

using System;
using System.Diagnostics;

public class ProcessTest {


public static void Main(string[] args) {
Process p = Process.Start(args[0]);
p.WaitForExit();
Console.WriteLine(args[0] + " exited.");
}
}

S - 58: Bir metot obsolete olarak asl iaretlenir?

C - 58 : using System; yazdnz varsayarak

[Obsolete]
public int Foo() {...}

yada

[Obsolete("Bu mesaj metodun neden Obsolete olduunu aklar.")]


public int Foo() {...}

Not: Obsolete kelimesindeki O harfi byktr.

S - 59: using deyimini kaynak koduma eklememe ramen derleyici tanmlanmam


trlerin bulunduunu sylyor. Nerede yanl yapyorum acaba?

C - 59 : Byk bir ihtimalle isim alannn bulunfuu assembly dosyasn referans vermeyi
unutmusunuzdur. using deyimi sadece bir sentaksdr. Assembly nin fiziksel olarak
konumunu da ayrca belirtmeniz gerekir. IDE yi kullanarak project mensnden add
reference seenei seip istediiniz assembly ye referans verebilirsiniz. Komut satr
derleyicisi kullanyorsanz /r argmann kullanmalsnz.

S - 60 : Basit bir ok kanall uygulama iin rnek kod var m?

C - 60 : Evet. rnek :

using System;
using System.Threading;

class ThreadTest
{
public void runme()
{
Console.WriteLine("Runme Called");
}

public static void Main(String[] args)


{
ThreadTest b = new ThreadTest();
Thread t = new Thread(new ThreadStart(b.runme));
t.Start();
}
}
S - 61: Override edilmi bir metodun temel snftaki versiyonunu nasl arabilirim?

C - 61 : Aadaki gibi base anahtar szcnn kullanarak arabilirsiniz.

public class MyBase


{
public virtual void meth()
{
System.Console.WriteLine("Test");
}
}

public class MyDerived : MyBase


{
public override void meth()
{
System.Console.WriteLine("Test2");
base.meth();
}

public static void Main()


{
MyDerived md = new MyDerived();
md.meth();
}
}

S - 62: C# gelitiricilerini dzenli ifadeler(regex) destei sunulmumudur?

C - 62 : Evet, .NET snf ktphanesi programclara dzenli ifadelerle almak iin


System.Text.RegularExpressions isim alannda bir takm snflar salamaktadr.

S - 63 : C# ile yazm olduum uygulamay altrdmda neden gvenlik hatas


alyorum?

C - 63 : Baz gvenlik hatalar a zerinde paylama alm kaynaklar zerinde


alrken alnr. Roaming profilleri, mapped diskler gibi kaynaklar zerinde almayan
baz snflar vardr. Bunun olup olmadn kontrol etmek iin uygulamanz lokal diskinize
alp yeniden altrmay deneyin.

Bu tr durumlarda genellikle System.Security.SecurityException istisnai durumu


meydana gelir.

Bu tr sorunlarn stesinden gelmek iin caspol.exe arac yardmyla intranet iin gvenlik
policy nizi codegroup 1.2 ye ayarlayabilirsiniz.
S - 64: try-catch bloklarnda faaliyet alan (scope) problemlerinin stesinden nasl
gelirim?

C - 64 : try blou iinde yarattnz nesneye catch blou iinden eriemezsiniz nk try
blounun sonunda ilgili nesnenin faaliyet alan bitecektir. Bunun nne gemek iin
aadaki kod blou kullanlabilir.

Connection conn = null;


try
{
conn = new Connection();
conn.Open();
}
finally
{
if (conn != null) conn.Close();
}

try bloundan nde deikeni null deere atamakla derleyicinin CS0165 (Use of possibly
unassigned local variable 'conn' ) hatasn vermesini engellemi oluruz.

S - 65: .NET gelitirme ortamnda regsvr32 ve regsvr32 /u komutlarnn karl nedir?

C - 65 : RegAsm aracn kullanabilirsiniz. .NET SDK iinde bu aracn kullanm hakknda


detayl bilgiyi bulmanz mmkndr.

S - 65: C#, parametreleri zellikleri destekliyor mu?

C - 65 : Hayr, fakat dilin temel yapsnda indeksleyici diye ayr bir kavram vardr.

Bir indeksleyici bir trn dizi gibi indek operatr ile kullanlabilmesini salar.Ksaca
zellikler field benzeri eriimi indeskleyiciler ise dizi benzeri eriimi salarlar.

rnek olmas asndan daha nce yazdmz Stack snfn dnn. Bu snf tasarlayan
snfn ye elemanlarna bir dizi gibi eriilmesini isteyebilir ve bylece gereksiz Pop ve
Push armlar yaplmam olur. Yani stack bir bal liste gibi tasarlanm olmasna
ramen bir dizi gibi kullanlabilmektedir.

ndeksleyici bildirimi zellik bildirimine benzemektedir. ki bildirim arasndaki en byk


fark indeksleyicilerin isimlerinin olmamasdr.(indeskleyici bildiriminde isi yerine this
anahtar szc kullanlr.) Dier bir fark ise indekleyicilerin indeks parametresi
alabilmesidir. Bu indeks parametresi keli parantezler iinde yazlr.
C# ile XMLQuery rnei

Bu yazmda sizlere, XML dokmanlarnda nasl sorgulama yapabileceimizi basit bir rnek ile
anlatmaya alacam.

Dilerseniz hemen uygulamaya geelim. Yeni bir Asp.Net Web Application an ve adn XmlQuery
olarak ayarlayn. Ardndan projeye yeni bir xml dokman ekleyin ve adn Kaytlar.Xml olarak
ayarlayn. Xml dokmann yapsn aadaki gibi dzenleyin.

<?xml version="1.0" encoding="utf-8" ?>


<Kayitlar>
<Kayit id="1" tip="A">
<Adi>Tolga</Adi>
< Soyadi>Gler</Soyadi>
<Numaras>1544747</Numaras>
</Kayit>
<Kayit id="2" tip="B">
<Adi>Utku</Adi>
<Soyadi>Selen</Soyadi>
<Numaras>4577877</Numaras>
</Kayit>
<Kayit id="3" tip="B">
<Adi>Murat</Adi>
<Soyadi>Kula</Soyadi>
<Numaras>8787878</Numaras>
</Kayit>
<Kayit id="4" tip="C">
<Adi>Argun</Adi>
<Soyadi>elikten</Soyadi>
<Numaras>7454621</Numaras>
</Kayit>
</Kayitlar>

WebForm1.aspx.cs dosyasna aadaki kodlar ekleyin.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
namespace XmlQuery

public class WebForm1 : System.Web.UI.Page

private void Page_Load(object sender, System.EventArgs e)

XmlNodeList Isimler,Isimler2,Isimler3,Isimler4,Isimler5;
//XmlNodeList trinden deikenlerimizi tanmlyoruz.

XmlTextReader rdr = new XmlTextReader("http://localhost/XmlQuery/kayitlar.xml");


// XmlTextReader snf yardm ile xml dkmanna eriiyoruz.
XmlDocument MyXmlDoc = new XmlDocument();
MyXmlDoc.Load(rdr);
//XmlDocument snfn xml dkman zerinde ilem yapabilmek iin kullanyoruz

// Xml domanndan id si 1 olan isimleri semek iin


Isimler = MyXmlDoc.SelectNodes("/Kayitlar/Kayit[@id='1']/Adi");
/* XmlDocumen.SelectNodes metoduna parametre olarak verdiimiz XPATH
e dikkat edin.
*/
for(int i = 0;i < Isimler.Count;i++)
Response.Write(Isimler.Item(i).InnerXml.ToString()+"<br>");
// Sonu "Tolga" olacaktr.

// id si 1 veya 2 olan kaytlar iin


Isimler2 = MyXmlDoc.SelectNodes("/Kayitlar/Kayit[@id='1' or @id='2']/Adi");
for(int i = 0;i < Isimler2.Count;i++)
Response.Write(Isimler2.Item(i).InnerXml.ToString()+"<br>");
// Sonu "Tolga" ve "Utku" olacaktr.
// id si 1 ve tipi A olan kaytlar iin
Isimler3 = MyXmlDoc.SelectNodes("/Kayitlar/Kayit[@id='1' and @tip='A']/Adi");
for(int i = 0;i < Isimler3.Count;i++)
Response.Write(Isimler3.Item(i).InnerXml.ToString()+"<br>");
// Sonu "Tolga" olacaktr.

// tipi B olan kaytlarn adnn ilk iki harfi "Ut" olanlar


Isimler4 = MyXmlDoc.SelectNodes("/Kayitlar/Kayit[@tip='B']/Adi[substring(.,1,2) ='Ut']");
for(int i = 0;i < Isimler4.Count;i++)
Response.Write(Isimler4.Item(i).InnerXml.ToString()+"<br>");
// Sonu "Utku" olacaktr.

// tipi B olan kaytlarn adnda "ura" geenler


Isimler5 = MyXmlDoc.SelectNodes("/Kayitlar/Kayit[@tip='B']/Adi[contains(.,'ura')]");
for(int i = 0;i < Isimler5.Count;i++)
Response.Write(Isimler5.Item(i).InnerXml.ToString()+"<br>");
// Sonu "Murat" olacaktr.

Siz rnekleri istediiniz gibi gelitirip oaltabilirsiniz.

2003 2005 Microsoft Yazlm Gelitirme Aralar Yol Haritas 1

ubat 2002de Visual StudioNet ve dotNET Platformu dnyadaki tm yazlm


gelitiricilerin hizmetine sunuldu; bu nemli olay sayesinde programclar ok deiik
alanlarda program gelitirme ilerini dotNET platfromu ve Visual StudioNET ile yapabilir
hale geldi. Visual Studio.NET 2003 ile programclar mterilerine baars kantlanm,
yksek performansl ve gvenilir yazlmlar gelitirmeye devam ediyorlar.

dnyasndaki deiikliklerle birlikte ihtiya duyulan yazlmlarn da gelimesi ve


deimesi gerekiyor. Byle bir ortamda Micrsoft kendisinin yazlm gelitirme aralarn
kullanan gelitiricilere devrim niteliinde ve i dnyasnn deien ihtiyalarna en ksa ve
en iyi zmlerini retecek yazlm gelitirme aralarn sunmaya devam
ediyor. Kurumlarn gelecekteki yazlm ihtiyalarnn planlamasn yaparken onlara
yardmc olmak amacyla Microsoft bu yol haritasn sunmaktadr. Bu belge zellikle u
rnler zerinde younlamtr:

Microsoft Ofis 2003 iin Visual Studio aralar: u anda beta aamasnda
olan bu teknoloji sayesinde, Microsoft Office Word 2003 ve Microsoft Excel 2003
.Net ortamnda programlayabileceiz.
Whidbey kod adl Visual Studio 2004: Visual Studio.NET ve .NET
platformunun bu versiyonunda birok yenilikler ve deiikliklerle geliyor. Balca
yenilikler snf ktphanesinde, ortak dil alma (CLR) ksmnda, programlama
dillerinde ve Visual studio.NETin arayznde (IDE) olacaktr. Ayrca SQL Servern
yeni versiyonu olan SQL Server Yukon ile byk bir entegrasyon salanacaktr.
Bu sayade C# ve Visual Basic.Net ile sakl yordamlar (stored procedures) yazp
Yukon zerinde altrabileceiz.
Orcas kod adl Visual Studio 2005: Bu versiyonda ise Longhorn isimli
Windows iletim sistemiyle daha iyi entegrasyon ve programlama alt yaps
salanacak.

Microsoft yazlm gelitirme aralar her zaman Windows platformunun en son


zelliklerine erimeyi ve onlar programlamay programclara sunmutur. Yukarda da
grld gibi Microsoft bu gelenei srdrmeye devam edecektir. Bu balamda
Microsoft Ofis Sistem 2003, SQL Server Yukonu ve Windows iletim sistemlerini
programlamak iin bir ok kolaylklara sahip olacaz biz yazlm gelitiriciler olarak.

Microsoft Ofis 2003 iin Visual Studio Aralar

Yazlm gelitiriciler hem Visual Studio hem de Microsoftun baarsndaki ncl g


olmulardr.
- Eric Rudder, Sunucu ve Aralardan sorumlu Genel bakan yardmcs.

Visual Studio 2003n hemen ardndan Microsoft, Ofis 2003 iin Visual Studio aralarn
piyasaya srd. Bu yeni teknoloji sayesinde .NET platformundan ynetilen kod sayesinde
Microsoft Word 2003 ve Microsoft Excel 2003 iin kod yazlabilecek. Tpk VBA ve COM
tabanl otomasyon projeleri gibi. Microsoft Ofis 2003 iin Visual Studio Aralar biz
yazlmclara u nemli avantajlar da getiriyor:

Tandk programlama deneyimi: Microsoft Ofis 2003 iin Visual Studio Aralar
ile programclar .Net snf ktphanelerini kullanabilirler. Bylelikle bir ok
zahmetli i iin ok daha az satr kod yazmak zorunda kalacaz. Mesala stringleri
ilemede, veri yaplarnda, veri taban ilemlerinde ve dosya ynetiminde byk
kolaylklar salar. Dahas Visual Studio.NET ile daha gl ofis uygulamalar
gelitirme ansna da sahibiz. Microsoft Ofis 2003 iin Visual Studio Aralar ile
Word ve Excel dosyalarnn nesne modellerine tam olarak eriim ve onlar
programlama hakkmz douyor.
Kolaylatrlm program kurulumu ve bakm: Microsoft Ofis 2003 iin Visual
Studio Aralar ile yazdmz kodlar DLL olarak derlenebilir. Bu DLL(ler) genelde
a zerinde paylamda olan bir yerde dururlar ve Excel veya Word aldnda
ilgili dll makinaya indirilir ve altrlr. Eer kodda bir deiiklik olursa yeni
derlenmi kod otomatik olarak istemci makineye indirilir.
Gelimi gvenlik: Microsoft Ofis 2003 iin Visual Studio Aralar ile daha gvenli
bir alma ortamna sahip olacaz. Hem gvenlik kod (trusted code) altracaz
hem de gvenliin sistem yneticisi tarafndan denetim altna alnmas salanacak.

Whidbey kod isimli Visual Studio 2004

Gelimi aralar, tm kritik zamanlarda, uygulamar iin ok nemli dnemeler


olmutur Ayn ekilde uygulamardaki bu kritik dnemeler bilgi ilem alannda bir sonraki
aamay getirmitir.
-Bill Gates

2004 ylnda piyasaya sunulacak olan Visual Studio.NET ve .NET altyaps yazlm
gelitirmenin tm alanlarnda ok nemli deiiklikleri beraberinde getirecektir.
Gelitiricilerden alnan geribildirimler (feedback) ve bunlarn dikkatlice
deerlendirilmesiyle programclarn daha verimli olmalarn ve IDE iinden dier yazlm
gelitiricilere ulamay ve destek hizmetlerine ulamay mmkn klacaktr. Yenilikler
programlama dillerindeki gelimeler, .NET Platformundaki deiiklikler ve kurumsal
yazlm gelitirme projelerine destek ve yardmlarn artrlmasdr.

Dier gze arpan gelime ise Microsoft tarafndan retilen yazlm gelitirme aralarnn
planl olarak birbiri ile ve sistemle daha uyumlu hale gelmesidir. Whidbeyin SQL Server
Yukon ile ok iyi entagrasyonu bu uyumluluk planlarnn banda geliyor. Tpk Windows
Server 2003n daha sisteminize kurulurken .NET Plaformunun varsaylan olarak
kurulmas gibi. Bu sayede SQL Server Yukon CLR ortamna tam olarak adapte olmu hale
gelecektir. Yukarda da belirtildii gibi Whidbey ortamnda SQL Server Yukon zerinde
alan sakl yordamlar (stored procedures) yazabileceiz. Tabi ki Whidbey ile veri taban
ilemlerimizi daha az kod yazarak gerekletirme ansmz vardr.

Yukardaki geni deiikliklerin yannnda yenilikler balca u konularda olmutur:

Programlama Dilleri: Bu versiyonda Microsoft Visual Studio ierisinde tam


destek verdii 4 dilde (Visual Basic, Visual C#, Visual C++ ve Visual J#) nemli
deiiklikler yapacak. Bu deiikler dillerin glerini artracaklar gibi dillerin
zellikleri ve ortak alabilmesine en ufak bir yan etkisi olmayacaktr.
.NET Platformu: Whidbey ile .NET Platformundaki snf ktphanelerinde nemli
deiiklikler olacak. Deiiklikler daha gl ve ho Windows uygulamalar
gelitirmeyi salayaca gibi ASP.NET programlama ve ADO.NET veri ilemleri
daha verimli olacaktr. Ayrca en son web servisleri standartlarn destekleyecek ve
daha geni apl cihaz tabanl (Mobil veya dier programlanabilir cihazlar iin)
programlama imkanlar gelecek.
Kurumsal Yazlm Gelitirme: Bu yeni versiyon ile sistem tasarmclarna ve
kurumsal yazlm gelitiren yazlm mhendislerine kapsaml ve etkili zmler iin
yeni aralar sunulacak. Bu aralar gelitirilmi proje analizi ve tasarm, yazlm
ayarlar ynetme ve yazlmn datlmas (deployment) gibi kritik noktar iin
dnlmtr.

Programlama Dilleri
.NET Platforumunda yazlm gelitirmek iin 20den fazla deiik dil kullabiliriz. Bunun
yannda Microsoft resmi olarak .Net platformunda 4 dili Whidbeyde destekliyor olacak.
Microsoft Whidbeyde bu 4 dil iin gerekli tm aralar ve destei en gvenilir yazlm
gelitirmek iin bizlere sunuyor.

Visual Basic
Whidbey ile gelecek olan Visual Basic versiyonunda programclarn verimliliini inanlmaz
seviyede artracak yenilikleri greceiz. Tabi bu yenilikler Visual Basic programlama dili
ile .NET ortamnda yazlm gelitirmek iin bize sunulan tm zellikleri de sonuna kadar
kullanacaz. Visual Basic Whidbeydeki kritik deiiklikler temel olarak unlardr:

Sk sk yazmak zorunda kaldmz baz kodlar yazmak ok daha hzl


1
olacaktr.
Program tasarm halindeyken dahi hatalar minimize etmek iin alnan
2
nlemler ve yollar.
3 Veri ve Veritabanlarna daha kolay eriim.
4 Gelitirilmi RAD hata ayklama
5 ok ileri seviyede Visual Basic programlar yazabilme.

1. ou programda sk sk yazmak zorunda kaldmz kodlarn yazm Visual Basic


Whidbeyde en az iki kat hzl bir biimde yazlabilinecek. Programc verimliliin artmas
iin alma zaman nesnelerine ve metodlarna direk olarak eriim ve bunlar getirdii
esneklik dier bir gzel haber. Kod editrndeki gelimeler sayesinde sk sk yazlan
kodlar hzlca yazmak iin sadece belirli boluklar doldurmak yetecektir. Bu sayede dilin
sz dizimi yerine gelitirilen projenin mant zerinde younlama frsat bulacaz.

2. Yeni kod editr sayesinde her seviyedeki programclarn hatalarn en aza, daha
tasarm aamasnda, indirmek mmkn. Microsoft Wordta bulunan gramer ve yazm
hatalarn kontrol ve dzeltmeye yarayan aracn bir benzeri Visual Basic Whidbey ile
gelecek. Visual Basic derleyicisi de daha iyi bir kod denetimi yaptktan sonra program
derleyecek bylece alma annda ortaya kmas muhtemel hatalarn nne geilecek.

3. Visual Basic Whidbey ile veriye eriim ve veri zerinde deiiklikler yapmak ok daha
kolay hale geliyor. Kolaylatrlan ilerin banda, yerel ve uzaktaki veriye, ile ilgili veri
tayan nesnelere ve uzaktaki XML Web servislerine eriim geliyor. Whidbey ayrca
sadece veriler zerinde alan (databound) programlar gelitirmeyi de inanlmaz kolay
hale getiriyor. Bu tr programlar tek satr dahi kod yazmadan dahi gelitirme imkan
bulacaz. ok sk kullanlan veriye eriim senaryolar iin tasarlanan bu yntemlerle
programlar veri kaynandaki tablolar ve stunlar srkleyip brakarak program
gelitirebileceiz.

4. Whidbey ile gelen hata ayklama yntemleri iin aralar hem daha gl hem de Visual
Basic programclarnn aina olduklar bir biimde tasarland. Edit ve Continue
komutlarnn batan tasarm sayesinde programda hata ayklarken tekrar tekrar
program derlemeyi ve hata ayklamaya devam etmeyi unutun. Ayrca break modundaki
deiiklikler ile daha nce grlmemi en gl ve esneklikte hata ayklama aralarna
sahip olacaz.

5. Son olarak, ileri seviyedeki Visual Basic programlar iin dilde bir ok iyiletirmeler
yapld. Bunlar ilelere ar yklenme (operator overloading), iaretsiz veri tipleri
(unsigned data types), kod iinde XML tabanl kod dokmantasyonu yazm (inline XML-
based code doumentation) ve ksmi veri tipleri (partial types). Dildeki bu gelimeler
sayesinde Visual Basic programclar tip gvenli (type -safe), yksek performansl,
derleme zamannda onaylanm (compile time-verified) olan generics yazabilecekler. Bu
sayede kodun tekrar tekrar fakl veri tipleriyle birlikte kullanlmasn beraberinde
getirecektir.

nceki versiyonlar gibi Visual Basic Whidbeyde hzl bir biimde program gelitirmeyi
mmkn klmak zerine younlamtr. Planl olan yenilikler ile Visual Basic Programclar
daha gvenli, daha salam ve daha ho programlar kolay bir biimde gelitirip onlar
ayn kolaylkla web, alma grubu ve kurumsal ortamlarda datmay/kurmay
garantiliyor.

Visual C++

Visual C++ Whidbey nceki versiyonunlarndan daha gl olarak sistem programlama


ve yazlm gelitirme grevlerini hem Windows hem de .NETi tercih eden programclar
hedef alyor. Planl olarak yaplan yenilikler derleyiciyi, gelitirme ortamn, programlama
dilini ve temel ktphaneleri kapsyor. Ek olarak Visual C++ Whidbey ile mobil cihazlar
iin native C++ uygulamarnda gelitirmek mmkn olacak.

C++ derleyicisindeki gelimelerden biri Profile Gudied Optimization (POGO)dr. POGO


teknolojisi derleyicinin bir uygulamay inceleyip onun nasl kullanld hakknda bilgi
toplamasdr. Bu bilgiler ile Visual C++ kodu daha iyi biimde optimize edecek. Son hali
olmasada 64-Bit POGO teknolojisinin Pre-release versiyonu cretsiz olarak indirilebilir.
Whidbey de ise bu teknoloji daha gelimi olarak 32-bit derleyici iin hazr olarak
gelecektir.

CLRnin n srmlerinde Visual C++ Managed Extentions ile gelecek ve programclar


.NETin tm tm olanaklarna ulaabilecekler. Whidbey srmnde ise Visual C++
gelitiricileri C++a has zelliklere, mesela generics'e sahip olacak. Dier gelimeler ile
C++ CLR ortamnda yazlm gelitirme arac olarak kullanmak daha kolay bir hal
alacaktr.

Visual C++ Whidbey C++ temel ktphanelerinde bir ok gelimeyi beraberinde


getiriyor. Bildiimiz gibi C++ta kullanabileceimiz dnya apnda yaygn ktphaneler
bunuluyor. Bunlar en ok ne kanlarndan biri de Microsoft Foundation Class
(MFC)dir. Visual C++ Whidbey ile gelen MFCde bir ynden yeni gelimeler olacak.
Bunlarn en dikkat ekeni ise Windows Fusion teknolojisine destektir. Windows Fusion
DLLlerin kard sorunlar aza indirmek iin yaratlan ileri seviye bir teknolojidir. Dier
nemli gelime ise kolayca MFC tabanl uygulamalarn .NET platformu tarafndan
desteklenmesidir.

Viusal C#

Microsoft Visual C#a deiik dillerden ok ho zellikleri Whidbeyde eklemeyi planlyor.


Bu deiiklikler ile programclara Kod odakl RAD olanaklar salanacak. Yani, C#
programclar daha verimli bir biimde tekrar kullanlabilir nesne ynelimli bileenler ve i
taslaklar gelitirecekler. Eklenecek yenilikler generics, itaretrler, anonymous metodlar
ve ksmi tiplerdir.

Bir yazlm projesinin karmakl artka programclar daha fazla oranda hazr olan
program bileenlerini direk kullanmaya veya onlarn zerinde az bir deiiklikle kullanma
eilimi gsterirler. Byle yksek seviyede kodun yeniden kullanlmasn baarmak iin
generics ismi verilen yntemi tercih ederler. Whidbeyde CLR iine yerletirilen zellikler
sayesinde yksek perfromansl, tip gvenli ve derleme zamannda onaylanm
generics'leri C++ta bulunan templatelere benzer biimde gelitirebiliriz. Generic ler
programclara kodu bir kere yazp bir ok deiik veri tipleriyle birlikte hi bir performans
kayb olmadan kullanmay vaad eder. CLR de yazlan genericlerin benzerlerine gre daha
sade koda, bu sayede daha kolay okunabilir ve bakm yaplabilir olmalar byk bir
avantajdr.

C# ile kodun tekrar kullanlmas ynnde bir ok kolaylklarn gelmesine ek olarak tekrar
tekrar yapmamz gereken baz karmak kod paralar iin de yeni yeni zmler
retilmitir. Mesela enum sabitleri iin yenileciler(iterators). Yenileyiciler sayesinde enum
sabitleri ile almak daha rahat bir hal almtr. Bilgisayar bilimlerinde aratrmalarda
kullanlan CLU, Sather ve Icon programlama dillerindeki zelliklerden esinlenerek foreach
bloklar iinde hangi veri tiplerinin nasl ne ekilde yenileyicilerin kullanlmasnn
tanmlanmas mmkn hale gelmitir.

Anonim metodlar (anonymous methods) da C# diline Whidbey ile girecek. Bu tr


metodlar ile yazm olduumuz bir kod parasn bir delege iine koyup daha sonra
kullanacaz. Anonim metodlar programlama dillerinin incelendii derslerde geen lamda
function fikri zerine kurulmutur ve Lisp ve Phyton dillerinde uygulanmtr. Bu tr
metodlar kullanlacaklar anda ve yerde tanmlanyorlar. Normalde bir fonksiyon daha
nce tanmlanr ve derleyici onun imzasn (method signature ) bilmek ister. Bylelikle
anonim metodlar, zellikle metodun yapt i veya metodun imzasnn alma annda
deimesinin gerektiinde baz ilemlerin yaplmasn daha uygun ve kolay hale gelir.

Son olarak Whidbey C# ile programclar bir veri tipinin tamamn tek bir yerde deil
deiik kaynak dosyalarnda tanmlayabilecekler. Bu tr tipler paral tip (partial types)
olarak adlandrlacaklar. Ayrca paral tipler geni projelerde daha kolay program
tasarm ve kod yazm imkan salayacaktr.

C# dilindeki ngrlen yenilikler ile hem byk projeler iin gelitirilecek platformlarn
tasarmclar hem de yazlm mimarlar (software artitechts) iin favori dil olmaya devam
edecektir. Ayrca modern sz dizimi ve bileen ynelimli zellikleri (component-
oreineted) ile koda odaklanm RAD arac olarak karmza kacaktr.

Visual J#

J# Whidbey ile planlam bir ok yenilik gelecektir. Bunlarn amac programclarn sahip
olduklar Java deneyimlerini daha iyi bir biimde .NET ortamnda kullanmalar ynndedir.
Yeniliklerin banda Borwser Controls ve J# dilinin gelitirilmesini sayabiliriz.

J#n 2002de .NETe katlmas ile Java programclar nceden yazdklar Java
Appletlerini .NET koduna evirebilmek ve .NET ortamnda da Applet tr yazlmlar
gelitirebilmeyi talep ettiler. Programclarn bu isteklerine cevap olarak Microsoft J#
Browser Controls adlandrlan teknolojiyi gelitirdi. u anda beta aamasnda olan bu
teknoloji sayesinde var olan applet kaynak kodlarn ap tekrar J# ile (ok ok az kod
deiiklii ile) derlemek yeterli olacaktr. Bu teknolojinin tam olarak kullanlmaya
baland gnlerde programclar kendi J# Browser Controllarn tpki Java appletini bir
web sayfasna gmer gibi gmebilecekler. Ek olarak, tabiki, J# Browser Controllar .NET
Frameworkunun tm olanaklarna eriim haklar olacak ve XML web servislerinin
kullanm mmkn olacak.

J#a eklenecek yenilikler ile .NET dilleri aras uyumluluu artacak ve Windows iletim
sisteminin zelliklerine eriim daha rahat olacaktr. lk olarak yeni J#ta Enum sabitleri ve
deer tipleri kavramlar ile J# CLSye daha uyumlu olacak. kincisi ise volatile ve assert
anahtar kelimelerinin eklenmesi ile daha esnek ve daha optimize olarak alan program
kodlarna sahip olacaz. Son olarak genericlerin J# iinden arlabilmesi ile dier .NET
dilleri ile daha da uyumlu olacaktr.

Java programclar iin hem alk bir sz dizimi hem de nesne ynelimli zellikleri ile .NET
ortamnda kolayca yazlm gelitirebilecekleri dil olarak J# ne kacaktr. Whidbey J#ta
gn yzne kacak harika zellikler sadece Java ve J++ programclarn deil bilgisayar
bilimlerinde eitim gren renciler ve onlarn hocalarn ok mutlu edecektir.
C# ile Rastgele Kod retimi

Bu uygulama birok, yerde iimize yarayabilecek bir Rastgele Kod retici dir. Rastgele
retilmi bir koda birok yerde ihtiya duyabiliriz. rnein; web sitenizin ye kaytlarnda
ye adaylarnn gerek email adreslerini girmelerini garantilemek isteyebilirsiniz. Bunu
salamann en basit yolu, kiinin verdii email adresine rastgele rettiinz bir kodu
gndermektir. Bylece ye adayndan, yelik ilemlerinin tamamlanarak hesabn aktive
olabilmesi iin, email adresine gnderdiiniz aktivasyon kodunu yelik aktivasyon
sayfanzda girmesini isteyebilirsiniz. Eer email adresi doru deilse aktivasyon kodunu
edinemeyeceinde yelii de geerli olmaz.

Rastgele kod retebilmek iin kullanacamz en nemli snf System isim alan
(namespace) ierisinde bulunan Random snfdr (class). Bu snf kullanarak kod
ierisinde grnmesini istediimiz karakterler dizisinin boyutu kadar rastgele tamsay
reteceiz.

Kullanacamz dier bir snf ise System.Text isim alan ierisinde bulunan StringBuilder
snfdr. Yapacamz ilem bir metin birletirme dngs iermekte ve metin birletirme
ilemlerinde StringBuilder snf, string tipine oranla daha fazla performans salamaktadr.
Uygulamay bir fonksiyon olarak hazrlayacaz.

Fonksiyon retecei rastgele kod un ka karakter uzunlukta olmas istendiini


codeLength parametresiyle alacak. rettii codeLength kadar karakter uzunluundaki
Rastgele Kodu da string veri tipinde, fonksiyonun arld yere dndrecek.

private string GenerateCode(int codeLength)


{

Fonksiyonda ilk olarak sb deiken adyla, rastgele kodu yaplandracamz


StringBuilder nesnesini ve ikinci olarak da objRandom adyla, rastgele say retecek
olan Random nesnesini yaplandracaz.

System.Text.StringBuilder sb=new System.Text.StringBuilder();

System.Random objRandom=new System.Random();

Sra Rastgele Kodumuz iinde yer almasn istediimiz karakterleri bir metin dizisi olarak
tanlamaya geldi. Ben bu rnekte A-Z, a-z ve 0-9 aras karakterleri kullandm. Siz
isterseniz uygulamay zenginletirmek iin farkl karakterler de kullanabilirsiniz.

string[] strChars = { A", "B", "C", ...

"1", "2", "3", ...

a", "b", "c", ... };

imdi ilemlere balayabiliriz. nce rastgele reteceimiz say araln bulalm.


Yukardaki karakterler strChars adnda bir metin dizisinde tutulmaktalar. Diziler 0
indeksle baladklarndan rastgele retilecek olan minimum rakam 0 olmaldr. retilecek
maksimum rakam ise dizinin en son elemannn indeksi olmaldr. Dizinin en byk
indeksli elemannn indeks bilgisini

int maxRand=strChars.GetUpperBound(0);

koduyla ayn anda hem bu deeri tutacak olan maxRand adnda bir deiken
tanmlayarak dizinin GetUpperBound(0) metoduyla alrz.

Rastgele Kodun retilmesi, istenilen kod uzunluu iin her bir basaman rastgele
oluturulmasyla salanr. Bunun iin, 0 ile Rastgele Kod iin kullanlacak karakter
dizisinin en byk indeksi arasnda rastgele bir say objRandom.Next(maxRand)
metoduyla retilir ve bu deer rndNumber deikenine atanr.

int rndNumber=objRandom.Next(maxRand);

Karakter dizisindeki rastgele bir eleman, edinilen rndNumber saysn indeks olarak
kullanarak strChars(rndNumber) ifadesiyle elde edilir ve bu karakter sb.Append
metoduyla sb nesnesine eklenir.

sb.Append(strChars[rndNumber]);
Eer 10 karakter uzunluunda bir rastgele kod istenirse, nce birinci basamak iin
rastgele bir karakter retilir, daha sonra ikinci basamak iin ve bu bylece 10a kadar
devam eder. Bu retilen karakterler sb deikeni ierisinde ard arda eklenir.

for(int i=0;i<codeLength;i++)
{
int rndNumber=objRandom.Next(maxRand);

sb.Append(strChars[rndNumber]);
}

En son olarak da StringBuilder nesnesinin ierinde yaplandrlm olan ve rastgele


karakterlerden meydana gelen sonu, string veri tipine sb.ToString() metoduyla
dntrlerek fonksiyon sonlandrlr ve deer fonksiyonun arld yere dndrlr.

return sb.ToString();

Kodun tamamlanm ekli aadaki gibidir.

private string GenerateCode(int codeLength)


{
System.Text.StringBuilder sb=new System.Text.StringBuilder();

System.Random objRandom=new System.Random();

string[] strChars = { "A","B","C","D","E","F","G","H","I",

"J","K","L","M","N","O","P","Q","R",

"S","T","U","V","W","X","Y","Z",

"1","2","3","4","5","6","7","8","9","0",

"a","b","c","d","e","f","g","h","i","j","k",

"l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};

int maxRand=strChars.GetUpperBound(0);

for(int i=0;i<codeLength;i++)

{
int rndNumber=objRandom.Next(maxRand);

sb.Append(strChars[rndNumber]);
}

return sb.ToString();
}
Metin(String) lemlerinde Performans Artrmak

Programlama yaparken sk sk metinsel ilemler yapmak durumunda kalrz.

Bir metni baka bir metinle birletiririz...

Byke bir metnin ierisinden bir blmn alrz...

ki metni birbiriyle karlatrrz...

....

Bu liste bylece uzar gider. Metinsel ilemler denilince akla gelen ilk ey metin
birletirme ilemidir. Bir metnin bir dierine eklenmesi. metinle ilgili olduunda bu
ii gerekletirmek iin C# ta ilk akla gelen veri tipi string dir. System.String
snfn (class) temsil eden string bir referans trdr. Ancak biraz farkl bir referans
trdr. Yap olarak immutable, yani deimezdir/sabittir ve bu yzden bir kez
yaplandrldktan sonra ierii deitirilemez. te bu yapdan dolaydr ki bir string
deikene ancak bir kez deer atayabilirsiniz.
Peki ya aadaki kod?

string metin="Merhaba";

metin=metin + " Dnya!"; // metin=Merhaba dnya!

String bir referans tr olduu iin bellekteki bek (heap) blgesinde yaratlr ve
ieriine Merhaba yklenir. bekteki bu nesneye kodun eriebilmesi iin gerekli adres
bilgisi ise bellein yn (stack) blgesinde yaratlan metin deikenine yazlr. Yani
referans trlerde deiken nesneyi deil, nesnenin adresini tutar.

imdi ikinci satra bakalm. Birinci satrda, metin deikeninin temsil ettii string
nesnesine birinci string nesnesi diyelim. kinci satrdaki kod ilendiinde birinci string
nesnesi zerine yeni deer ekelenemeyeceinden, bekte ikinci bir string nesnesi
tretiliyor ve ilem sonucu, yani Merhaba Dnya! bu ikinci string nesnesine
ykleniyor.

Ve kilit nokta!

metin deikeni ikinci satrdaki kodun sonunda artk birinci string nesnesinin deil,
ikinci string nesnesinin adresini tamaya balyor. Yani artk birinci string nesnesi
tamamen eriilemez oluyor ve p Toplayc (Garbage Collector) devreye girip bellei
temizleyene kadar bellekte yer tutmaya devam ediyor.

te string veri tipinin bu yaps nedeniyle metinsel ilemlerde daha iyi performans
salamak amacyla System.Text isim alan iine bulunan StringBuilder snf
kullanlmaktadr.

Algoritmaya bal olarak deimekle birlikte, StringBuilder snfnn ok ok daha hzl


olduu sylenebilir.

'string' veri tipi kullanilarak metin birlestirme.....

Baslangi : 24.11.2003 20:31:06

Bitis : 24.11.2003 20:31:08

Toplam sre : 2193,1536 milisaniye

'StringBuilder' sinifi kullanilarak metin birlestirme.....

Baslangi : 24.11.2003 20:31:08

Bitis : 24.11.2003 20:31:08

Toplam sre : 20,0288 milisaniye

Uygulamaya sonlandirmak iim [Enter] tusuna basin.

Aadaki rnek kod ve yukardaki ekran grnts, metin birletirme ilemlerinde


gerekten ok iyi performans gsteren StringBuilder snfnn, string ile karlatrld
bir Console uygulamasdr.
static void Main(string[] args)
{

// Degisken tanimlari

string str="";

System.Text.StringBuilder sb=new System.Text.StringBuilder();

DateTime start; // islemin baslangi ani

DateTime end; // islemin bitis ani

TimeSpan sure; // islemin toplam sresi

// string veri tipiyle metin birlestirme islemi.....

Console.WriteLine("'string' veri tipi kullanilarak metin birlestirme.....");

start=DateTime.Now; // islemin baslangi zamani

Console.WriteLine("Baslangi :\t" + start.ToString());

// Metin birlestirme islemi.....

for(int i=0;i<10000;i++)

str +=i.ToString();

end=DateTime.Now; // islemin bitis zamani

Console.WriteLine("Bitis :\t\t" + end.ToString());

sure=end.Subtract(start); // geen sre hesaplaniyor..

Console.WriteLine("Toplam sre :\t" + sure.TotalMilliseconds + " milisaniye");

//-------------------------------------------------------

Console.WriteLine();

// StringBuilder sinifiyla metin birlestirme islemi.....

Console.WriteLine("'StringBuilder' sinifi kullanilarak metin birlestirme.....");

start=DateTime.Now; // islemin baslangi zamani

Console.WriteLine("Baslangi :\t" + start.ToString());


// Metin birlestirme islemi.....

for(int i=0;i<10000;i++)

sb.Append(i.ToString());

end=DateTime.Now; // islemin bitis zamani

Console.WriteLine("Bitis :\t\t" + end.ToString());

sure=end.Subtract(start);// geen sre hesaplaniyor..

Console.WriteLine("Toplam sre :\t" + sure.TotalMilliseconds + " milisaniye");

//-------------------------------------------------------

Console.WriteLine();

Console.WriteLine("Uygulamaya sonlandirmak iim [Enter] tusuna basin.");

Console.ReadLine();
}

"Builder" Tasarm Deseninin C# ile Gerekletirilmesi

Bu yazda "Creational" desenler grubunda yer alan "Builder" tasarm deseninden ve bu


deseni C# ile nasl gerekletirebileceimizden bahsedeceim.

Bu yazy okumadan nce "Singleton" ve "Abstract Factory" tasarm desenlerini konu


alan yazlarm okumanz tavsiye ederim.

"Builder" deseni adndan da anlalaca zere bir nesnenin oluturulmas ile ilgilidir. Bu
desende kullanlan yaplar hemen hemen "Abstract Factory" deseninde kullanlan yaplar
ile ayndr. Bu iki desen arasnda ok kk farkllklar vardr. Bu farklar ilerleyen
ksmlarda aklayacam.

"Builder" deseni birden fazla paradan oluan kompleks yapdaki bir nesnenin
oluturulmasn ve bu kompleks nesnenin oluturulma safhalarn istemci modlnden
tamamen gizlemek iin kullanlr. Kompleks nesnenin yaratlmas istemci modlnden
tamamen yaltld iin nesnenin yaratlmas ile ilgili ilemler farkl versiyonlarda
tamamen deitirilebilir, bu istemci programn almasn hi bir ekilde
etkilemeyecektir. Burda dikkat edilmesi gereken nokta ise udur : bu desen kompleks
nesneyi oluturan yaplarn gerek nesneden tamamen bamsz bir yapda olduu
durumlarda kullanld zaman esneklik getirecektir. Dolaysyla her bir farkl parann
kompleks nesnede kullanlmas, kompleks nesnenin ilevini deitirmeyecei gibi
sadece grnmn yada tipini deitirecektir.

Builder deseninin Abstract Factory deseninden farkna gelince; "Abstract Factory"


deseninde soyut fabrika olarak bilinen yapnn metotlar fabrikaya ait nesnelerin
yaratlmasndan bizzat sorumludur. Builder deseninde ise ayn mekanizma biraz daha
farkl ilemektedir. Builder deseninde istemci modl, nesnelerin ne ekilde
oluturulacana soyut fabrika yapsna benzer bir yap olan Builder yapsnn metotlar
ile
karar verir ve istemci oluturulan bu nesneyi Builder snfndan tekrar talep eder.

Yukardaki soyut aklamalardan sonra daha gereki bir rnekle bu deseni aklamamn
sizin ruh haliniz asndan faydal olacan dnyorum. Farkl donanm rnlerinin
biraraya getirilerek bilgisayar sistemlerinin oluturulduu bir teknik servisi gz nnde
bulunduralm. Bir mteri bu servise gelerek eitli zellikleri iinde barndran bir
bilgisayar talep eder. stei alan servis temsilcisi bu istei teknik birimlere iletir
ardndan teknik eleman istenilen zelliklerde bir bilgisayarn olumas iin gerekli
donanmlar raflarndan alr ve birletirir. Sonuta mterinin istei yerine gelir ve
karlkl bir mutluluk havas iine girilir. Tabi bizi ilgilendirin mterinin ve satcnn
mutluluu deil elbette. Bizi ilgilendiren nokta mterinin bilgisayar oluturuan
paralarn birletirilmesinden tamamen soyutlanddr. Dikkat ederseniz verilen
zelliklerde bilgisayarn olumasnda mterinin hi bir etkisi olmamtr. Eer mteri
son anda vazgeip farkl zelliklerde bir bilgisayar istemi olsayd yine bir etkisi
olmayacakt. Bu durumda eski bilgisayarn ilgili paralar deitirilip yeni istee uygun
paralar taklacakt. Burda da kompleks bir yap olan bilgisayar sisteminin kendisini
oluturan paralardan (donanm) tamamen bamsz bir yapda olduunu gryoruz.
Herhangi bir diskin yada monitrn deimesi bilgisayar bilgisayar yapmaktan
karmayacak sadece bilgisayarn tipini ve grntsn deitirecektir. Bu durum bizim
yukarda akladmz builder deseninin amacna tam olarak uymaktadr. Zira birazdan
bir teknik servisteki bu ileri otomatize eden temel desenimizi C# ile nasl
gerekletirebileceimizi greceiz.

Builder desenin de temel olarak 4 yap bulunmaktadr. Bu yaplar srasyla yledir :

"Builder" Arayz : Bu yap iinde gerek/somut(concrete) Builder snflarnn


uygulamas gereken zellikleri ve metotlar barndrr. "Builder" abstract bir snf
olabilecei gibi bir arayz de olabilir. En ok tercih edilen yap arayz olmasna
ramen uygulamanzn ihtiyacna gre abstract snflarda kullanabilirsiniz.
Gerek rneimizde bu yap bir bilgisayar sisteminin minimum olarak
uygulamas gereken zellikleri temsil eder. rnein kullanclara satlacak her
bilgisayar sistemi mutlaka HDD,RAM gibi yaplar ierisinde bulundurmaldr.
Dolaysyla birbirinden farkl bilgisayar sistemlerinin bu tr yaplar mutlak olarak
ierisinde barndrabilmesi iin zorlayc bir etkene dier bir deile abstract ye
elemanlara yada arayzlere ihtiyacmz vardr.

"Concrete(Somut) Builder" Yaps : Gerek bir bilgisayar sistemini temsil


eden ana yapmzdr. Farkl farkl donanmlarn bir araya getirilmesi ile ok
sayda sistem oluturulabilir. Oluturulabilecek her sistem gerek bir Builder
yapsna denk dmektedir.

Product(rn) : Gerek bir bilgisayar sistemini ve bu sistemde hangi


zelliklerin bulunduunu somut olarak yapsnda barndran bir modeldir. Bu
noktada bir nceki Concrete Builder yapsnn paralar oluturduunu, bu
paralarn birlemesinden oluan kompleks nesneninde Product olduunu
belirtmekte yarar var.

Director(Ynetici) : Genellikle istemci ile yani rneimizdeki mteri ile


Builder(paralar birletirip rn yapan birimler) yaplar arasnda kpr
grevinde bulunan yap olarak bilinir. Ksacas bilgisayar sisteminin olumas iin
raflardan donanmlar alp onlar birletiren teknik eleman Director grevindedir.
Tabi Director yapsnn i yaparken Builder arayznn kstlarna gre almas
gerektiinide belirtmek gerekir.

UML Modeli

Aadaki ekil "Builder" tasarm deseninin UML snf diagramn gstermektedir.


emadaki her bir ekil desendeki iligili yapy modellemektedir. Ayrca desendeki snflar
arasndaki ilikilerde detayl bir ekilde gsterilmitir.

Yukardaki UML diyagramn ksaca zetleyecek olursak : Builder arayznde bulunan


metotlar yardmyla gerek builder snflarnda kompleks nesnenin paralar
birletirilerek istenilen nesne oluturulur. Kompleks sistemi oluturan paralar farkl
saylarda olabildi halde minumum gereklilikleri de salamak zorundadr. Bu minumum
gereksinimler Builder arayznde bildirilmitir. Director snfndaki bir metot, her sistem
iin standart olan Builder arayzndeki metotlar kullanarak hangi sistemin
oluturulduundan bamsz olarak kompleks nesnenin oluturulmas salanr. Yani
Director hangi tr bir bir bilgisayar sisteminin oluturulaca ile ilgilenmez. Director
snf sadece kendisine gnderilen parametre sayesinde Builder arayznn
metotlarndan haberdardr. Son olarak istemci Director snfnn ilgili metotlarn
kullanarak gerek rnn olumasn salar. Bunun iin elbette Director snfnn ilgili
metoduna hangi rnn oluturulacan bildirmesi gerekir.

Bu ksa aklamadan sonra yukardaki diyagram baz alarak modern bir programlama
dili olan C# ile bu deseni nasl gerekletirebileceimizi inceleyelim.

Builder Deseninin C# ile Gerekletirilmesi

! Aadaki kodlar ksaca inceleyip aklamalar okumaya devam edin.

using System;

namespace BuilderPattern
{
public interface IBilgisayarToplayicisi
{
Bilgisayar Bilgisayar{get;}

void CDROM_Olustur();
void HDD_Olustur();
void Monitor_Olustur();
void RAM_Olustur();
}

public class GoldPC : IBilgisayarToplayicisi


{
private Bilgisayar mBilgisayar;

public Bilgisayar Bilgisayar


{
get{return mBilgisayar;}
}

public GoldPC()
{
mBilgisayar = new Bilgisayar("Gold-PC");
}

public void CDROM_Olustur()


{
mBilgisayar["cdrom"] = "52X GoldStar";
}

public void HDD_Olustur()


{
mBilgisayar["hdd"] = "60 GB Seagate";
}

public void Monitor_Olustur()


{
mBilgisayar["monitor"] = "17' Hyundai";
}

public void RAM_Olustur()


{
mBilgisayar["ram"] = "512 MB DDR Kingston";
}
}

public class SilverPC : IBilgisayarToplayicisi


{
private Bilgisayar mBilgisayar;

public Bilgisayar Bilgisayar


{
get{return mBilgisayar;}
}
public SilverPC()
{
mBilgisayar = new Bilgisayar("Silver-PC");
}

public void CDROM_Olustur()


{
mBilgisayar["cdrom"] = "48X Creative";
}

public void HDD_Olustur()


{
mBilgisayar["hdd"] = "30 GB Maxtor";
}

public void Monitor_Olustur()


{
mBilgisayar["monitor"] = "15' Vestel";
}

public void RAM_Olustur()


{
mBilgisayar["ram"] = "256 MB SD Kingston";
}
}

public class Bilgisayar


{
private string mBilgisayarTipi;
private System.Collections.Hashtable mParcalar = new
System.Collections.Hashtable();

public Bilgisayar(string BilgisayarTipi)


{
mBilgisayarTipi = BilgisayarTipi;
}

public object this[string key]


{
get
{
return mParcalar[key];
}
set
{
mParcalar[key] = value;
}
}

public void BilgisayariGoster()


{
Console.WriteLine("Bilgisayar Tipi : " + mBilgisayarTipi);
Console.WriteLine("---> CD-ROM Model : " + mParcalar["cdrom"]);
Console.WriteLine("---> Hard Disk Model : " + mParcalar["hdd"]);
Console.WriteLine("---> Monitr Model : " + mParcalar["monitor"]);
Console.WriteLine("---> RAM Model : " + mParcalar["ram"]);
}
}

public class TeknikServis


{
public void BilgisayarTopla(IBilgisayarToplayicisi bilgisayarToplayicisi)
{
bilgisayarToplayicisi.CDROM_Olustur();
bilgisayarToplayicisi.HDD_Olustur();
bilgisayarToplayicisi.Monitor_Olustur();
bilgisayarToplayicisi.RAM_Olustur();
}
}
}

Kaynak koddan da grlecei zere en temel yapmz IBilgisayarToplayicisi arayzdr.


Bu arayzde bir Bilgisayar rnn temsil etmek iin bir zellik ve bilgisayar oluturan
paralar oluturmak iin gereken metotlar bulunmaktadr. Bu metotlarn bu arayzden
treyen btn snflar tarafndan uygulanmas gerekmektedir. rneimizde bir GoldPC
ve SilverPC bilgisayar modelleri iin gereken bileenleri oluturmak iin 4 adet metot
bulunmaktadr. Burada en nemli nokta her Bilgisayar tipinde bir zelliinde bulunmas.
Bu zellik istendii zaman oluturulan Bilgisayar rnn istemciye vermektedir. Zaten
dikkat ederseniz her bir sisteme iliikin zellikler Bilgisayar snfndaki Hashtable
nesnesinde saklanmtr. Ayrca her Bilgisayar nesnesinin ayrca bir tip bilgisi
saklanmaktadr. Son olarak TeknikServis isimli snfmz ele alalm. Bu snf Builder
desenindeki Director yapsna denk dmektedir. Bu snftaki BilgisayarTopla metodu
kendisine gnderilen bilgisayartoplaycs arayz referansna ait metotlar kullanarak
Bilgisayar nesnesinin paralarn kendisi oluturmaktadr. Bu rnekte bilgisayar
oluturan her para kafa kartrmamak iin ayr bir snf olarak tasarlanmamtr.
Bunun yerine string trnden deerlere sahip olan bir hashtable nesnesi kullanlmtr.

Not : Yukardaki rnek gerek otomasyonda birebir kullanlamayabilir. rnein her bir
bilgisayar modeli iin ayr ayr snf tasarlamak ho olmayabilir. Bu sorunu daha dinamik
bir ekilde zmek gerekir. Buradaki rnek sadece Builder desenin daha rahat bir
ekilde kavrayabilmeniz iin verilmitir.

Son olarak yukardaki yaplar kullanan bir istemci program yazp desenimizi test
edelim.

using System;

namespace BuilderPattern
{
class Class1
{
static void Main(string[] args)
{
TeknikServis teknikservis = new TeknikServis();

IBilgisayarToplayicisi BT1 = new GoldPC();


IBilgisayarToplayicisi BT2 = new SilverPC();

tekniksevis.BilgisayarTopla(BT1);
teknikservis.BilgisayarTopla(BT2);

BT1.Bilgisayar.BilgisayariGoster();
Console.WriteLine("-------------");
BT2.Bilgisayar.BilgisayariGoster();
}
}
}

Program altrdmzda aadaki ekran grntsn elde ederiz.

Bilgisayar Tipi : Gold-PC


---> CD-ROM Model : 52X GoldStar
---> Hard Disk Model : 60 GB Seagate
---> Monitr Model : 17' Hyundai
---> RAM Model : 512 MB DDR Kingston
-------------
Bilgisayar Tipi : Silver-PC
---> CD-ROM Model : 48X Creative
---> Hard Disk Model : 30 GB Maxtor
---> Monitr Model : 15' Vestel
---> RAM Model : 256 MB SD Kingston

Desenlerle ilgili bir sonraki yazmda Creational desenlerden olan "Prototype" desenini
ele alacam. Herkese iyi almalar.

Kod Optimizasyonu ve "volatile" Anahtar Szc

Bu yazda C#'n nemli ama tam olarak neden kullanld baz profesyonel programclar
tarafndan bile pek fazla bilinmeyen bir anahtar szck olan volatile zerinde duracaz.

Bir ok popler derleyici sizin isteiniz dnda kodunuzun ileyi mantna mdahale
edebilmektedir. Bu mdahalenin en bilinen sebeplerinden birisi uygulumanzn kod
boyutunu kltmek yada uygulamanzn alma zamann drmektir. Aslnda biz bu
ilemlerin tamamna birden optimizasyon da diyebiliriz. Zira hemen hemen btn
derleyicilerin optimizasyon ileminin yaplp yaplmayacan belirten bir parametresi
vardr. C# derleyicisi iin bu parametre /optimize yada ksaca /o eklindedir.

Peki optimizastondan neyi anlamalyz? Genel olarak iki farkl ekilde optimizasyondan
bahsetmek mmkndr. Birincisi daha henz derleme aamasndayken programcnn
gznden kaan baz gereksiz bildirimlerin veya tanmlamalarn derleyici tarafndan
derlenecek koda dahil edilmemesi ile olabilir. rnein hi kullanmadnz bir deiken iin
bellekte bir alan tahsis edilmesinin hi bir gerei yoktur. Bu yzden hi bir yerde
kullanlmayan deikenlerin derleyiciniz tarafndan derleme modlne iletilmemesi bir
optimizasyon olarak grlmektedir. Bu tip optimizasyon kapsam iinde ele alnabilecek
dier bir rnek ise aadaki kod paras ile gsterilmitir.

Not : Aadaki kodun bilinsiz yada dalgn bir programc tarafndan yazldn
varsayyoruz.

int a = 0;

while(a != 0)
{
a=2;
a=0;
}

Yukardaki kodda ak hi bir zaman while blounun iine gelmeyecektir. Ve stelik eer a
deikeni farkl bir i parac(thread) tarafndan while blouna girmeden deitirilip ak
while blouna girse bile a deikeni while blou iinde tekrar eski sabit deerine atanyor.
Dolaysyla while blounda bulunan kodlarn altrlabilir uygulama dosyasnn boyutunu
bytmekten baka bir ie yaramayaca aktr. O halde burda insan st bir
mekanizmann devreye girip kodu optimize etmesi gerekir. Bu mekanizma elbetteki
derleyicinin optimizasyon iine yarayan parametresidir. Optimizasyon ileminde
derleyiciden derleyiciye fark olmasna ramen yukardaki kod parasnn geebilecei en
optimum biim aada gsterildii gibidir.

int a = 0;

while(a != 0)
{

Dier bir optimizasyon biimi ise derleyicinin deikenlerin elde edilmesinde yada tekrar
yazlmasnda bellein yada ilemcinin tercih edilmesi ile ilgilidir. Bu noktada
mikroilemciler ile ilgili ksa bir bilgi vermekte fayda var : Kaynak kodumuz altrlabilir
durumdayken aslnda makine koduna evrilmitir. Bu komutlar daha nceden
mikroilemcilerde elektronik dzeyde programlandklar iin bu komutlar tek tek
mikroilemcide kolaylkla icra edilir. Mikroilemciler ayn anda tek bir i yapabilecei iin
yapaca ilemler iinde kulland deikenleri her defasnda bellekten almak yerine daha
hzl olmas asndan mikroilemcideki data register dediimiz kaytlarda tutar. Bu
register dediimiz blmlerin snrl sayda bulunduunu belirtmek gerekir. Dolaysyla
bellekte bulunan uygulamamzn ihtiyacna gre daha dorusu icra edilecek bir sonraki
makine kodunun eidine gre ilemci bellekten ilgili deikenleri register'larna ykler ve
ilgili komutunu altrr. Doaldr ki bir deerin mikroilemci tarafndan bellee(ram)
yazlmas ile mikroilemcideki register blgesine yazlmas arasnda dalar kadar fark
vardr. Bu fark elbette hz faktrdr. te tam bu noktada ikinci tip optimizasyon kuraln
tanmlayabiliriz. Derleyici yle bloklara rastlayabilir ki, bu bloklar iinde bulunan bir
deikenin deerini her defasnda bellekten okuyacana bu deikenin deerini bir
defaya mahsus olmak zere mikroilemcinin ilgili register blgesine blgesine kaydeder
ve sonraki okumalarda ilemci bellek yerine bu register blgesini kullanr. Bylece
kodunuzun alma sresinde nemli saylabilecek bir azalma grlr. Elbetteki bu
optimizasyon ileminin yzlerce kez tekrarlandn varsayarak bu sonuca varyoruz.

Yukarda deiken okuma ile ilgili sylediklerimin ayns bir deikenin deerini
deitirmek iin de geerli olduunu belirtmeliyim. Yani siz programnzn 10. satrnda bir
deikenin deerini bir deerden baka bir deer ektiiniz halde derleyici bu ilemi
15.satrda yapabilir. Bu durumda 15. satra kadar o deikenin kullanlmad yorumunu
yapabiliriz. Bu ekilde mikroilemcinin bellee yazma ilemi geciktirilerek belli lde
optimizasyon salanr. Tabi bu optimizasyonun ls tamamen mikroilemcinin o anki
durumuna baldr.

Buraya kadar herey normal. Bir de madolyonun teki yzne bakalm. Bildiiniz zere
uygulamalar genellikle oklu i paracklarndan(multi thread) ve proseslerden oluur. Her
bir proses dier bir proses teki deikene iletim sisteminin izin verdii lde eriip
zerinde ilemler yapabilir. Ayn ekilde bir i paracda dier bir i paracnda
bulunan deikene eriip zerinde eitli ilemler yapabilir. Peki bunun bizim
optimizasyon kurllarmzla balants ne? yle ki : derleyici bir deikenin deerinin farkl
bir i paraca tarafndan yada farkl bir proses tarafndan ilenecei zerinde durmaz.
Bu tamamen iletim sisteminin ynetimindedir. Hal byleyken bizim yukarda
bahsettiimiz ikinci optimizasyon tipi baz durumlarda yarar getireceiniz zarar getirebilir.
Zira optimizasyon adna bir deikenin deerini her defasnda bellekten okuma yerine
mikroilemcideki ilgili register dan okurken o anda farkl bir i paraca yada farkl bir
proses hatta ve hatta iletim sistemi sizin erimeye altnz deikenin deerini sizin
uygulamanzn mantna gre deitirebilir. Bu durumda siz o deikenin son halini
kullanmam olursunuz. Dolaysyla programnzda farkl thread lar yada prosesler
arasnda paylalan veya iletim sistemi tarafndan deitirilmesi muhtemel olan
deikenlerinizi optimizasyon kuralna tabi tutmamanz gerekir. Peki bunu nasl
baaracaz?

volatile anahtar szc burada imdadmza yetiiyor. Bir deikeni volatile anahtar
szc ile bildirdiiniz takdirde derleyicinizin optimizasyon ile ilgili parametresini ak
tutsanz bile ilgili deiken yukarda bahsi geen tehlikeli optimizasyon kurallarna tabi
tutulmayacaktr. Yani volatile ile bildirilen deikenlere programn ak srasnda her
ihtiya duyulduunda deikenin gerek yeri olan bellee bavurulur. Ayn ekilde bir
deikene yeni bir deer yazlaca zaman bu yazma ilemi hi geciktirilmeden bellekteki
yerine yazlr. Bylece volatile ile bildirilen deikenler farkl i paracklar yada prosesler
tarafndan ortak kullanlyor olsada programn ak ierisinde her zaman son versiyonu
elde edilecektir. nk bu deikenlerin deeri her defasnda bellekten ekilir. Her ne
kadar optimizasyondan taviz verme zorunda kalsak ta bylece uygulamalarmzda
kabilecek olas buglarn(bcek) nne gemi oluruz.

volatile, C# dilindeki anahtar szcklerden biridir. ye deiken bildirimi ile birlikte


kullanlr. volatile anahtar szc yalnzca aadaki deiken tipleri ile birlikte
kullanlabilir.

Herhangi bir referans tipindeki deiken ile

byte, sbyte, short, ushort, int, uint, char, float yada bool. trnden olan
deikenler ile

byte, sbyte, short, ushort, int, yada uint trnden semboller ieren
numaralandrmalar(enums) ile

unsafe modda iken herhangi bir gsterici tr ile

volatile anahtar szcnn kullanmna baz rnekler verelim :

public static volatile int a;

public volatile bool a;


public volatile int* a;

....

Microsoft'un resmi dkmanlarnda(MSDN) verilen bir rnei buraya tayarak ne gibi


durumlarda volatile anahtar szcne ihtiya duyacabileceimizi grelim.

using System;
using System.Threading;

class Test
{
public static int result;
public static volatile bool finished;

static void Thread2()


{
result = 143;
finished = true;
}

static void Main()


{
finished = false;
new Thread(new ThreadStart(Thread2)).Start();

for (;;)
{
if (finished)
{
Console.WriteLine("result = {0}", result);
return;
}
}
}
}

Yukardaki rnek programdaki pf nokta finished isimli deikenin ana thread ve ana
thread iinde balatlan yeni thread tarafndan ortak kullanlan bir deiken olmasdr.
Eer finished deikeni volatile olarak bildirilmemi olsayd, ak thread2 metoduna
gelmi olmasna ramen Main metodu iindeki if blou altrlmayabilirdi. nk
derleyici ana thread iinden finished deikeninine tampolanm bir blgeden(register)
eriebilir. Bu durumda finished deikeninin gerek deeri true olmasna ramen ana
thread de finished deikeni halen false olarak ele alnr. Bu yzden finished deikeninin
her durumda son versiyonunu elde etmek iin bu deiken volatile anahtar szc ile
bildirilmitir.

volatile anahtar szcnn kullanmna bir rnek daha verelim. Belli bir anda bir snftan
sadece bir nesnenin olumasn salayan Singleton desenini daha nceki bir makalemde
ele almtm. Bu konu ile ilgili bilgi eksikliiniz varsa ilgili makaleyi okumanz tavsiye
ederim. Bahsi geen makalede verilen desenin bir uygulamas aada ki gibi yeniden
yazlmtr.

public class SingletonDeseni


{
private static volatile SingletonDeseni nesne;
private static Object kanalKontrol = new Object;

private SingletonDeseni()
{

public static Singleton Nesne()


{
if(nesne == null)
{
lock(kanalKontrol)
{
if(nesne == null)
{
nesne = new SingletonDeseni();
}
}
}

return nesne;
}
}

Bu rnekte SingletonDeseni nesnesinin belli bir anda tekil olarak bulunduunu ok kanall
uygulamalar iinde geerli klmak iin bu nesne volatile olarak bildirilmitir. stelik bu
rnekte farkl bir prosesin mdahalesi olsa bile bu nesneden ancak ve ancak bir adet
yaratlacaktr.

Son olarak volatile kelimesinin szlk anlam zerinde durmak istiyorum. ki yl nce
ngilizce'den Trke'ye evrilmi bir Visual C++ kitabn okuduumda volatile ile
bildirilmi deikenlerden oynak(!) deikenler diye bahsedildiine ahit oldum. lk bata
bu ilgin kullanm bana birey ifade etmedi ama hislerimin yardmyla aslnda yazarn
volatile dan bahsettiine karar verdim. Sizde takdir edersiniz ki yukarda anlattklarmz
ile "oynak" kelimesi arasnda pek bir ba bulunmamaktadr. Kitabn evirisini yapan yazar
muhtemelen bir programc deil bir evirmendi. nk eer iyi bir programc olsayd
oynak kelimesi yerine daha uygun bir kelime seilebilirdi. volatile'n szlk anlam "uucu
olan", "buhar olan" anlamna gelmektedir. Ancak ben henz volatile szcne kendi
mesleimizle ilgili uygun bir karlk bulamadm. Bu konuda daha nce cdili ve cdernek
isimli iki yahoo grubunda eitli tartmalar olmutur. Bu gruplara ye olarak ilgili
tartmalarda geen konumalar okumanz neririm. Eer sizin de bu konuda nerileriniz
varsa bizimle paylarsanz seviniriz.

Umarm faydal bir yaz olmutur. Herkese iyi almalar...


Overloaded(Ar Yklenmi) Metotlarn Gc

Bu makalemde sizlere overload kavramndan bahsetmek istiyorum. Konunun daha iyi


anlalabilmesi asndan, ilerliyen ksmlarda basit bir rnek zerinde de alacaz.

ncelikle Overload ne demek bundan bahsedelim. Overload kelime anlam olarak Ar


Ykleme anlamna gelmektedir. C# programlama dilinde overload dendiinde, ayn isme
sahip birden fazla metod akla gelir. Bu metodlar ayn isimde olmalarna ramen, farkl
imzalara sahiptirler. Bu metodlarn imzalarn belirleyen unsurlar, parametre saylar ve
parametre tipleridir. Overload edilmi metodlar kullandmz snflarda, bu snflara ait
nesne rnekleri iin ayn isme sahip fakat farkl grevleri yerine getirebilen ( veya ayn
grevi farkl say veya tipte parametre ile yerine getirebilen ) fonksiyonellikler kazanm
oluruz.

rnein;
ekil 1 : Overload metodlar.

ekil 1 de MetodA isminde 3 adet metod tanm gryoruz. Bu metodlar ayn isime sahip
olmasna ramen imzalar nedeni ile birbirlerinden tamamyla farkl metodlar olarak
alglanrlar. Bize salad avantaj ise, bu metodlar barndran bir snf nesnesi
yarattmzda ayn isme sahip metodlar farkl parametreler ile arabilmemizdir. Bu bir
anlamda her metoda farkl isim vermek gibi bir karklnda bir nebze nne geer. Peki
imza dediimiz olay nedir? Bir metodun imzas u unsurlardan oluur.

Metod mzasn Kabul Edilen Metod mzas Kabul


Unsurlar Edilmeyen Unsurlar

Parametre says Metodun geri dn


tipi
Parametrelerin tipleri

Tablo 1. Kullanm Kurallar

Yukardaki unsurlara dikkat ettiimiz srece dilediimiz sayda ar yklenmi (overload


edilmi) metod yazabiliriz.

imdi dilerseniz kk bir Console uygulamas ile , overload metod oluumuna engel tekil
eden duruma bir gz atalm. ncelikle metodun geri dn tipinin metodun imzas olarak
kabul edilemiyeceininden bahsediyoruz. Aadaki rneimizi inceleyelim.

using System;

namespace Overloading1
{
class Class1
{
public int Islem(int a)
{
return a*a;
}

public string Islem(int a)


{
string b=System.Convert.ToString(a);
return Yasim:+b;
}

[STAThread]
static void Main(string[] args)
{
}
}
}

rnein yukardaki uygulamada, Islem isimli iki metod tanmlanmtr. Ayn parametre tipi
ve saysna sahip olan bu metodlarn geri dn deerlerinin farkl olmas neden ile
derleyici tarafndan farkl metodlar olarak alglanm olmas gerektii dnlebilir. Ancak
byle olmamaktadr. Uygulamay derleme altmzda aadaki hata mesaj ile
karlarz:

Overloading1.Class1' already defines a member called 'Islem'


with the same parameter types

Yapc metodlar da overload edebiliriz. Bu nokta olduka nemlidir; ki metodlar overload


etmeyi .NET ile yazlm gelitirirken ska kullanrz. rnein, SqlConnection snfndan bir
nesne rnei oluturmak istediimizde bunu yapabileceimiz 2 tane overload edilmi
yapc metod olduunu grrz. Bunlardan birisi aada grlmektedir.

ekil 2. rnek bir Overload Constructor(Ar Yklenmi Yapc) metod.

Dolaysyla bizde yazdmz snflara ait constructorlar overload edebiliriz. imdi dilerseniz
overload ile ilgili olaraktan ksa bir uygulama gelitirelim. Bu uygulamada yazdmz bir
snfa ait constructor metodlar overload ederek deiik tipte fonksiyonellikler edinmeye
alacaz.

Bu uygulamada KolayVeri isminde bir snfmz olucak. Bu snfn adet yapcs olucak.
Yani iki adet overload constructor yazcaz. ki tane diyorum nk C# zaten default
constructoru biz yazmasak bile uygulamaya ekliyor. Bu default constructorlar parametre
almayan constructorlardr. Overload ettiimiz constructor metodlardan birisi ile, setiimiz
bir veritabanna balanyoruz. Dier overload metod ise, parametre olarak veritaban
adndan baka, veritabanna balanmak iin kullanc ad ve parola parametrelerinide
alyor. Nitekim ou zaman veritabanlarmzda yer alan baz tablolara eriim yetkisi
snrlamalar ile karlaabiliriz. Bu durumda bu tablolara balant aabilmek iin yetkili
kullanc ad ve parolay kullanmamz gerekir. Byle bir olay canlandrmaya altm.
Elbetteki asl amacmz overload constructor metodlarn nasl yazldn, nasl kullanldn
gstermek. rnek gelimeye ok, hemde ok ak. imdi uygulamamzn bu ilk ksmna bir
gzatalm. Adakine benzer bir form tasarm yapalm.
imdi sra geldi kodlarmz yazmaya. ncelikle uygulamamza KolayVeri adnda bir class
ekliyoruz. Bu classn kodlar aadaki gibidir. Aslnda uygulamaya bu aamada
baktmzda SqlConnection nesnemizin bir balant oluturmasn zelletirmi gibi
oluyoruz. Gerekten de ayn ilemleri zaten SqlConnection nesnesini overload
constructorlari ile yapabiliyoruz. Ancak temel amacmz airi yklemeyi anlamak olduu
iin programn alma amacnn ok nemli olmad dncesindeyim. Umuyorum ki
sizlere ar ykleme hakknda bilgi verebiliyor ve vizyonunuzu gelitirebiliyorumdur.

using System;
using System.Data.SqlClient;

namespace Overloading
{
public class KolayVeri
{

/* Connection'in durumunu tutacak ve sadece bu class iinde


geerli olan bir string deiken tanmladk. private anahtar kelimesi
deikenin sadece bu class ierisinde yaayabilceini belirtir.
Yazmayabiliriz de, nitekim C# default olarak deikenleri private kabul
eder.*/
private string baglantiDurumu;

/* Yukarda belirttiimiz baglantiDurumu isimli deikenin sahip olduu


deeri, bu class'a ait nesne rneklerini kullandimz yerde grebilmek
iin sadece okunabilir olan (readonly), bu sebeplede sadece Get blouna
sahip olan bir zellik tanmlyoruz.*/
public string BaglantiDurumu
{
get
{
/* Bu zellie eritiimizde baglantiDurumu deikeninin
o anki deeri geri dndrlecek. Yani zelliin
agrld yere dndrlcek.*/
return baglantiDurumu;
}
}

/* Iste C# derleyicisinin otomatik olarak ekledii parametresiz yapc


metod. Biz bu yapcya tek satrlk bir kod ekliyoruz. Eer nesne rnei
parametresiz bir Constructor ile yaplrsa bu durumda balantnn kapal
olduunu belirtmek iin baglantiDurumu deikenine bir deer atyoruz. Bu
durumda uygulamamzda bu nesne rneinin BaglantiDurumu zelliine
eristiimizde BALANAMADIK deerini elde edeceiz.*/
public KolayVeri()
{
baglantiDurumu="BALANAMADIK";
}

/* Bizim yazdmz ar yklenmi ilk yapc metoda gelince. Burada


yapcmz, parametre olarak bir string alyor. Bu string veritabannn
adn barndrcak ve SqlConnection nesnemiz iin gerekli baglant
stringine bu veritabannn adn geiricek.*/
public KolayVeri(string veritabaniAdi)
{
string connectionString="initial
catalog="+veritabaniAdi+";data source=localhost;integrated
security=sspi";
/* SqlConnection baglantmz yaratlyor.*/
SqlConnection con=new SqlConnection(connectionString);

/* Baglant ilemini bir try blounda yapyoruz ki, herhangi bir nedenle
Sql sunucusuna balant salanamazsa (rnegin hatal veritaban ad
nedeni ile) catch blounda baglantiDurumu deikenine BALANAMADIK
deerini atyoruz. Bu durumda program iinde KolayVeri snfndan rnek
nesnenin BaglantiDurumu zelliinin deerine baktmzda BALANAMADIK
deerini alyoruz bylece balantnn saglanamadna kanaat getiriyoruz.
Kanaat dedikte aklima skdarda ki Kanaat lokantasi geldi :) Yemekleri
ok gzeldir. Sanirim karnmz ackt... Neyse kaldmz yerden devam
edelim.*/
try
{
con.Open(); // Balantmz alyor.
/* BaglantiDurumu zelliimiz (Property), baglantiDurumu
deikeni sayesinde BALANDIK deerini alyor.*/
baglantiDurumu="BAGLANDIK";
}
/* Eer bir hata olursa baglantiDurumu deiskenine
BALANAMADIK deerini atyoruz.*/
catch(Exception hata)
{
baglantiDurumu="BAGLANAMADIK";
}
}

/* Sra geldi ikinci overload constructor metoda. Bu metod ekstradan iki


parametre daha alyor. Bir tanesi user id'ye tekabl edicek olan
kullaniciAdi, dieri ise bu kullanc iin password'e tekabl edecek olan
parola. Bunlar SqlConnection'in connection stringine alarak ,
veritabanna belirtilen kullanc ile giri yapm oluyoruz. Kodlarn
ileyii bir nceki metodumuz ile ayn.*/
public KolayVeri(string veritabaniAdi,string kullaniciAdi,string
parola)
{
string connectionString="initial
catalog="+veritabaniAdi+";data source=localhost;user
id="+kullaniciAdi+";password="+parola;
SqlConnection con=new SqlConnection(connectionString);
try
{
con.Open();
baglantiDurumu="BAGLANDIK";
}
catch(Exception hata)
{
baglantiDurumu="BAGLANAMADIK";
}
}
}
}

imdi sra geldi, formumuz zerindeki kodlar yazmaya.

string veritabaniAdi;

private void lstDatabase_SelectedIndexChanged(object sender,


System.EventArgs e)
{
veritabaniAdi=lstDatabase.SelectedItem.ToString();

/* Burada kv adnda bir KolayVeri snfndan nesne rnei (object


instance) yaratlyor. Dikkat edicek olursanz burada yazdm
ikinci overload constructor'u kullandk.*/

KolayVeri kv=new KolayVeri(veritabaniAdi);


/* Burada KolayVeri( dediimizde .NET bize kullanabileceimiz ar
yklenmi constructorlar aagdaki ekilde olduu gibi
hatrlatacaktr. IntelliSencein gzn seveyim.*/

Sekil 4. 2nci yapc

stbDurumBilgisi.Text=lstDatabase.SelectedItem.ToString()+"
"+kv.BaglantiDurumu;

private void btnOzelBaglan_Click(object sender, System.EventArgs e)


{
string kullanici,sifre;
kullanici=txtKullaniciAdi.Text;
sifre=txtParola.Text;
veritabaniAdi=lstDatabase.SelectedItem.ToString();

KolayVeri kvOzel=new KolayVeri(veritabaniAdi,kullanici,sifre);


/* Burada ise dier ar yklenmi yapcmz kullanarak bir
KolayVeri nesne rnei oluturuyoruz.*/

ekil 5. 3nc yapc

stbDurumBilgisi.Text=lstDatabase.SelectedItem.ToString()+"
"+kvOzel.BaglantiDurumu+" User:"+kullanici;
}

Evet imdide programn nasl alitna bir bakalm. Listbox nesnesi zerinde bir
veritaban adna bastmzda bu veritabanna bir balant alr.

ekil 6. Listboxta tklanan veritabanna balandktan sonra.

Ve birde kullanc ad ile parola verilerek nasl balanacamz grelim.


ekil 7. Kullanc ad ve parola ile balant

Peki ya yanl kullanc ad veya parola girersek?

ekil 8. Yanl kullanc ad veya parolas sonras.

Evet deerli okuyucular bu seferlikte bu kadar. Bir sonraki makalemizde grmek


dileiyle hepinize mutlu gnler, yarnlar dilerim.
C#'ta Numaralandrclar(Enumerators)

Bu makalemizde, kendi deer trlerimizi oluturmann yollarndan birisi olan


Enumerator'lar inceleyeceiz. C# dilinde veri depolamak iin kullanabileceimiz temel
veri trleri yannda kendi tanmlayabileceimiz trlerde vardr. Bunlar Structs(Yaplar),
Arrays(Diziler) ve Enumerators(Numaralandrclar)'dr.

Numaralandrclar, snrl sayda deer ieren deikenler yaratmamza olanak salarlar.


Burada bahsi geen deiken deerleri bir grup olutururlar ve sembolik bir adla temsil
edilirler. Numaralandrclar kullanma nedenlerimizden birisi verilere anlamlar
yklekleyerek, program ierisinde kolay okunabilmelerini ve anlalabilmelerini
salamaktr.

rneklerimizde bu konuyu ok daha iyi anlyacaksnz. Bir Numaralandrc tanmlamak


iin aadaki szdizimi (syntax) kullanlr.

<Kapsam belirteleri> enum <numaralandrcAdi>


{
<birinciUye>,
<ikinciUye>,
<ucuncuUye>,
}

Kapsam belirteleri protected, public, private, internal yada new deerini alr ve
numaralandrcnn geerli olduu kapsam belirtir. Dikkat edilecek olursa, elemanlara
herhangi bir deer atamas yaplmamtr. Nitekim bu numaralandrclarn zelliidir. lk
eleman 0 deerine sahip olmak zere dier elemanlar 1 ve 2 deerlerini sahip olucak
ekilde belirlenirler. Dolaysyla programn herhangi bir yerinde bu numaralandrcya ait
elemana ulatmzda, bu elemann index deerine erimi oluruz. Grdnz gibi
numaralandrc kullanmak okunurluu arttrmaktadr.

Dilersek numaralandrc elemanlarnn 0 indexinden deil de her hangibir deere


balamasn salayabilir ve hatta dier elemanlarada farkl index deerleri atayabiliriz.
Basit bir numaralandrc rnei ile konuyu daha iyi anlamaya alalm.

using System;

namespace enumSample1
{
class Class1
{

/* Haftanin gnlerini temsil edicek bir numaralandrc tipi oluturuyoruz.


Pazartesi 0 index deerine sahip iken Pazar 6 index deerine sahip
olucaktr.*/

enum Gunler
{
Pazartesi,
Sali,
Carsamba,
Persembe,
Cuma,
Cumartesi,
Pazar
}

static void Main(string[] args)


{
Console.WriteLine("Pazartesi gnnn degeri={0}",
(int)Gunler.Pazartesi);

Console.WriteLine("arsamba gnn degeri={0}",


(int)Gunler.Carsamba);
}

Burada Gunler yazdktan sonra VS.NET in intellisense zellii sayesinde,


numaralandrcnn sahip olduu deerlere kolayca ulaabiliriz.

Program altrcak olursak aadaki ekran grntsn elde ederiz:

imdi baka bir rnek gelitirelim. Bu kez numaralandrcnn deerleri farkl olsun.

using System;

namespace enumSample
{
class Class1
{

enum Artis
{
Memur = 15,
Isci = 10,
Muhendis = 8,
Doktor = 17,
Asker = 12,
}

static void Main(string[] args)


{
Console.WriteLine("Memur maasi zam artis orani={0}",
(int)Artis.Memur);

Console.WriteLine("Muhendis maasi zam artis orani= {0}",


(int)Artis.Muhendis);
}

Dikkat edicek olursak, numaralandrclar program iinde kullanrken, ak olarak(explicit)


bir dnm yapmaktayz. u ana kadar numaralandrc elemanlarna integer deerler
atadk. Ama dilersek Long tipinden deer de atayabiliriz. Fakat bu durumda enumin
deer trnde belirtmemiz gerekmektedir.rnegin:

using System;

namespace enumSample
{
class Class1
{

enum Snrlar: Long


{
EnBuyuk = 458796452135L,
EnKucuk = 255,
}

static void Main(string[] args)


{
Console.WriteLine("En st sinir={0}",(long)Sinirlar.EnBuyuk);

Console.WriteLine("Muhendis maasi zam artis orani={0}",


(long)Sinirlar.EnKucuk);
}

}
Grld gibi Snrlarlar isimli numaralandrc long tipinde belirtilmitir. Bu sayede
numaralandrc elemanlarna long veri tipinde deerler atanabilmitir. Dikkat edilecek bir
dier nokta ise, bu elemanlara ait deerleri kullanrken, long tipine dntrme
yaplmasdr.

Bir numaralandrc varsaylan olarak integer tiptedir. Bu nedenle integer deerleri olan
bir numaralandrc tanmlanrken int olarak belirtilmesine gerek yoktur.

imdi daha ok ise yarar bir rnek gelitirmeye alsalm. Uygulamamz son derece basit
bir forma sahip ve bir ka satr koddan oluuyor. Amacmz numaralandrc kullanmann
programc asndan ileri daha da kolaylatryor olmas. Uygulamamz bir Windows
Application. Form tasarmmz aadaki gibi olucak.

Form yklenirken ehir Kodlarnn yer ald comboBox kontrolmz otomatik olarak
numaralandrcnn yardmyla doldurulucak. Ite program kodlar:

using System;

namespace enumSample
{
class Class1
{

enum AlanKodu: Long


{
Anadolu=216,
Avrupa=212,
Ankara=312,
Izmir=412
}

private void Form1_Load(object sender, System.EventArgs e)


{
comboBox1.Items.Add(AlanKodu.Anadolu);

comboBox1.Items.Add(AlanKodu.Ankara);

comboBox1.Items.Add(AlanKodu.Avrupa);

comboBox1.Items.Add(AlanKodu.Izmir);

}
}

te sonu:

Aslnda bu comboBox kontroln baka ekillerde de alan kodlar ile ykleyebiliriz. Bunu
yapmann saysz yolu var. Burada asl dikkat etmemiz gereken nokta numaralandrc
sayesinde bu saysal kodlarla kafamz kartrmak yerine daha bilinen isimler ile ayn
sonuca ulamamzdr.

Geldik bir makalemizin daha sonuna. lerliyen makalelerimizde bu kez yine kendi deer
tiplerimizi nasl yaratabileceimize struct kavrami ile devam edeceiz. Hepinize mutlu
gnler dilerim.
Microsoft .NET Programlama Dilleri

Bu yazda Microsoft dotNET ile birlikte programclara sunulun gelitirme dilleri zerinde
durulmutur. Bu yaz Temmuz 2003'te MSDN de yaynlanan Microsoft Programming
Languages yazsndan Trke'ye evrilmitir.

Microsoft .NET'in Yararlar

Microsoft . NET Framework ,XML Web Servisi ve uygulamalarnn derlenip altrlmas


iin gerekli olan Microsoft Windows bileenlerini ierir. Bu; bize gelitirdiimiz
uygulamalarda

yksek bir verim ,

standart bir alt yap,

daha basit uygulama gelitirme ,

oklu dillerin(multilanguage) bulunduu bir ortam ,

var olan programlama bilgilerinden yararlanabilme,

var olan uygulamalar ile kolay entegre olabilme,

internet uygulamalarnda kullanabilme ve altrmann rahatln getirir.

.NET Framework, iki ana blmden oluur : CLR(Common Language Runtime) ve web
tabanl programlamada devrimsel bir gelime yaratan birletirilmi snf
ktphanesi(ASP.NET), akll istemci uygulamalarn gerekletirmek iin Windows
formlar, ortam ve temel veri girileri iin ADO.NET alt sistemi. Programclar iki farkli dille
uygulama gelitirirken rahatlkla .NET Framework kullanabilirler. Bu dillerin hepsi (MSIL)'e
derlenir ve daha sonra native(ana) koda dntrlr ve CLR ortamnda altrlr. Bu
sayede herhangi bir dille yazlan herhangi bir uygulama baka bir uygulama ile kolaylkla
entegre olabilir. Bu ortamn programclara salad yarar udur; ilerini yaparken
kullanmalar iin geni bir dil seenegi vardir ve dolaysyla programclar en iyi bildikleri
dili seebilirler.

Geni Bir Dil Seenei

Sanatlar alrken bulunduklar ortam ve aralar, sanatlarn tecrbelerini ve


kiiliklerini yanstr. Ayn yazlm uzmanlar gibi onlarda bildikleri dili ve eitimlerini gz
nne alarak alrlar. Tm yazlm uzmanlarn memnun edecek bir dil henz yoktur.
Programclar, doutan farkl bir kimliktirler: ksmen bilim adam, ksmen sanat, her
zaman dik kafal, ve hep daha iyisini aratran insanlardr. Buna ramen modern
programlama dillerinin eksikliklerini kabul ederler.

"Biz her zaman, yarm milyon veya 50 milyon VB(Visual Basic) bilen programcya sahip
olacaz. Bizim, .NET 'de VB miz var. Ve bizim simdi, . NET'de Java dilimiz ve hatta,
COBOL dilimiz bile var! Bunun ne demek oldugunu tahmin et? " -Tim Huckaby, baskan
ve CEO, Interknowlogy

Programlama dilleri personel almnda nemli bir faktrdr. Bir yazlm uzmannn bildii
dilden baka bir dili kullanmaya gemesi zordur. .NET yapsnn gc ile bir ka dili iinde
barndran bir platform salar. Programclar bu platform da-C++, Objective C, Fortran,
COBOL, Visual Basic, Perl -'in her biri ile gl yazlm gelitirilebilirler.

Bu blmde Microsoft'un drt farkl programlama dili sunduunu ve bunlar tek bir
ortamda nasl birletirdiini greceiz.

Visual Basic.NET , dnyann en popler gelitirme aracnn ve dilinin en son


uyarlamasdr. Visual Basic.NET, vazgeilemez verimliligi teslim eden, ve
task(grev)-oriented(ynelimli) programlama iin esiz zellikler sunan bir dildir.

Visual C++ dili, power(g)-oriented(ynelimli) gl uygulamalar gelitirilebilen ,


farkli teknolojilerle kpr kurabilen, hem windows doal diline
hemde(assembly) .NET ara diline(IL) derlenebilen maksimum performans
karekteristiklerine ve yksek fonksiyonaliteye sahip bir dil olarak karmza kar.

Visual C #.NET , modern ve yenilik getiren programlama dili ve gelitirme


aracdr. Microsoft, C# ile bizi 2001'de tantrd, C++ ve Java programclarnn
bildii bir sentaks(szdizimi) ile sunulmutu, bu yzden C++ ve Java
gelitiricilerinin ilgisini ekmis olan C#, .NET Framework ile beraber kod
odakl uygulamalar daha dzenli bir dil yaps ile sunar.

Visual J#.NET , Microsoft . NET iin Java-dili gelistirme aracidir. Visual J#.NET,
Visual J++ ve Java gelistiricilerine kendi dil ve sz dizimlerinden uzaklasmadan
.NET'in olanaklarindan tam olarak yararlanabilmeyi ve endstrinin en gelismis XML
web servisleri platformundan faydalanabilmelerini saglamistir.

Burada Microsoft, programlama dillerindeki geni dil seeneinin gelitiricilere uygunluu


ile dikkat eker. Microsoft.NET, programclar bu yeni platformda birletirmek iin eitim
ve zme daha hzl ulamay saglamada onlara yardm etme imkan da sunar.

Visual Basic .NET

Visual Basic 1.0, Windows'un gelimesi ve daha geni bir kullanc saysna ulamas ve
gnmzdeki verimliliine kavumas iin bir devrim yaratt. Byle zengin bir tarihe sahip
olan VB , okunabilir bir syntax, sezgisel bir arayzn ve aletlerin oldugu , task-
oriented(grev ynelimli) yaps ile hzl build edilebilmesi ile ve .Net ile yeni bir
yaplandrmaya kavumutur. Visual Basic.NET dilinede dier popular diller gibi her tr
Windows uygulamas, WEB,ve mobile aletler iin uygulama yapabilme yetenekleri eklendi.

Task-Orinted(grev ynelimli) Gelime

Deadline(Son teslim) tarihleri, yazlm sanayisine yeni olan bir ey deildir. Programclarn
byk bir grubu iin, deadline tarihleri, gnlk hayatn bir gereidir. Programclar
ounlukla, plan yaparken ,iin gereksinimlerini karlayacak hzl bir yolun zmn
ararlar. Bazi zmler , bu ortamlar yaratlrken dikkatlice test edilecek, daha sonra
uygulama bu tarz yaplarda hemen kullanlacaktr. Uygulama gelitirme uzmannn
problemlerde zme odaklanmas iin bir dahaki i verilene kadar serbest braklmas
gerekir. Task-Oriented bir gelitirme ortam, ortam farkllklarndan programcy
kurtarmak iin kabul edilebilir bir yntemdir.

Hangi Programclar Neden VB.NET'i Semelidir?


Gelecek kuak uygulamalar ve servisleri birletirerek .NET ortamnda aratrma yapmak
isteyen aadaki tipteki programclar iin Visual Basic.NET ideal bir dildir.

.NET Framework ortamnda hzl ve retken bir arala uygulama gelitirmek


isteyen programclar : .Net ile birlikte hizli ve rahat bir gelistirme araci sunulurken
Visual Basic.NET uygulamalarinda kolay sntax ve sezgiyle elde edilen gelistirme ortamini
sunar. Ayrca VB.NET progracmlar ilgili kaynaklara ok hzl bir ekilde eriebime
imkanna sahiptir.

VB ile uygulama gelitirme tecrbesi olan programclar : Visual Basic bilen


programcilar iin Visual Basic.Net yapisina gemek zor olmayacaktir. Visual Basic .NET
anahtar szckleri, sentaks ve derleme yaps ile farkllklar olutursa da, geleneksel VB
programcsna tandk gelecektir. VB.NET te ayrca case-insensitivity, anlalr kodlar ve
sentaks vardr. Visual Basic'in ilk versiyonlarn kullananlarda .NET kullanmaya
ynelebilirler. Mevcut bulunan ActiveX kontrollerini de Visual Basic .NET te kullanmaya
devam edebilirler.

Halihazrdaki ortamlara benzer tasarm zaman ve kod editr paradigmalar


arayan programclar : Gelitiriciler bildik bir arayz ve editor ararken, VB.NET ile
uygulamalarn tasarm drag and drop ile yaplabiliyor. Ayrca otomatik, kolay
biimlendirilmi bir kodlama sunar.

Sezgisel ve eriebilirlik zellii yksek olan bir dille gelitirme yapmak isteyen
programclar : Visual Basic.NET, gelitiricilerin byk bir blmne ulaabilmek iin
tasarlanmtr. Bu nedenle hem uzmanlara, hem de yeni balayanlara nerilir. Yeni
balayanlar, Visual Basic ortamnn ve Visual Basic dilinin birok benzersiz zelligini
faydal bulacaktr.

VB.NET Diline Has zellikler

VB.NET, uygulama retkenliini hzlandracak dier .NET dillerinde olmayan bir takm
zellikleri iinde barndrr.

Deikenlere varsaylan ilk deer verme :VB.NET'te deikenleri kullanlmadan


nce onlara ilk deer verilme zorunluluu yoktur. Bu yzden yeni balayan bir ok
programcnn dier dillerde olduu gibi kafas karmayacaktr.

Implicit typing(dolayl tr belirtme) ve ge balama(late binding) :Visaul


Basic.Net te bir deiken kullanlmadan nce onun tipini belirtmek zorunda degiliz. Bu da
programcya daha az eforla daha kullanli kod yazmasnda yardm eder.

Numaralandrclarn Davran :Visual Basic. NET,Enumeration tipleri kullanmak


gerektiginde .NET ortami sezgiyle bunu programciya getirir.

Varsaylan public eriimi :Visual Basic.NET snfinn yele elemanlar varsaylan


olarak public olduu iin programclara sezgisel gc fazla olan bir zellik sunar.

Shared ye elemanlarn kullanma :Shared(C# taki static) ye elemanlarna hem


snfn ismi zerinden hem de ilgili snf nesnelerinden eriilebilir. Bu da programciya daha
esnek bir yap sunar. rnein

Dim x as new MyClass

x.SharedMethod() ' ile birlikte


MyClass.SharedMethod()

ifadesi de geerlidir.

Opsiyonel parametreler : Visual Basic.NET programclar nesne ynelimli


programlama tekniinin btn nanslarn bilmeye gerek kalmadan esnek snf yaplar
tasarlayabilir. rnein snf tasarmclar opsiyonel parametreleri kullanarak daha esnek
snflar tasarlayabilirler.

Filtrelenmi catch bloklar :VB.NET istisnai durumlar ele elmada esnek bir yap
sunar. Filtrelenmi catch bloklar sayesinde programclar hatalar, hata numarasna gre,
istisnannn trne gre yada herhangi bir koullu ifadeye gre filtreleyebilirler.

Parametreli zellikler : Visual Basic.NET te zellikler C# taki karlndan farkl


olarak parametreli olabilir. Bylece zellikler daha esnek bir yap sunmu olur.

Declarative event handlers : Visual Basic.NET'te olaylara iliikin metotlar bildirirken


Handles anahtar szc kullanlr.

Arayz ye elemanlarnn yeniden bildirilmesi : VB.NET'te implemente edilen bir


arayzn ye elemannn ismi arayz uygulayan snf tarafndan deitirilebilir.

VB.NET Gelitirme Ortamna Has zellikler

Visual Basic.NET programclara daha ok yarar salayacak bir tasarma, uygulama ve


servis yazmakta kolay bir ortam salar. Bu sadece Visual Basic.NET'i degil tm .NET
platformunu kapsar.

Arka planda kodun derlenmesi : Gelitirme ortam siz alrken arka planda kodunuzu
derler ve eer kodda hata varsa bunu size listeler.

Visual Basic . NET otomatik olarak yazdnz kodu dzenler ve kaydeder. Otomatik olarak
dzenlerken kodun durumu , anahtar szcklerin durumunu ve deiskenleri hizalayabilir.
Bu da ok fazla ifadenin kullanld durumlarda yanl ifadelerin yada formatsz ifadelerin
dzgn grlmesini salar.

Performans

Son nemli nokta performanstr.Visual Basic . NET derleyicisinin rettii ara kod, C#
derleyicisinin rettii IL kodu ile ayn performansa sahiptir.

Visual C+ +

ounlukla yazd programlardan g beklentisi olan programclarn bu platformun tm


zelliklerinden faydalanmas mmkndr.CLR ve . NET altyapsnn pek ok faydalarna
ramen, baz programclar hala uygulamalar gelitirirken, Windows iletim sisteminin
tm genilik ve derinliklerine gvenerek uygulamalarn olutururlar. Geleneksel olarak
programclar, sistem verimliliini en iyi kullanan kodu yazmak sistem tarafndan salanan
kaynaklara(disk,hafza) en etkili eriimi salamak amacyla Visual C++ ortamn
semilerdir. Visual C++.NET bu geleneksel yntemlerin devamn salamay
hedeflemitir. Tabi bunu yaparken Win32 API den sklkla faydalanr. C++.NET ayn
zamanda .NET Framework ve ynetilebilir CLR nin bir ok imkanna erimeyi de salar.

G Ynelimli(Power-Oriented) Gelitirme
Bir ok durumda gelitiriciler, iletim sisteminin salad btn imkanlara erimek
isterler. Microsoft, bu imkanlardan soyutlanm yada tamamen bu imkanlar zerine
kurulmu deiik aralar tasarlamtr. Bugn itibariyel .NET framework salam uygulama
gelitirmek iin bu imkanlarn birounu sunarken yinede iletim sisteminin btn
yeteneklerini iinde barndrmaz. G ynelimli(Power-Oriented) gelitirme aralar,
programclara bu dilin tm zelliklerinin yannda, uygulamann gerektirdii zmlerin de
kolayca zme kavuabilecei ktphaneleri salar.

Hangi Programclar Neden VB.NET'i Semelidir?

Visual C++, aadaki tipteki programclar iin ideal bir dildir.

Win32 tabanl bileen ve uygulama gelitirmek isteyen programclar :


Gnmzde programclarn bir grubu, native windows tabanl uygulamalar yapmaya
ihtiyac vardr. Bu programclar bu tr uygulamalar iin Win32 API yi ve native(doal) C++
ktphanelerini kullanrlar. Visual C++.NET 2003, bu tr uygulamalarn performansn
daha iyi ynde etkileyebilrcek bir takm derleme parametrelerine sahiptir.

Win32 tabanl uygulamalar ve .NET ile gelitirilmi uygulamar arasndaki


boluu doldurmak isteyen programclar : Halihazrda yazlm olan bir ok
uygulama, karmak kodlar yznden, zaman, cret veya bir ok nedenden dolay .NET
Framework kullanlarak yeniden yazlamayabilir. Visual C++ ile programclar, var olan
uygulamalarnn genileterek devamn .NET Framework ats altnda gelitirebilirler.
stelik daha karmak bir WinAPI altyapsn da kullanma imkanna kavuurlar. Microsoft
C# ve ya Visual Basic Windows API lerine eriimi salarken, C++'a kars bir rakip olarak
tasarlanmad.

Uygulamalarn ana olarak performans ile ilgilenen programclar : Uygulama


tasarmnda ve altrlmasnda C++ gelitiriciye geni bir kontrol imkan sunar. leri
dzey gelitiriciler C++ kullanarak dier dillerde gelitirebilecekleri
uygulamalardan(native Windows yada .NET tabanl) daha hzl ve etkili alan uygulama
tasarlayp implemente edebilirler.

Farkl platformlar arasnda alabilecek program gelitirmek isteyen


programclar : Yalnzca C++ dili ISO standartlarn ierir ve gerekten tanabilir
sentaks, her sistemde alabilecek bir yap ierir. Visual C++.NET 2003'n geniletilmi
standart uyumluluunu salarken ayn zamanda programclara ileri seviye dil zelliklerini
ve bir ok iletim sisteminde bulunan popler snf ktphanelerini kullanma imkan
sunar.

C++.NET Diline Has zellikler

Visual C++. NET, ileri dzey yazlmclar tarafndan byk bir taleple karlan kendine has
bir takm zelliklere sahiptir. Bu zelliklerin hepsi C++.NET'i .NET dilleri arasnda en gl
klmaya yetmektedir.

ablonlar(Templates) : Byk lde C++ diline has olan ablonlar yeniden


kullanlabilirlii ve performans art gibi bir ok nemli zellii salamaktadr.

Gstericiler(Pointers) : Gstericiler, C + + gelitiricilerine makinenin yerel hafzasna


dorudan eriebilmesini salar ve bylece en yksek seviyede performans elde edilir.

oklu Tretme(Multiple Inheritance) : C++, hemen hemen tm OOP desenlerini


implemente etmeyi salayan ve btn OOP zelliklerini uygulamaya geirecek zelliklere
sahiptir. oklu tretme de bu zelliklerden biridir.
Intrinsics : Intrinsics'ler, geleneksel programlama tekniklerinde olmayan bir takm
yeni zelliklere erimeye imkan sunar. rnein MMX ve AMD 3D Now! registerlar ve
komutlar.

C++.NET Gelitirme Ortamna Has zellikler

Visual C++.NET 2003 gelitirme ortamda daha esnek ve daha gelimi uygulamalar
gelitirmek iin bir takm zellikler salar.

Derleyiciyi optimize etmek : Visual C++ derleyicisi bir ok gelitirme seneryosu iin
derleme ilemini optimize edebilir. Bu seneryolardan bir ka : MSIL retimi, kodun
alca sisteme zgn optimizasyon, floating say hesaplamalarnn youn olduu
derlemeler.

alma zaman kod gvenlii kontrol : Programclar kt niyetli ataklara kar


derleyicinin ileri seviye zelliklerini kullanarak daha gvenli Windows tabanl uygulamalar
gelitirebilirler.

32 bit ve 64 bit destei : Visual C++.NET derleyicisi 32 ve 64 bitlik Intel ve AMD


mikroilemcilerine ve ynelik gml mikrpilemcilere ynelik leklenebilir kod
retebilmektedir.

leri dzey hata raporlama : Uygulamalar daima programclarn hatalarndan


etkilenirler. Minidump teknolojisiyle Visual C++ gelitirme ortam, uygulama gelitirme
uzmanlarna hatalarn kolayca belirlenmesine yardmc olur. stelik derlenmi kodda bile
bu hatalar kolaylkla rapor edilebilir.

Gelimi hata ayklama(debug) : Visual Studio hata ayklaycs ayn anda hem
native hemde ynetilebilir kodda hata ayklama desteini benzer bir ekilde sunar.

Gelecekte, Visual C + + . NET Programcilara yardim etmek iin daha gl zellikleri


ierecek.

Generics : Parametreli kod algoritmalarn yeniden kullanlabilirliini salamay


hedefleyen alma zaman(run-time) teknolojisi.

Ynetilen(Manage) tiplerde ablonlar : Derleme zaman C++ ablon sentaksnn


ynetilen(manage) tipler iinde kullanlabilmesi.

Visual C#

Geleneksel Olarak Visual Basic ve Visual C + + farkl spektrumdaki programclar


hedeflemitir. Visual Basic zellike retkenlii n plana karmas ile programclara daha
kolay ve sezgisel bir gelitirme modeli sunuyordu. te yandan Visual C++, retkenlii
azaltyor gibi grnmesine ramen Windows iletim sisteminin btn zelliklerini etkili bir
ekilde kullanma imkan tanyordu.

Bu iki dilin sunduu imkanlar arasndaki boluu doldurmak iin Microsoft kod odakl
uygulama gelitirmeyi modern ve yeniliki bir tazrda ele alan C# dilini gelitirdi. C#, C++
szdizimine benzer bir ekilde temiz ve gzel bir programlama dili sunarken ayn
zamanda Visual Basic dilinin retkenliinide korur.

Kod Odakli Gelitirme


Programclarn hepsi projelerinde mutlaka belli zelliklerde kod yazarlar. Fakat
programclarinin ou zamanlarnn nemli bir ksmn sihirbaz(wizard),kontrol ve tasarm
aralar kullanarak harcarlar ve bylece nemli lde bir retkenlik salarlar. Bu zelliin
programclar iin tek kt yan sihirbaz tarafindan retilen kodun anlalabilirliinin az
olmasdr.Fakat programclar kodlarnda anlalrlk ve verimlilik arasindaki tercihlerinde
gveni tercih ettiler.

Ayrca kod odakl gelitirme yapan programclar bakalar tarafindan doru tasarlanm
kodu yeniden yazmaya ynelir ve bu daha az bilgili programclarn pratik olarak iyi kod
gelitirebilmesindeki karmakl dzeltir.

Hangi Programclar Neden VB.NET'i Semelidir?

Gelecek kuak uygulamalar ve servisleri birletirerek .NET ortamnda aratrma yapmak


isteyen aadaki tipteki programclar iin C# ideal bir dildir.

retkenlik arayan C/C++ ailesindeki diller ile gelitirme yapan


programclar :C# dili, C++ dili gibi isle(operator) ar yklerken buna ek olarak
numaralandrmalar, kk-byk harf duyarll ve component-oriented(bilesen-
ynelimli) zellikler olan property,delegate, events ve daha fazlasini ierir. C#, .NET
framework ile beraber yksek verimlilik ,ynetilebilir , daha gvenli ve anlalabilir
szdizimi ile yeni zellikler isteyen C++ programclarna sunulmu bir dil olarak da
dnlebilir.

Framework tasarmclar ve yazlm mimarlari : Framework tarafindan iyi


desteklenen , isle ykleme zellikleri ieren, gvenli olmayan kodlara ve nceden
yazlm yazlmlara eriimiyle C#, yazlm mimarlarna geni ve esnek ktphaneler ve i
paracklar tasarlama imkan salar.

Java tabanl yazlmlar gelitirmi programclar : Java Language Conversion


Asistant (JLCA) ile Java programclar uygulamalarn C# ve .NET Frameworke'e rahatlkla
tayabilirler. JLCA kaynak kod seviyesinde bir analiz yapar ve Java kodunu C# koduna
dntrr. Dntrme ilemi bittiinde gelitiricinin dikkat etmesi gereken noktalar
belirtilir. Bylece tama ilemi an az hasarla geekletirilmi olur.

C#'n C ++ Diline Benzer olan zellikleri

C# dili, geleneksel C++ zelliklerinin bir ounu desteklemektedir. Bu geleneksel


zelliklerin bir ou Visual C++ 'taki retkenlii artrmak iin de kullanlmtr.

Tm CLR trleri iin destek : C# dili tm CLR veri tiplerini destekler , programclar
zm sunarken .NET ortamnn ynetilen alma ortamnn tm zelliklerinden
yararlanrlar.

Referens yolu ile parametre aktarma ve out parametresi : C# programclar,


parametreleri foksiyonlara referans yolu ile aktarabilirler ayrca out parametresi ile
deikenlere ilk deer vermeden onlar fonksiyonlara parametre olarak geirebilirler.

Overloading (Operatr ar ykleme) : Snf ktphanesi tasarmclar operatrleri


ar ykleyerek daha salam snflar tasarlayabilirler.

Using ifadesi : Programclar, uygulamalarnda bulunan kaynaklar daha kontroll bir


ekilde ynetebilmek iin using anahtar szcn kullanrlar.
Guvensiz kod(Unsafe code) : C#, programclara gsterici kullanma imkan tanyarak
hafzaya direkt eriimi salar. Her ne kadar gvensiz kodda CLR ynetiminde olsa da ileri
dzey programclar uygulamalarnn hafza ynetimi zerinde sz sahibi olmalar iin
gvensiz kod yazabirler. Buna ramen hafza zerinde daha etkili bir kontrol iin Visual
C++ kullanlmas daha ok tavsiye edilir.

XML dkmantasyonu : Programclar, kodlarna aklayc notlar eklemek iin XML


formatndaki bildirimleri kullanabilirler.

te yandan C# dil tasarmnn snrlarn geniletecek ekilde hzla bymektedir. C#


dilinin tasarmclar yakn bir gelecekte dile eklemeyi planladklar bir ka nemli zellikten
bahsetmektedir. Daha modern ve yeniliki bir yaklam sunan bu zellikle unlardr :

Generics : Varolan kodlarn yeniden kullanlabilirliini kolayca salayan C++


ablonlarna benzer bir yap.

Eriiciler (Iterators) : Koleksiyon tabanl snflarn elemanlar arasnda daha hzl ve


kolay bir ekilde dolamamz salayacak yap.

Anonim(Anonymous) Metotlar : Basit grevleri temsilcilerle daha rahat bir ekilde


ele alacak yntem

Ksmi(partial) Trler : Bir kodu farkl dosyalara blebilecek trler.

Visual J #

Microsoft, Visual J# dili ile JAVA dilini .NET ortamna sokmu oldu. Microsoft Java diline
.NET ortamnn pratikliini getirdi ve okullarda mfredatlar olan programclara,
grencilere, ve profesrlere Java yapsn muhafaza ederek onlarn .NET e hzl bir ekilde
girmelerini salad. Ayrca J# dili windows tabanl uygulama gelitiren Visual J++ 6.0
kullanclarna kolayca Visual J# .Net ortamna geebilmelerinde kolaylklar sagladi.

Java Gelitirme Ortam

C++ gelitiricilerin sklkla karlatklar problemler etkili ve kolay bir sentaks yaps ayn
zamanda benzer OOP fonksiyonelitesi ile JAVA ile giderilmitir.Java ile uygulama
gelitirenlerin .NET ortamnda uygulama gelitirenilmeleri iin en uygun dil J# olarak
grlmektedir. Java programclar dil deitirmek zorunda kalmadan .NET framework teki
btn olanaklardan hzl bir ekilde faydalanma imkanna kavumutur.

Hangi Programclar Neden VB.NET'i Semelidir?

Visual J#, aadaki tipteki programclar iin ideal bir dildir.

Java-dili gelitiricileri : Daha nceden Java dilini kullanan bir programc .NET e
geerken bska bir dili renmek istemeyebilir. Visual J#, .NET platformunun getirdii
zellikler ile java programclarnn bilgilerini kullanabildikleri rahat ve hzl bir platform
sunar.

Visual J++ ile kod gelitiren programclar : Visual J# ortam varolan Visual J++
uygulamalarn .NET ortamna sorunsuzca tayabilir ve bylece Visual J#.NET kullanmaya
baslayan programclar projelerinde .NET alt yapsnn getirdii pratiklii ve rahatl
hemen farkederler.
grenciler, gretmenler, ve profsrler : renciler ve retmenler Computer
Science derslerinde Java dilinin basitliinden faydalanmak iin Visual J#.NET dilini
kullanabilirler. Visual J#.NET, ileri bilgisayar bilimin btn gerekliliklerini karlar.

J#.NET Diline Has zellikler

Bir ok dilde bulunan zelliklerin ogunu yapsnda ieren J#, daha rahat ve bildik yaps
ile deneyimli Java gelitiricileri iin .Net Framework'e ynelik uygulamalar gelitirmek iin
ideal bir dildir.

Java dilinin sz dizimi : Java gelitiricileri bildik bir dil yaps ile karlacak ve ayn
zaman .NET in tm imkanlarndan faydalandklarn grecekler.

Snf ktphanesi destei : Bamsz olarak gelitirilen ve bir ok zellii sunan Java
1.1.4 JDK versiyonundaki ktphane ile JDK 1.2 java.util de bulunan hemen hemen
btn snflar ierir.

zellikler, temsilciler(delegates) ve olaylar(events) : .NET geleneksel JAVA sz


dizimi ile .NET'in gl zelliklerinden olan event ,delegate, ve property yaplarn
destekler.

Javadoc Yorumlar : J#, Javadoc kolarndaki yorumlama stilini destekler. Visual J# .


NET, kullanclarn HTML API belgesini yaratabilmesine olanak klar.

Visual J#.NET Gelitirme Ortamna Has zellikler

Visual J#.NET direkt olarak Visual Studio.NET gelitirme ortamna entegre bir ekilde
alr. Dolaysyla tasarlama aralar, editrler ve hata ayklayclar Visual J# gelitirme
ortamnda rahatlkla kullanlabilir. Ayrca hazlihazrdaki JAVA programclarnn .NET'e
geiini kolaylatracak bir takm aralar da vardr.

Visual J++ Upgrade Wizard : Visual J++ gelitiricileri projelerini Visual J# ortam
iin upgrade edebilirler. Bu sihirbaz proje dosyalarn evirir ve olas potansiyel sorunlar
iin kullancy bilgilendirir.

Ikili dnstrc : Bu ara, Java byte kodunu, .NET uygulamalarnda kullanmak


zere MS.NET assembly lerine dntrr.

zet

Programlama dilleri fakli zmler iin kullanlabilmektedir. Her dil kendi zelliklerini ve
belirli bir uygulamann ihtiyalarn karlayabilecek en uygun ortam ierir. Microsoft
geni bir dil seeneini sunduu gelismi .NET yaps ile yazlm uygulamalarnda daha
salam ve fonksiyonalite salam bulunmakta.
C#'ta Params ile Deiken Sayda Parametre ile alma

Bu makalemizde, C# metodlarnda nemli bir yere sahip olduunu dndm params


anahtar kelimesinin nasl kullanldn incelemeye alacaz. Bildiiniz gibi metodlara
verileri parametre olarak aktarabiliyor ve bunlar metod iersinde ileyebiliyoruz. Ancak
parametre olarak geirilen veriler belli sayda oluyor. Diyelimki saysn bilmediimiz bir
eleman kmesini parametre olarak geirmek istiyoruz. Bunu nasl baarabiliriz? te
params anahtar szc bu noktada devreye girmektedir. Hemen ok basit bir rnek ile
konuya hzl bir giri yapalm.

using System;

namespace ParamsSample1
{
class Class1
{
/* burada Carpim isimli metodumuza, integer tipinde deerler geirilmesini
salyoruz. params anahtar bu metoda istediimiz sayda integer deer geirebileceimizi
ifade ediyor*/ public int Carpim(params int[] deger)
{
int sonuc=1;

for(int i=0;i<deger.Length;++i) /*Metoda gnderilen elemanlar doal olarak bir


dizi olutururlar. Bu dizideki elemanlara bir for dngs ile kolayca eriebiliriz. Dizinin
eleman saysn ise Length zellii ile reniyoruz.*/
{
sonuc*=deger[i]; /* Burada metoda geirilen integer deerlerin birbirleri ile
arplmasn salyoruz*/
}

return sonuc;
}

static void Main(string[] args)


{
Class1 cl=new Class1();
Console.WriteLine("1*2*3*4={0}",cl.Carpim(1,2,3,4)); /* Burada Carpim isimli
metoda 4 integer deer gnderdik. Aadaki kodda ise 2 adet integer deer
gnderiyoruz.*/

Console.WriteLine("8*5={0}",cl.Carpim(8,5));
Console.ReadLine();
}
}

}
Bu rnei altracak olursak, aadaki sonucu elde ederiz.

ekil 1. Ilk Params rneinin Sonucu

Peki derleyici bu ilemi nasl yapyor birazda ondan bahsedelim. Carpim isimli metoda deiik saylarda parametre
gnderdiimizde, derleyici gnderilen paramtetre says kadar boyuta sahip bir integer dizi oluturur ve du dizinin
elemanlarna sras ile (0 indexinden balayacak ekilde) gnderilen elemanlar atar. Daha sonra ayn metodu bu
eleman says belli olan diziyi aktararak arr. cl.Carpim(8,5) satrn dnelim; derleyici,

lk admda,

int[] dizi=new int[2] ile 2 elemanl 1 dizi yaratr.

kinci admda,

dizi[0]=8

dizi[1]=5 eklinde bu dizinin elemanlarn belirler.

Son admda ise metodu tekrar arr.

cl.Carpim(dizi);

Baz durumlarda parametre olarak geireceimiz deerler farkl veri tiplerine sahip olabilirler. Bu durumda params
anahtar szcn, object tipinde bir dizi ile kullanrz. Hemen bir rnek ile grelim. Ayn rneimize Goster isimli
deer dndrmeyen bir metod ekliyoruz. Bu metod kendisine aktarlan deerleri console penceresine yazdryor.

public void Goster(params object[] deger)


{
for(int i=0;i<deger.Length;++i)
{
Console.WriteLine("{0}. deerimiz={1}",i,deger[i].ToString());
}

Console.ReadLine();
}

static void Main(string[] args)


{
cl.Goster(1,"Ahmet",12.3F,0.007D,true,599696969,"C");
}

Grld gibi Goster isimli metodumuza deiik tiplerde(int,Float,Decimal,bool, String) parametreler


gnderiyoruz. te sonu;
ekil 2. params object[] kullanm.

imdi dilerseniz daha ie yarar bir rnek zerinde konuyu pekitirmeye alalm. rnein deiik sayda tabloyu
bir dataset nesnesine yklemek istiyoruz. Bunu yapcak bir metod yazalm ve kullanalm. Programmz, bir sql
sunucusu zerinde yer alan her hangibir databasee balanp istenilen saydaki tabloyu ekranda programatik
olarak oluturulan dataGrid nesnelerine ykleyecek. Kodlar inceledike rneimizi daha iyi anlyacaksnz.

ekil 3. Form Tasarmmz

Uygulamamz bir Windows Application. Bir adet tabControl ve bir adet Button nesnesi ieriyor. Ayrca params
anahtar szcn kullanan CreateDataSet isimli metodumuzu ieren CdataSet isimli bir classmzda var. Bu
classa ait kodlar yazarak iimize balayalm.

using System;
using System.Data;
using System.Data.SqlClient;

namespace CreateDataSet
{
public class CDataSet
{

/* CreateDataSet isimli metod gnderilen baglantiAdi stringinin deerine gre bir


SqlConnection nesnesi oluturur. tabloAdi ile dataset nesnesine eklemek istediimi tablo
adlarini bu metoda gndermekteyiz. params anahtar kullanld iin istediimiz sayda
tablo ad gnderebiliriz. Elbette, geerli bir Database ve geerli tablo adlar
gndermeliyiz.*/

public DataSet CreateDataSet(string baglantiAdi,params string[] tabloAdi)


{
string sqlSelect,conString;
conString="data source=localhost;initial catalog="+baglantiAdi+";integrated
security=sspi"; /* Burada SqlConnection nesnesinin kullanaca connectionString'i
belirliyoruz.*/
DataSet ds=new DataSet();/* Tablolarimizi tayacak dataset nesnesini
oluturuyoruz*/
SqlConnection con=new SqlConnection(conString); /*SqlConnection nesnemizi
oluturuyoruz*/
SqlDataAdapter da;/* Bir SqlDataAdapter nesnesi belirtiyoruz ama henz
oluturmuyoruz*/

/*Bu dng gnderdiimiz tabloadlarn alarak bir Select sorgusu oluturur ve


SqlDataAdapter yardmyla select sorgusu sonucu dnen tablo verilerini oluturulan bir
DataTable nesnesine ykler. Daha sonra ise bu DataTable nesnesi DataSet nesnemizin
Tables kolleksiyonuna eklenir. Bu ilem metoda gnderilen her tablo iin yaplacaktr.
Bylece dng sona erdiinde, DataSet nesnemiz gndermi olduumuz tablo adlarna
sahip DataTable nesnelerini iermi olucaktr. */

for(int i=0;i<tabloAdi.Length;++i)
{
sqlSelect="SELECT * FROM "+tabloAdi[i];
da=new SqlDataAdapter(sqlSelect,con);
DataTable dt=new DataTable(tabloAdi[i]);

da.Fill(dt);
ds.Tables.Add(dt);
}

return ds; /* Son olarak metod arld yere DataSet nesnesini


gndermektedir.*/
}

public CDataSet()
{
}
}
}

imdi ise btnYukle isimli butonumuzun kodlarn yazalm.

private void btnYukle_Click(object sender, System.EventArgs e)


{
CDataSet c=new CDataSet();
DataSet ds=new DataSet();
ds=c.CreateDataSet("northwind","Products","Orders");

for(int i=0;i<ds.Tables.Count;++i)
{
/* tabControl'umuza yeni bir tab page ekliyoruz.*/
tabControl1.TabPages.Add(new
System.Windows.Forms.TabPage(ds.Tables[i].TableName.ToString()));
/* Oluturulan bu tab page'e eklenmek zere yeni bir datagrid oluturuyoruz.*/
DataGrid dg=new DataGrid();
dg.Dock=DockStyle.Fill;/*datagrid tabpage'in tamamn kaplyacak*/
dg.DataSource=ds.Tables[i]; /* DataSource zellii ile DataSet te i indexli tabloyu
balyoruz.*/
tabControl1.TabPages[i].Controls.Add(dg);/* Oluturduumuz dataGrid nesnesini TabPage
stnde gstermek iin Controls koleksiyonunun Add metodunu
kullanyoruz.*/
}
}

imdi programmz altralm. te sonu;

ekil 4. Tablolarn yklenmesi.

Grld gibi iki tablomuzda yklenmitir. Burada tablo saysn arttrabilir veya azaltabiliriz. Bunu params
anahtar kelimesi mmkn klmaktadr. rnein metodomuzu bu kez 3 tablo ile aralm;

ds=c.CreateDataSet("northwind","Products","Orders",Suppliers);

Bu durumda ekran grntmz ekil 5 teki gibi olur.


ekil 5. Bu kez 3 tablo gnderdik.

Umuyorumki params anahtar szc ile ilgili yeterince bilgi sahibi olmusunuzdur. Bir sonraki makalemizde
grmek dileiyle hepinize mutlu gnler dilerim.
C#'ta zyenilemeli Algoritmalar (Recursion)

zyenilemeli algoritmalar tm dnyada bilgisayar bilimleriyle ilgili blmlerde veri yaplar


ve algoritmalar derslerinde detayl olarak incelenir. Bu balamda biz de makalemizde
zyenilemeli algoritmalar gelitirmeyi ve C# ile kodlamay reneceiz. nce konunun
teorik temelleri zerinde duracaz. Daha sonra daha iyi anlalabilmesi iin konu ile ilgili
rnekler yapacaz. Makaleyi bitirmeden nce ise klasik dngler ve zyenilemeli
algoritmalar karlatracaz.

Bir alogirtma gelitirirken genelde dngleri ve karar mekanizmalarn metodlarn iinde


kullanrz. Fakat baz durumlarda dngler yerine zyenilemeli algoritmalar kullanmak
daha kolay ve anlalr olabilir. zyenilemeli (recursive) metodlarn pf noktas bu tr
metodlarn bir ekilde tekrar tekrar kendilerini armalardr.

zyenilemeli algoritmalarda problemin en basit hali iin zm bulunur. Bu en basit


duruma temel durum (base case) denir. Eer metod temel durum iin arlrsa
sonu dnderilir Daha karmak durumlar iin metod, temel durumdan yararlanlarak,
problemi zmeye alr yani kendini arr. Karmak durumlar iin yaplan her ar
recursion step olarak adlandrlr.

sterseniz konunun kafanzda daha iyi canlanmas iin klasik faktoriyel rneiyle devam
edelim. Sfrdan byk herhangi bir n tamsaysnn faktoriyelinin forml udur:

n! = n * (n-1) * (n-2) * .... * 3 . 2 . 1

Ayrca 0! ve 1!'in deerleri bir olarak tanmlanmtr. Mesela 5! = 4*3*2*1 =


120'dir.

Bir saynn, mesela n, faktoriyelini zyenilemeli deilde dng kullanarak bulmak istersek
aadakine benzer bir kod kullanabiliriz:

int faktoriyel = 1;

for( int i = n; i >= 1; i-- )


faktoriyel *= i;
Kod 1: Dng ile Faktoriyel hesab

Eer bu problemi zyenilemeli algoritma yardmyla zmek istersek u noktaya dikkat


etmemiz gerekiyor:

n! = n * (n-1)!

Daha ak bir yazm ile;

5! = 5 * 4 * 3 * 2 * 1

5! = 5 * (4 * 3 * 2 * 1)

5! = 5 * (4!)
Aada ekilde 5!in zyenilemeli bir algoritmada nasl hesablanacan gryoruz. eklin
solunda 5!'den 1!'le kadar her zyenilemeli ardaki neyin arlaca sada ise sonuca
ulalana kadar her arda dnen deerler yeralyor.

C# diliyle zyenilemeli biimde Faktoriyel hesab yapan bir metodu aadaki gibi
yazabiliriz. Bu fonksiyona int tipinde sayi isimli bir deiken geiriyoruz. Eer sayi 1'den
kk veya eit ise, ki bu temel durumdur, fonksiyon 1 deerini dnderiyor. Dier
durumlarda ise fonksiyonumuz

sayi * Faktoriyel(sayi-1)

deerini dnderiyor.

private static long Faktoriyel(int sayi)


{
if( sayi <= 1 ) // Eer temel durumsa 1 dnder
return 1;
else // Temel durum deilse n * (n -1)! bul.
return sayi * Faktoriyel( sayi-1 );
}

Kod 2: zyenileme ile Faktoriyel hesab

Sra rneimizi bir Windows uygulamas olacak biimde programlayalm. Bunun iin
ncelikle aada grdmz Form'u tasarlayalm. Metin kutusuna txtSayi ve dmeye
btnHesapla isimleri vermeyi unutmayalm.
Formdaki btnHesapla isimli dmeye ift tklayalm dmenin Click olayna cevap veren
metodu yazalm.

private void btnHesapla_Click(object sender, System.EventArgs e)


{
string sonucMetin="";

// metin kutusundan deeri al ve int tipine evir:


int sayi = Convert.ToInt32(txtSayi.Text);

for(int i=1; i<= sayi; i++)


sonucMetin += i + "!= \t" + Faktoriyel(i).ToString() + "\n";

MessageBox.Show(sonucMetin.ToString(),"Faktoriyel Hesab");
}

Kod 3: rnek programda btnHesapla_Click() metodu

Yukardaki metod iinde metin kutusuna girilen sayi deerine kadar olan tm
faktoriyeller hesaplanp ekrana mesaj kutusu iinde yazdrlyor. Programmz
altrmadan nce programmza Kod 2'de yeralan metodu da eklemeyi unutmaynz.
rneimizi 10 deeri iin altrrsak aadaki sonucu elde ederiz:

zyenilemeli Algoritma rnei: Fibonacci Serisi

Lise ve niversitelerde matematik derslerinde seriler konusunda gsterilen Fibanocci


serilerini programlamak iin dngler yerine zyenilemeli algoritma kullanmak daha kolay
ve anlalr oluyor. Bu serinin tanm ise herhangi bir n says iin Fibonacci(n)'nin deeri
Fibonacci(n-1) ve Fibonacci(n-2)'nin eklindedir. Tabiki Fibonacci(0) ve Fibonacci(1)'in
deeri 1 olarak alnyor.

Bu serideki saylar doada ok sayda bulunur ve spiral eklini olutururlar. Ayrca art
arda gelen iki Fibonacci deerinin oran 1.68.. eklindedir. Bu deer altn oran olarak
adlandrlr. zellikle kart postallar, tablolar vb nesnelerin boy ve enlerinin oranlar da
1.68.. gibidir. nk insan gzne ok ho grnrler. Neyse konumuza devam edelim
isterseniz...

Yukardaki tanmlardan yola karak Fibonacci serisini hesaplayan metod'ta iki temel
durum olacaktr. Bunlar Fibonacci(0) = 1 ve Fibonacci(1) = 1. Ayrca dier durumlar iin
dnen deer, herhangi bir n iin, Fibonacci(n-1) ve Fibonacci(n-2)'nin toplamdr. O
zaman metodumuz aadaki gibi olacaktr:

private static long Fibonacci(int sayi)


{
if( sayi == 0 || sayi == 1) // Eer temel durumlardan biriyse 1 dnder
return 1;
else // Temel durum deilse (n-1) + (n -2) bul.
return Fibonacci( sayi-1 ) + Fibonacci( sayi-2 );
}

Kod 4: zyenileme ile Fibonacci serisi hesab

Fibonacci serisi ile ilgili aadaki kk formu tasarlayalm. Sonra gerekli kodlar yazp
rneimizi deneyelim. Formdaki metin kutusunun ismi yine txtSayi olsun. Ayrca Hesapla
etiketine sahip dmenin ismi btnHesapla olsun. Son olarak arka plan koyu krmz olan
etiketin ismi de label2 olacak.

Program tamamlamak iin Hesapla dmesinini tklandnda gerekli ileri yapacak kodu
yazmaya geldi. Ayrca programn kodunun iine Kod 4 yeralan fonksiyonu da ekleyiniz.

private void btnHesapla_Click(object sender, System.EventArgs e)


{
// Kullancn girdii deeri al ve int tipine evir.
int sayi = Convert.ToInt32(txtSayi.Text);

// Fibonacci Hesab yapan fonksiyonu girilen sayi deeri ile ar.


// Sonucu label2'ye yazdr.
label2.Text =Fibonacci(sayi).ToString();
}

Kod 5: Fibonacci rneinde btnHesapla_Click() metodu

Program test etmek iin Fibonacci(15) deerini bulmak istersek aadaki sonucu elde
ederiz.
zyenilemeli Algoritma rnei: Fibonacci Serisi

Makalemizi bitirmeden nce zyenilemeli algoritmalar ile dnglerden oluan


algoritmalarn aralarndaki farklara ve benzerlikte gzatmakta yarar olduu kansndaym.
ki algoritma tr de ak kontrol mekanizmlarn kullanr. Dnglerde for, while ve do
while yaplar kullanlrken zyenilemeli algoritmalarda if, if/else ve switch yaplar
yeralr. Aslnda hem dngler de hem de zyenilemeli metodlarda itereasyonlar bulunur.
Dngler doalar gerei ak bir biimde iteratiftirler. Fakat zyenilemeli algoritmalarda
iterasyon ayn metodun tekrar tekrar kendi iinden arlmas ile gerekleir. Dngl ve
zyenilemeli algoritmalarda gze arpan dier bir benzerlikte sonladrc testlerin
bulunmasdr. Dnglerde sayacn(counter) belli bir deere ulap ulamad kontrol
edilir ve gerekirse dng sonlanr. zyenilemeli algoritmalarda o andaki durumun temel
durum olup olmamasna gre ilemler devam edebilir veya sonlanabilir. Son olarak hem
dnglerle hem de zyenilemeli algoritmalar ile bilgisayar sonsuz dngye(infinite loop)
sokabiliriz. Birincisi dngnn sonlanaca sayaca ulamann imkansz olmasndan ikincisi
ise temel duruma ulaamamaktan kaynaklanr.

Aslnda zyenilemeli algoritmalar kullanrsak hem daha yava hem de hafzada daha ok
yer kaplayan programlar yazm oluruz. Fakat ou zaman ayn problemin mn
zyenilemeli olarak bulmak daha kolaydr. Ya da dnglerle ayn sonuca varacak
algoritmay dnmek zor olur. Ayrca zyenilemeli algoritmalar inceleyince anlamak ve
hata ayklamak daha kolaydr. Bu durumda seim programcya kalmtr. Yalnz
ilemcilerin giderek hzlanmas, hafza fiyatlarndaki d ve programn daha kolay
ynetilebilmesinin getirdii avantajlar gz nne almanz tavsiye ederim.

Bu makalede zyenilemeli algoritmalar detaylar ile inceledik. Konu ile ilgili sorularnz
rahatlkla sorabileceinizi belirterek makalemize son verelim.
Struct(Yap) Kavram ve Class(Snf) ile Struct(Yap) Arasndaki
Farklar

Bu makalemizde struct kavramn incelemeye alacaz. Hatrlayacanz gibi, kendi


tanmladmz veri trlerinden birisi olan Numaralandrclar (Enumerators) grmtk.
Benzer ekilde dier bir veri tipide struct (yap) lardr.

Yaplar, snflar ile byk benzerleklik gsterirler. Snf gibi tanmlanrlar. Hatta snflar
gibi, zellikler,metodlar,veriler, yapclar vb... ierebilirler. Buna karn snflar ile yaplar
arasnda ok nemli farkllklar vardr.

Hereyden nce en nemli fark, yaplarn deer tr olmas ve snflarn referans tr


olmasdr. Snflar referans trnden olduklar iin, bellekte tutulu biimleri deer
trlerine gre daha farkldr. Referans tiplerinin sahip olduu veriler bellein bek(heap)
ad verilen tarafnda tutulurken, referansn ad stack(yn) da tutulur ve bekteki
verilerin bulunduu adresi iaret eder. Ancak deer trleri bellein stack denilen ksmnda
tutulurlar. Aadaki ekil ile konuyu daha net canlandrabiliriz.

ekil 1. Referans Tipleri

Aadaki ekilde ise deer tiplerinin bellekte nasl tutulduunu gryorsunuz.


ekil 2. Deer Tipleri

te snflar ile yaplar arasndaki en byk fark budur. Peki bu farkn bize salad
getiriler nelerdir? Ne zaman yap ne zaman snf kullanmalyz? zellikle metodlara veriler
aktarrken bu verileri snf ierisinde tanmladmzda, tm veriler metoda aktarlacan
sadece bu verilerin bekteki balang adresi aktarlr ve ilgili parametrenin de bu
adresteki verilere iaret etmesi salanm olur. Bylece byk boyutlu verileri stack'ta
kopyalayarak gereksiz miktarda bellek harcanmasnn nne geilmi olunur. Ancak
kk boyutlarda veriler ile alrken bu verileri snflar ierisinde kullandmzda bu
kezde gereksiz yere bellek kullanld bek ier ve performans der. Bu konudaki
uzman gr 16 byte'tan kk veriler iin yaplarn kullanlmas, 16 byte'tan byk
veriler iin ise snflarn kullanlmasdr.

Dier taraftan yaplar ile snflar arasnda baka farkllklarda vardr. rnein bir yap iin
varsaylan yapc metod (default constructor) yazamayz. Derleyici hatas alrz. Ancak bu
deiik sayda parametreler alan yapclar yazmamz engellemez. Oysaki snflarda
istersek snfn varsaylan yapc metodunu kendimiz yazabilmekteyiz.

Bir yap iersinde yer alan constructor metod(lar) iinde tanmlam olduumuz alanlara
balang deerlerini atamak zorundayz. Oysaki bir snftaki constructor(lar) iinde
kullanlan alanlara balang deerlerini atamaz isek, derleyici bizim yerimize saysal
deerlere 0, boolean deerlere false vb... gibi balang deerlerini kendisi otomatik
olarak yapar. Ancak derleyici ayn ii yaplarda yapmaz. Bu nedenle bir yap iinde
kullandmz constructor(lar)daki tanmlam olduumuz alanlara mutlaka ilk deerlerini
vermemiz gerekir. Ancak yinede dikkat edilmesi gereken bir nokta vardr. Eer yap
rneini varsaylan yaplandrc ile oluturursak bu durumda derleyici yap iinde
kullanlan alanlara ilk deerleri atanmam ise kendisi ilk deerleri atar. Unutmayn,
parametreli constructorlarda her bir alan iin balang deerlerini bizim vermemiz
gerekmektedir. rnein, aadaki Console uygulamasn inceleyelim.

using System;

namespace StructSample1
{
struct Zaman
{
private int saat,dakika,saniye;
private string kosucuAdi;

public string Kosucu


{
get
{
return kosucuAdi;
}
set
{
kosucuAdi =value;
}
}

public int Saat


{
get
{
return saat;
}
set
{
saat =value;
}
}

public int Dakika


{
get
{
return dakika;
}
set
{
dakika =value;
}
}

public int Saniye


{
get
{
return saniye;
}
set
{
saniye =value;
}
}
}

class Class1
{
static void Main (string[] args)
{
Zaman z;
Console.WriteLine ("Koucu:"+z.Kosucu);
Console.WriteLine ("Saat:"+z.Saat.ToString());
Console.WriteLine ("Dakika:"+z.Dakika.ToString());
Console.WriteLine ("Saniye:"+z.Saniye.ToString());
}
}
}

Yukardaki kod derlenmeyecektir. Nitekim derleyici "Use of unassigned local variable


'z'" hatas ile z yaps iin ilk deerlerin atanmadn bize syleyecektir. Ancak z isimli
Zaman yap trn new anahtar ile tanmlarsak durum deiir.

Zaman z;

Satr yerine

Zaman z=new Zaman ();

yazalm . Bu durumda kod derlenir. Uygulama altnda aadaki ekran grnts ile
karlarz. Grld gibi z isimli yap rneini new yaplandrcs ile tanmladmzda,
derleyici bu yap iindeki zelliklere ilk deerleri kendi atamtr. Kosucu isimli zellik iin
null, dier integer zellikler iin ise 0.

ekil 3. New yaplandrcs ile ilk deer atamas.

Yine nemli bir farkta yaplarda tretme yapamyacamzdr. Bilindii gibi bir snf
oluturduumuzda bunu baka bir temel snftan kaltm yolu ile tretebilmekteyiz ki
inheritance olarak geen bu kavram ilerliyen makalelerimizde ileyeceiz. Ancak bir
yapy baka bir yapy temel alarak tretemeyiz. imdi yukarda verdiimiz rnekteki
yapdan baka bir yap tretmeye alalm.

struct yeni:Zaman

satrlarn kodumuza ekleyelim. Bu durumda uygulamay derlemeye altmzda


aadaki hata mesajn alrz.

'Zaman' : type in interface list is not an interface

Bu belirgin farkllklarda inceledikten sonra dilerseniz rneklerimiz ile konuyu


pekitirmeye alalm.
using System;

namespace StructSample1
{
struct Zaman
{
private int saat,dakika,saniye;
private string kosucuAdi;

/* Yap iin parametreli bir constructor metod tanmladk. Yap iinde yer alan kosucuAdi,saat,dakika,saniye
alanlarna ilk deerlerin atandna dikkat edelim. Bunlar atamassak derleyici hatas alrz. */

public Zaman(string k,int s,int d,int sn)


{
kosucuAdi =k;
saat =s;
dakika =d;
saniye =sn;
}

/* Bir dizi zellik tanmlayarak private olarak tanmladmz asl alanlarn kullanmn kolaylatryoruz. */
public string Kosucu
{
get
{
return kosucuAdi;
}
set
{
kosucuAdi =value;
}
}

public string Saat


{
get
{
return saat;
}
set
{
saat =value;
}
}

public string Dakika


{
get
{
return dakika;
}
set
{
dakika =value;
}
}

public string Saniye


{
get
{
return saniye;
}
set
{
saniye =value;
}
}
}

class Class1
{
static void Main (string[] args)
{
/* Zaman yaps iinde kendi yazdmz parametreli constuructorlar ile Zaman yaps rnekleri
oluturuyoruz. Yaptmz bu tanmlamarn ardndan bellein stack blgesinde derhal 4 adet deiken oluturulur
ve deerleri atanr. Yani kosucuAdi,saat,dakika,saniye isimli private olarak tanmladmz alanlar bellekte stack
blgesinde oluturulur ve atadmz deerleri alrlar. Bu oluan veri dizisinin adda Zaman yaps tipinde olan
Baslangic ve Bitis deikenleridir. */

//

Zaman Baslangic=new Zaman ("Burak",1,15,23);

Zaman Bitis=new Zaman ("Burak",2,20,25);

/* Zaman yaps iinde tanmladmz zelliklere eriip ilem yapyoruz. Burada elbette
zamanlar birbirinden bu ekilde karmak matematiksel olarak bir cinayet. Ancak amacmz yaplarn kullanmn
anlamak. Bu satrlarda yap iindeki zelliklerimizin deerlerine eriiyor ve bunlarn deerleri ile sembolik ilemler
yapyoruz */

int saatFark=Bitis.Saat-Baslangic.Saat;

int dakikaFark=Bitis.Dakika-Baslangic.Dakika;

int saniyeFark=Bitis.Saniye-Baslangic.Saniye;

Console.WriteLine ("Fark {0} saat, {1} dakika, {2} saniye",saatFark,dakikaFark,saniyeFark);

}
}
}
Bir sonraki makalemizde grmek dileiyle. Hepinize mutlu gnler dilerim

Windows 98'de C# Kodu Derleyin

Windows 9x iletim sistemlerine dotNET Framework kurularak, dotNET platformunda


yazlm programlar altrlabiliyor, fakat siz 9x iletim sistemlerinde dotNET program
yazp derleyemiyorsunuz, nk .NET programlarn yazabilmek iin Microsoft 2 ara
sunuyor.

1 ) .NET Framework SDK: Ykleyebilmek iin en az windows NT 4.0 SP6 kurulu 32 MB


RAM'li bir sistem gerekmektedir.

2 ) Visual Studio .NET: Ykleyebilmek icin en az Windows 2000 Professional SP3 ve 96


MB RAM ieren bir sistem gerekmektedir.

Diyelim ki elimizde bir Windows 98 iletim sistemi ykl sistem var. Bu sistemin bellei
de sadece 32 MB olsun. Bu zelliklere sahip bir sistem zerinde .NET programlar yazmak
isteyelim. Bunu yapabilir miyiz?
Eer .NET programlarn yazmann tek yolu yukaridaki aralari kullanmak olsayd bu
sorunun yant "hayr" olacakt. Fakat .NET programlarn yazmann birka yolu daha var.
Bunlardan bir tanesi Mono projesi dahilinde gelitirilen C# derleyicisidir. http://www.go-
mono.com/ adresinden projeyle ilgili bilgilere ve gerekli tm programlara cretsiz
ulaabilir bilgisayarnza indirebilirsiniz. mono'nun bugnku tarih itibariyle Windows icin
0.28 srm mevcut. Mono'nun CLR altyaps ile basit bir uygulamayi "mint den1.exe"
eklinde altrmak istediimde benim bilgisayarmda "bellek yetersiz" gibi bir hata verdi.
Bu yzden Microsoft .NET Framework kurmanz da tavsiye ederim. Microsoft'un
sitesinden son .net framework kurulum dosyasn indirrip kurduktan sonra Mono'nun
"mcs" derleyicisi ile derlediginiz programlar normal Windows uygulamas altryormu
gibi ift tklayarak altrabilirsiniz. Aada basit bir rnek grlyor.

class den1{
public static void Main(){
System.Console.WriteLine("denemedir.");
System.Console.ReadLine();
}
}

Bu rnek uygulamay mcs derleyicisi ile aadaki gibi derliyoruz.

D:\Program Files\Mono-0.28\bin\>mcs den1.cs


Compilation succeeded

Oluan dosyaya ift tklayarak ya da exe'nin adn yazarak uygulamay altryoruz.

D:\Program Files\Mono-0.28\bin\>den1.exe
Denemedir.

sterseniz daha karmak bir uygulama ile mcs derleyicisinin yeteneklerini test edelim.

Matematik'te satr, stun veya diyagonallerindeki saylarn toplamnn hep ayn sayya eit
olduu karelere "sihirli kare" denir. Verilen bir tek sayl boyut icin sihirli kare oluturan
algoritma uygulamas C# ile verilmistir. Program Visual Studio .NET 2003 ortamnda
yazlmtr ve derlenmistir. VS.NET ile oluturulan caltrlabilir dosyann ad
WindowsApplication6.exe'dir. Ayn kaynak kod (Form1.cs) hicbir deiiklie ugratlmadan
Windows 98 uzerine kurulu Mono-0.28 ve .NET Framework 1.1 yuklu makinede Mono
derleyicisiyle "mcs Form1.cs -r:System.Windows.Forms -r:System.Drawing
-r:System.Data" komutuyla derlenmitir. Derleme baaryla sonuclanm ve Form1.exe
adli dosya olumutur. Aadaki masaustu grntsunde sol tarafta altrlan uygulama
Mono ile derlenen, sa tarafta altrlan uygulama ise (ayn kaynak koddan derlenmitir)
VS.NET 2003'te derlenmitir. ki dosya da ift tklanarak altrlmtr.

ekil 1: Mono ve VS.NET ile derlenen uygulamalar.

VS.NET Uygulamasn indirmek iin tklayn.

Mono ile derlenen uygulamay indirmek iin tklayn.

Sihirli Karelerin Oluturulmas - Basamak Yntemi

"Sihirli Kare" oluturmak icin kullanlan yntem La Loubere'in bulduu "Basamak" ad


verilen yontemdir.

Aada genel kural verilen "Basamak" yntemi her tek boyutlu sihirli kareyi oluturabilir.
Aagidaki anlatm "Yaayan Matematik" adli kitabin 53. sayfasndan alnmtr, bu konu
hakknda daha detayli bilgi ve buna benzer keyifli matematik elencelerini renmek iin
bu kitaba bavurmanz tavsiye edilir. Bu yntemin 3x3'lk bir sihirli kareye uygulan
aadaki ekilde gsterilmitir.

ekil 2: Sihirli kare algoritmas

"
1) 1 saysn en st satrn ortasndaki kareye yerletirerek balayalm.

2) Her koyduumuz saynn sa st aprazna bir sonraki sayy koyalm. Eer buras
sihirli karenin dndaki hayali bir kareyse (a,b,...,g diye isimlendirdiklerimizden biriyse)
sihirli karede bu yere denk gelen kutuyu bulup buraya saymz yerletirelim.

3) Eer sihirli karedeki sa st apraz doluysa, o zaman sayy bir onceki saynn altndaki
kutuya yerletirelim (4 ve 7 saylarnda olduu gibi).

4) 2. ve 3. basamaklar uygulamay srdurerek sihirli karedeki dier saylarn yerlerini


bulalm."

["Yaayan Matematik",s.53]

Tavsiyeler

Mono'nun resmi sayfas


Mono semineri slaytlar

Referans

"Yaayan Matematik", Theoni PAPPAS, Trke'ye eviren: Yldz SLER, Sarmal Yaymevi,
Ekim 1993.
Windows XP Stillerinin Kontrollere Uyarlanmas

Merhaba, bu makalede Windows XP sitillerinin form kontrollerine herhangi bir Manifest


dosyas olmadan uygulanmasn tartacaz. Ben uygulama rnei olarak bir ProgressBar
kontroln setim. altrlabilir rnek kod bu siteden indirilebilir.

Hereyden nce bu isteimizi gerekletirmek iin isteimizi uygulayacamz bir snfa


sahip olmamz gerekir. Ne yazk ki standart ProgressBar snf sealed olduu iin ben
snfm Control snfndan trettim:

public class XPProgressBar:Control


{
}

Daha sonra yapmamz gereken standart ProgressBar zelliklerini (Maximum, Minimum,


Value, Step) zelliklerini snfmza uygulamaktr. Bu zelliklerin hepsi integerdir. Kolay
olduu iin bu ksm geiyorum. Dikkat edilmesi gereken nokta Value zelliine bir deer
geerken snf rneimizin yeniden boyanmasn salamaktr. Bunu da Refresh()
fonksiyonu ile yapabiliriz. Uygulamamzn amac XP sitillerinin uygulanmas olduu iin
Style isminde bir zellik tantrz. Bu zellik Normal ve System isimlerinde iki enum deeri
tutar. Eer zelliimizin deeri System ise XP sitili uygulanr.

public Styles Style


{
get {<return FStyle;}
set
{
FStyle=value;
Refresh();
}
}

imdi snfmzn boyanmas iin OnPaint metoduna geebiliriz. lknce Normal deerini
grelim.

protected override void OnPaint(PaintEventArgs e)


{

Rectangle rect = ClientRectangle;

rect.Width-=6;

rect.Height-=6;

if(Maximum!=Minimum)
{
rect.Width =(Value-Minimum)*100/(Maximum-Minimum)*rect.Width/100;
}
if(Style==Styles.Normal)
{
ControlPaint.DrawBorder3D(e.Graphics,ClientRectangle,Border3DStyle.Sunken);

rect=new Rectangle(new Point(rect.X+3,rect.Y+3),rect.Size);

e.Graphics.FillRectangle(Brushes.Blue,rect);
}
else
{
//Burada Styles.System deerini uygulayacaz.
}
}

Yukardaki kodda yaplan Maximum ve Minimum deerlerine gre boyanacak alann


bulunup daha sonra boyanmasdr. Dikkat edeceiniz gibi segment eklinde deil de dz
boya eklinde boyanmtr. Eer isterseniz bu aamada bileenimizi test edebilirsiniz.

Dikkat edeceiniz gibi standart bir ProgressBarn yapaca ilemleri gerekletirdik. imdi
asl amacmz XP sitillerinin uygulanmas olduuna gre bu aamaya geelim.

ncelikle kullandmz iletim sisteminin yapacamz bu ilemi desteklemesi iin


Windows XP olmas lazm. Bunu nasl anlayacamz grelim:

bool IsThemedos()
{
if(Environment.OSVersion.Platform != PlatformID.Win32NT

|| Environment.OSVersion.Version.Major < 5

|| Environment.OSVersion.Version.Minor < 1)

return false;

return true;
}

Yukardaki fonksiyonda yaplan kullanlan iletim sisteminin version numaralarna bakarak


Windows XP olup almadn anlamaktr. Eer deilse program XP sitillerinin kullanmna
izin vermeyecektir.

imdi burada bir ara verip XP sitillerinin kullanmna olanak veren WinApi leri tantmak
istiyorum. ncelikle kullanacamz dll UxTheme.dll dir. Bizim bu programda
kullanacamz 4 tane WinApi fonksiyonu var. imdi bunlar tanyalm:

HTHEME OpenThemeData( HWND hwnd,LPCWSTR pszClassList);

Bu fonksiyon bir window iin ilgili snfn datasn aar. Dn deeri IntPtr dir.
pszClassList parametresi ise kullanacamz snfn string deeridir. Bizim rneimizde
bu deer "PROGRESS" dir.

BOOL IsAppThemed(VOID);

Bu Api bir kontrol fonksiyonudur. uygulamamzn visual sitilleri uygulayp


uygulamayacan sorgular.
BOOL IsThemeActive(VOID);

Bu da baka bir kontrol fonksiyonudur. Visual sitillerin uygulamamz iin aktif olup
olmadn denetler.

HRESULT DrawThemeBackground(

HTHEME hTheme,
HDC hdc,
int iPartId,
int iStateId,
const RECT *pRect,
const RECT *pClipRect
);

Uygulamamzn belki de en can alc Api si budur. Bu fonksiyonla visual sitillerin izim
ilemini gerekletiriyoruz. Dn deeri integer dir. Parametrelerine gelince:

hTheme: OpenThemeData fonksiyonu ile elde ettiimiz IntPtr deerini kullanacaz.

hdc: Controlmzn hdc deeri. CreateGraphics().GetHdc() ile elde edilir.

iPartId ve iStateId: Bu parametreler izeceimiz kontroln blmlerini ifade eder. Visual


Studio nun yardm indeksi blmne Parts and States yazarsak konuyla ilgili dkman
bulabiliriz. Bu durumda Controlmzn arkaplann izeceksek iPartId 1 deerini, eer
ndeki ilerleme blmn izeceksek 3 deerini almaldr. StateId deeri ise ProgressBar
iin kullanlmaz. Eer dkman iyice incelersek yapacamz dier uygulamalarda XP
sitillerini nasl uygulayacamz kolaylkla anlalr.

pRect ve pClipRect: Bu parametreler izeceimiz drtgen blm ifade eder. ClipRect


null deerini alabilir.

imdi programmza geri dnp anlattmz Api lerin kullanmna geebiliriz. ncelikle
snfmzn yapcsnda OpenThemeData apisini kullanarak XP sitilimizin deerini tutabilirz.
Daha sonra snfmzn OnPaint metodunda bo braktmz else ifadesini dolduralm.

if(IsThemedos() && IsAppThemed() && IsThemeActive())


{
DrawThemeBackground(e.Graphics,1,1,ClientRectangle);
DrawSystemSegments(e.Graphics,rect);
}

private void DrawSystemSegments(Graphics g, Rectangle rc)


{
int segwidth = 8;

int Count = ((rc.Width)/(segwidth+2))+((rc.Width<=0)?0:1);

Rectangle rect = new Rectangle(3,3,Count*(segwidth+2),rc.Height);

if (rect.Width>(Width-2*3))
{

rect.Width = rc.Width;
}

DrawThemeBackground(g,3,1,rect);
}

ncelikle kontrolmzn arka plann izdik. Daha sonra DrawSystemSegments


fonksiyonu ile segmentleri hesaplayp sonra da bunu izdirdik.

Bu konu hakknda anlatacaklarm bitti. Eer rnek kod incelenirse anlalmayan


blmlerin anlalmasna yardmc olacaktr. Hepinize iyi almalar.

Not : XP stilindeki kontrolleri grmeniz iin iletim sisteminizin temasn XP Stil olarak
deitirmeniz gerekmektedir.
Hashtable Koleksiyon Snfnn Kullanm

Bu makalemizde HashTable koleksiyon snfn incelemeye alacaz. Bildiiniz gibi


Koleksiyonlar System.Collections namespace'inde yer almakta olup, birbirlerinin ayn
veya birbirlerinden farkl veri tiplerinin bir arada tutulmasn salayan diziler
oluturmamza imkan salamaktadrlar. Pek ok koleksiyon snf vardr. Bugn bu
koleksiyon snflarndan birisi olan HashTable koleksiyon snfn inceleyeceiz.

HashTable koleksiyon snfnda veriler key-value dediimiz anahtar-deer iftleri eklinde


tutulmaktadrlar. Tm koleksiyon snflarnn ortak zellii barndrdklar verileri object
tipinde olmalardr. Bu nedenle, HashTable'lardada key ve value deerleri herhangibir veri
tipinde olabilirler. Temel olarak bunlarn her biri birer DictionaryEntry nesnesidir.
Bahsetmi olduumuz key-value iftleri hash tablosu ad verilen bir tabloda saklanrlar.
Bu deer iftlerine erimek iin kullanlan bir takm karmak kodlar vardr.

Key deerleri tektir ve deitirilemezler. Yani bir key-value iftini koleksiyonumuza


eklediimizde, bu deer iftinin value deerini deitirebilirken, key deerini
deitiremeyiz. Ayrca key deerleri benzersiz olduklarnda tam anlamyla birer anahtar
alan vazifesi grrler. Dier yandan value deerline null deerler atayabilirken, anahtar
alan niteliindeki Key deerlerine null deerler atayamayz. ayet uygulamamzda
varolan bir Key deerini eklemek istersek ArgumentException istisnas ile karlarz.

HashTable koleksiyonu verilere hz bir biimde ulamamz salayan bir kodlama yapsna
sahiptir. Bu nedenle zellikle arama maliyetlerini drd iin tercih edilmektedir.
imdi konuyu daha iyi pekitirebilmek amacyla, hemen basit bir uygulama gelitirelim.
Uygulamamzda, bir HastTable koleksiyonuna key-value iftleri ekliyecek, belirtilen key'in
sahip olduu deere baklacak, tm HashTable'n ierdii key-value iftleri listelenecek,
eleman iftlerini HashTable'dan kartacak vb... ilemler gerekletireceiz. Form
tasarmn ben aadaki ekildeki gibi yaptm. Temel olarak teknik terimlerin trke
karlna dair minik bir sz bir HashTable olarak tasarlayacaz.
ekil 1. Form Tasarmmz.

imdi kodlarmza bir gz atalm.

System.Collections.Hashtable htTeknikSozluk; /* HashTable koleksiyon nesnemizi


tanimliyoruz.*/

private void Form1_Load(object sender, System.EventArgs e)


{
htTeknikSozluk=new System.Collections.Hashtable(); /* HashTable nesnemizi
olusturuyoruz.*/
stbDurum.Text=htTeknikSozluk.Count.ToString(); /* HashTable'imizdaki eleman
sayisini Count zelligi ile greniyoruz.*/
}

private void btnEkle_Click(object sender, System.EventArgs e)


{
try
{
htTeknikSozluk.Add(txtKey.Text,txtValue.Text);/* HashTable'imiza key-value ifti
ekleyebilmek iin Add metodu kullaniliyor.*/
lstAnahtar.Items.Add(txtKey.Text);
stbDurum.Text=htTeknikSozluk.Count.ToString();
}
catch(System.ArgumentException) /* Eger var olan bir key'i tekrar eklemeye alisirsak
bu durumda ArgumentException istisnasi firlatilacaktir. Bu durumda, belirtilen key-
value ifti HashTable koleksiyonuna eklenmez. Bu durumu kullaniciya bildiriyoruz.*/
{
stbDurum.Text=txtKey.Text+" Zaten HashTable Koleksiyonunda Mevcut!";
}
}

private void lstAnahtar_DoubleClick(object sender, System.EventArgs e)


{
string deger;
deger=htTeknikSozluk[lstAnahtar.SelectedItem.ToString()].ToString(); /*
HashTable'daki bir degere ulasmak iin, kseli parantezler arasinda aranacak key degerini
giriyoruz. Sonucu bir string degiskenine aktariyoruz.*/

MessageBox.Show(deger,lstAnahtar.SelectedItem.ToString());
}

private void btnSil_Click(object sender, System.EventArgs e)


{
if(htTeknikSozluk.Count==0)
{
stbDurum.Text="ikartilabilecek hi bir eleman yok";
}
else if(lstAnahtar.SelectedIndex==-1)
{
stbDurum.Text="Listeden bir eleman semelisiniz";
}
else
{
htTeknikSozluk.Remove(lstAnahtar.SelectedItem.ToString()); /* Bir HashTable'dan
bir nesneyi ikartmak iin, Remove metodu kullanilir. Bu metod parametre olarak
ikartilmak istenen deger iftinin key degerini alir.*/

lstAnahtar.Items.Remove(lstAnahtar.SelectedItem);

stbDurum.Text="ikartildi";

stbDurum.Text=htTeknikSozluk.Count.ToString();
}
}

private void btnTumu_Click(object sender, System.EventArgs e)


{
lstTumListe.Items.Clear(); /* Asagidaki satirlarda, bir HashTable koleksiyonu iinde yer
alan tm elemanlara nasil erisildigini grmekteyiz. Keys metodu ile HashTable
koleksiyonumuzda yer alan tm anahtar degerlerini (key'leri), ICollection
arayz(interface) trnden bir nesneye atiyoruz. Foreach dngmz ile bu nesne iindeki
her bir anahtari, HashTable koleksiyonunda bulabiliyoruz.*/

ICollection anahtar=htTeknikSozluk.Keys; foreach(string a in anahtar)


{
lstTumListe.Items.Add(a+"="+htTeknikSozluk[a].ToString());
}
}

imdi uygulamamz altralm.


ekil 2. Programn almasnnn sonucu.

Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dieiyle hepinize
mutlu gnler dilerim.

Stack ve Queue Koleksiyon Snflar

Bu makalemizde Stack ve Queue koleksiyon snflarn incelemeye alacaz. Bir nceki


makalemizde bildiiniz gibi, HashTable koleksiyon snfn incelemetik. Stack ve Queue
koleksiyonlarda, System.Collections isim alannda yer alan ve ortak koleksiyon
zelliklerine sahip snflardr.

Stack ve Queue koleksiyonlar, her koleksiyon snfnda olduu gibi, elemanlarn object
tipinde tutmaktadrlar. Bu koleksiyonlarn zellii giren-kan eleman prensibleri zerine
almalardr. Stack koleksiyon snfi, LIFO ad verilen, Last In First Out( Son giren ilk
ikar) prensibine gore alrken, Queue koleksiyon snf FIFO yani First In First Out(ilk
giren ilk kar) prensibine gore alr. Konuyu daha iyi anlayabilmek iin asadaki
ekilleri gz nne alalm.
Sekil 1. Stack Koleksiyon Snfnn alma Yaps

Grld gibi, Stack koleksiyonunda yer alan elemanlardan son girene ulamak olduka
kolaydr. Oysaki ilk girdiimiz elemana ulamak iin, bu elemann stnde yer alan dier
tm elemanlar silmemiz gerekmektedir. Queue koleksyion snfna gelince;

Sekil 2. Queue Koleksiyon Snfnn alma Yaps

Grldg gibi Queue koleksiyon sinifinda elemanlar koleksiyona arkadan katilirlar ve ilk
giren eleman kuyruktan ilk ikan eleman olur.

Stack ve Queue farkl yaplarda tasarlandklar iin elemanlarna farkl metodlar ile
ulalmaktadr. Stack koleksiyon snfnda, en son giren eleman elde etmek iin Pop
metodu kullanlr. Koleksiyona bir eleman eklerken Push metodu kullanlr. Elbette
eklenen eleman en son elemandr ve Pop metodu arldnda elde edilecek olan ilk
eleman halini alir. Ancak Pop metodu son giren eleman verirken bu eleman
koleksiyondan siler. te bunun nne geen metod Peek metodudur. imdi diyebilirsiniz
ki madem son giren eleman siliniyor, Pop metodunu o zaman niye kullanyoruz.
Hatrlarsanz, Stack koleksiyonunda, ilk giren eleman elde etmek iin bu elemann
stnde yer alan tm elemanlar silmemiz gerektiini sylemitik. te bir dng
yapsnda Pop metodu kullanldnda, ilk giren elemana kadar inebiliriz. Tabi dier
elemanlari kaybettikten sonra bunun ok byk nem tayan bir eleman olmasn da
istemi olabiliriz.

Gelelim Queue koleksiyon snfnn metodlarna. Dequeue metodu ile koleksiyona ilk giren
elemani elde ederiz. Ve bunu yaptmz anda eleman silinir. Nitekim dequeue metodu
pop metodu gibi alr. Koleksiyona eleman eklemek iin ise, Enqueue metodu kullanlr.
lk giren eleman elde etmek ve silinmemesini salamak istiyorsak yine stack koleksiyon
snfinda olduu gibi, Peek metodunu kullanrz.

Bu koleksiyonlarin en gzel yanlarndan birisi siz eleman saysn belirtmediiniz takdirde


koleksiyonun boyutunu otomatik olarak kendilerinin ayarlamalardr. Stack koleksiyon
snf, varsayilan olarak 10 elemanl bir koleksiyon dizisi oluturur.(Eer biz eleman
saysn yapc metodumuzda belirtmez isek).Eer eleman says 10u geerse, koleksiyon
dizisinin boyutu otomatik olarak iki katina kar. Ayni prensip queue koleksiyon sinifi
iinde geerli olmakla birlikte, queue koleksiyonu iin varsayilan dizi boyutu 32 elemanli
bir dizidir.

Simdi dilerseniz, basit bir console uygulamasi ile bu konuyu anlamaya alisalim.

using System;
using System.Collections; /* Uygulamalarimizda koleksiyon siniflarini kullanabilmek iin
Collections isim uzayini kullanmamiz gerekir.*/

namespace StackSample1
{
class Class1
{

static void Main(string[] args)


{
Stack stc=new Stack(4); /* 4 elemanli bir Stack koleksiyonu olusturduk.*/

stc.Push("Burak"); /*Eleman eklemek iin Push metodu kullaniliyor.*/


stc.Push("Selim");
stc.Push("SENYURT");
stc.Push(27);
stc.Push(true);

Console.WriteLine("ikan eleman {0}",stc.Pop().ToString());/* Pop metodu son


giren(kalan) elemani verirken, ayni zamanda bu elemani koleksiyon dizisinden siler.*/
Console.WriteLine("ikan eleman {0}",stc.Pop().ToString());
Console.WriteLine("ikan eleman {0}",stc.Pop().ToString());
Console.WriteLine("------------------");

IEnumerator dizi=stc.GetEnumerator(); /* Koleksiyonin elemanlarini


IEnumerator arayznden bir nesneye aktariyoruz.*/

while(dizi.MoveNext()) /* dizi nesnesinde okunacak bir sonraki eleman var


oldugu srece isleyecek bir dng.*/
{
Console.WriteLine("Gncel eleman {0}",dizi.Current.ToString()); /* Current
metodu ile dizi nesnesinde yer alan gncel elemani elde ediyoruz. Bu dngy
alistirdigimizda sadece iki elemanin dizide oldugunu grrz. Pop metodu sagolsun.*/
}

Console.WriteLine("------------------");
Console.WriteLine("En stteki eleman {0}",stc.Peek()); /* Peek metodu son
giren elemani veya en ste kalan elemani verirken bu elemani koleksiyondan silmez.*/

dizi=stc.GetEnumerator();

while(dizi.MoveNext())
{
Console.WriteLine("Gncel eleman {0}",dizi.Current.ToString()); /* Bu
durumda yine iki eleman verildigini Peek metodu ile elde edilen elemanin koleksiyondan
silinmedigini grrz.*/
}

}
}
}

3. Stack ile ilgili programn ekran kts

Queue rnegimiz ise ayn kodlardan oluuyor sadece metod isimleri farkl.

using System;
using System.Collections;

namespace QueueSample1
{
class Class1
{
static void Main(string[] args)
{
Queue qu=new Queue(4);

qu.Enqueue("Burak"); /*Eleman eklemek iin Enqueue metodu kullaniliyor.*/


qu.Enqueue("Selim");
qu.Enqueue("SENYURT");
qu.Enqueue(27);
qu.Enqueue(true);

Console.WriteLine("ikan eleman {0}",qu.Dequeue().ToString());/* Dequeue


metodu ilk giren(en alttaki) elemani verirken, ayni zamanda bu elemani koleksiyon
dizisinden siler.*/
Console.WriteLine("ikan eleman {0}",qu.Dequeue().ToString());
Console.WriteLine("ikan eleman {0}",qu.Dequeue().ToString());
Console.WriteLine("------------------");

IEnumerator dizi=qu.GetEnumerator(); /* Koleksiyonin elemanlarini


IEnumerator arayznden bir nesneye aktariyoruz.*/
while(dizi.MoveNext()) /* dizi nesnesinde okunacak bir sonraki eleman var
oldugu srece isleyecek bir dng.*/
{
Console.WriteLine("Gncel eleman {0}",dizi.Current.ToString()); /* Current
metodu ile dizi nesnesinde yer alan gncel elemani elde ediyoruz. Bu dngy
alistirdigimizda sadece iki elemanin dizide oldugunu grrz. Dequeue metodu
sagolsun.*/
}

Console.WriteLine("------------------");
Console.WriteLine("En altta kalan eleman {0}",qu.Peek()); /* Peek metodu son
giren elemani veya en ste kalan elemani verirken bu elemani koleksiyondan silmez.*/

dizi=qu.GetEnumerator();

while(dizi.MoveNext())
{
Console.WriteLine("Gncel eleman {0}",dizi.Current.ToString()); /* Bu
durumda yine iki eleman verildigini Peek metodu ile elde edilen elemanin koleksiyondan
silinmedigini grrz.*/
}

}
}
}

Sekil 4. Queue ile ilgili programin ekran kts

Geldik bir makalemizin daha sonuna. Umuyorumki sizlere faydal olabilecek bilgiler
sunabilmiimdir. Bir sonraki makalemizde grsmek dileiyle hepinize mutlu gnler
dilerim.
Reflection(Yansma) ile Tiplerin Srr Ortaya kyor

Hi dotNET te yer alan bir tipin yelerini renebilmek istediniz mi? rnein var olan bir
dotNET snfnn veya sizin kendi yazm olduunuz yada bir bakasnn yazd snfa ait
tm yelerin neler olduuna programatik olarak bakmak istediniz mi?

te bugnk makalemizin konusu bu. Herhangi bir tipe (type) ait yelerin neler
olduunu anlayabilmek. Bu amala, Reflection isim uzayn ve bu uzaya ait snflar
kullanacaz. Bildiiniz gibi .NET te kullanlan her ey bir tipe aittir. Yani hereyin bir tipi
vardr. yelerini renmek isteimiz bir tipi ncelikle bir Type deikeni olarak alrz.
(Yani tipin tipini alrz. Bu nedenle ben bu teknie Tip-i-Tip adn verdim ). Bu noktadan
sonra Reflection uzayna ait snflar ve metodlarn kullanarak ilgili tipe ait tm bilgileri
edinebiliriz. Kk bir Console uygulamas ile konuyu daha iyi anlamaya alalm. Bu
rneimizde, System.Int32 snfna ait yelerin bir listesini alacaz. te kodlarmz;

using System;

namespace ReflectionSample1
{
class Class1
{
static void Main(string[] args)
{
Type tipimiz=Type.GetType("System.Int32");/* ncelikle String sinifinin tipini
greniyoruz. */

System.Reflection.MemberInfo[] tipUyeleri=tipimiz.GetMembers(); /* Bu satir


ile, System.String tipi iinde yer alana yelerin listesini Reflection uzayinda yer alan,
MemberInfo sinifi tipinden bir diziye aktariyoruz. */

Console.WriteLine(tipimiz.Name.ToString()+" sinifindaki ye
sayisi:"+tipUyeleri.Length.ToString());/* Length zelligi, MemeberInfo tipindeki dizimizde
yer alan yelerin sayisini, (dolayisiyla System.String sinifi iinde yer alan
yelerin sayisini) veriyor.*/
/* Izleyen dng ile, MemberInfo dizininde yer alan yelerin birtakim bilgilerini
ekrana yaziyoruz.*/
for(int i=0;i<TIPUYELERI.LENGTH;++I)
{
Console.WriteLine(i.ToString()+". ye adi:"+tipUyeleri[i].Name.ToString()
+"||"+tipUyeleri[i].MemberType.ToString()); /* Name zelligi yenin adini verirken,
MemberType zelligi ile, yenin tipini aliyoruz. Bu ye tipi metod, zellik, yapici metod
vb... dir.*/
}
}
}
}

Uygulamay altrdmzda aadaki ekran grntsn elde ederiz.

ekil 1. System.Int32 snfnn yeleri.

ye listesini incelediimizde 15 yenin olduunu grrz. Metodlar, alanlar vardr. Ayrca


dikkat ederseniz, Parse , ToString metodlar birden fazla defa gemektedir. Bunun nedeni
bu metodlarn overload ( ar yklenmi ) versiyonlara sahip olmasdr.

Kodlar incelediimizde, System.Int32 snfna ait tipleri GetMembers metodu ile,


System.Reflection uzaynda yer alan MemberInfo snf tipinden bir diziye aldmz
grrz. te olayn nemli kodlar bunlardan olumaktadr. MemberInfo dnda
kullanabaileceimiz baka Reflection snflarda vardr. Bunlar;

ConstructorInfo Tipe ait yapc metod yelerini ve bu yelere ait bilgilerini ierir.
EventInfo Tipe ait olaylar ve bu olaylara ait bilgileri ierir.
MethodInfo Tipe ait metodlar ve bu metodlara ait bilgileri ierir.
FieldInfo Tip iinde kullanlan alanlar ve bu alanlara ilikin bilgileri ierir.
ParameterInfo Tip iinde kullanlan parametreleri ve bu parametrelere ait bilgileri
ierir.
PropertyInfo Tip iinde kullanlan zellikleri ve bu zelliklere ait bilgileri ierir.

Tablo 1. Reflection Uzaynn Dier Kullanl Snflar

imdi bu snflara ait rneklerimizi inceleyelim.

Bu kez bir DataTable snfnn yelerini inceleyeceiz. rnek olarak, sadece olaylarn ve
bu olaylara ilikin zelliklerini elde etmeye alalm. Bu rneimizde, yukarda
bahsettiimiz tip-i-tip tekniini biraz deitireceiz. Nitekim bu teknii uygulamamz
halinde bir hata mesaj alrz. Bunun nne gemek iin, bir DataTable rnei (instance)
oluturup bu rnein tipinden hareket edeceiz. Dilerseniz hemen kodlarmza geelim.

using System;

namespace ReflectionSample2
{

class Class1
{
static void Main(string[] args)
{
System.Data.DataTable dt=new System.Data.DataTable(); /* Bir DataTable
rnegi(instance) yaratiyoruz.*/

Type tipimiz=dt.GetType(); /* DataTable rnegimizin GetType metodunu


kullanarak, bu rnegin dolayisiyla DataTable sinifinin tipini elde ediyoruz. */

System.Reflection.MethodInfo[] tipMetodlari=tipimiz.GetMethods(); /* Bu kez


sadece metodlari incelemek istedigimizden, GetMethods metodunu kullaniyor ve sonulari,
MethodInfo sinifi tipinden bir diziye aktariyoruz.*/

Console.WriteLine(tipimiz.Name.ToString()+" sinifindaki metod


sayisi:"+tipMetodlari.Length.ToString()); /* Metod sayisini Length zelligi ile aliyoruz.*/

/* Dngmz olusturuyor ve Metodlarimizi bir takim zellikleri ile birlikte


yazdiriyoruz.*/
for(int i=0;i<TIPMETODLARI.LENGTH;++I)
{
Console.WriteLine("Metod adi:"+tipMetodlari[i].Name.ToString()+" |Dns
degeri:"+tipMetodlari[i].ReturnType.ToString()); /* Metodun ismini name zelligi ile
aliyoruz. Metodun dns tipini ReturnType zelligi ile aliyoruz. */

System.Reflection.ParameterInfo[]
prmInfo=tipMetodlari[i].GetParameters();
/* Bu satirda ise, i indeksli metoda ait parametre bilgilerini GetParameters
metodu ile aliyor ve Reflection uzayinda bulunan ParameterInfo sinifi tipinden bir diziye
aktariyoruz. Bylece ilgili metodun parametrelerine ve parametre bilgilerine erisebilicez.*/

Console.WriteLine("-----Parametre
Bilgileri-----"+prmInfo.Length.ToString()+" parametre");
/* Dngmz ile i indeksli metoda ait parametrelerin isimlerini ve tiplerini
yazdiriyoruz. Bunun iin Name ve ParameterType metodlarini kullaniyoruz.*/

for(int j=0;j<PRMINFO.LENGTH;++J)
{
Console.WriteLine("P.Adi:"+prmInfo[j].Name.ToString()+" |
P.Tipi:"+prmInfo[j].ParameterType.ToString());
}

Console.WriteLine("----");
}
}
}
}

imdi uygulamamz altralm ve sonularna bakalm.

ekil 2. System.Data.DataTable tipinin metodlar ve metod parametrelerine ait bilgiler.

Reflection teknikleri yardmyla altrdmz programa ait snflarnda bilgilerini elde


edebiliriz. zleyen rneimizde, yazdmz bir snfa ait ye bilgilerine bakacaz.

yelerine bakacamz snfn kodlar;


using System;

namespace ReflectionSample3
{
public class OrnekSinif
{
private int deger;

public int Deger


{
get
{
return deger;
}
set
{
deger=value;
}
}

public string metod(string a)


{
return "Burak Selim SENYURT";
}

int yas=27;
string dogum="istanbul";

}
}

ikinci snfmzn kodlar;

using System;
using System.Reflection;

namespace ReflectionSample3
{
class Class1
{
static void Main(string[] args)
{
Type tipimiz=Type.GetType("ReflectionSample3.OrnekSinif");

MemberInfo[] tipUyeleri=tipimiz.GetMembers();

for(int i=0;i<TIPUYELERI.LENGTH;++I)
{
Console.WriteLine("Uye adi:"+tipUyeleri[i].Name.ToString()+" |Uye
Tipi:"+tipUyeleri[i].MemberType.ToString());
}
}
}
}
imdi uygulamamz altralm.

ekil 3. Kendi yazdm snf yelerinede bakabiliriz.

Peki kendi snfmza ait bilgileri edinmenin bize ne gibi bir faydas olabilir. te imdi tam
diimize gore bir rnek yazacaz. rneimizde, bir tablodaki verileri bir snf iersinden
tanmladmz zelliklere alacaz. Bu uygulamamz sayesinde sadece tek satrlk bir kod
ile, herhangibir kontrol veriler ile doldurabileceiz. Bu uygulamada esas olarak, veriler
veritabanndaki tablodan alncak ve oluturduumuz bir koleksiyon snfndan bir diziye
aktarlacak. Oluturulan bu koleksiyon dizisi, bir DataGrid kontrol ile ilikilendirilecek.
Teknik olarak kodumuzda, Reflection uzaynn PropertyInfo snfn kullanarak,
oluturduumuz snfa ait zellikler ile tablodaki alanlar karlatracak ve uygun iseler bu
zelliklere tabloda karlk gelen alanlar iindeki deerleri aktaracaz. Dilerseniz
kodumuz yazmaya balayalm.

using System;
using System.Reflection;
using System.Data;
using System.Data.SqlClient;

namespace ReflectDoldur
{
public class Kitap
{

private string kitapAdi;


private string yayimci;

/* zelliklerimizin adlarinin tablmuzdan alacagimiz alan adlari ile ayni olmasina


dikkat edelim.*/
public string Adi
{
get
{
return kitapAdi;
}
set
{
kitapAdi=value;
}
}

public string BasimEvi


{
get
{
return yayimci;
}
set
{
yayimci=value;
}
}

/* Yapici metodumuz parametre olarak geirilen bir DataRow degiskenine sahip. Bu


degisken ile o anki satiri aliyoruz.*/
public Kitap(System.Data.DataRow dr)
{
PropertyInfo[] propInfos=this.GetType().GetProperties(); /* this ile bu sinifi
temsil ediyoruz. Bu sinifin tipini alip bu tipe ait zellikleri elde ediyor ve bunlar bir
PropertyInfo sinifi tipinden diziye aktariyoruz.*/

/* Dngmz ile tm zellikleri geziyoruz. Eger metodumuza parametre olarak


geirilen dataRow degiskenimiz, bu zelligin adinda bir alan ieriyorsa, bu zellige ait
SetValue metodunu kullanarak zelligimize, iligili tablo alaninin degerini aktariyoruz.*/

for(int i=0;i<PROPINFOS.LENGTH;++I)
{
if(propInfos[i].CanWrite) /* Burada zelligimizin bir Set bloguna sahip olup
olmadigina bakiliyor. Yani zelligimizen yazilabilir olup olmadigina. Bunu saglayan
zelligimiz CanWrite. Eger zellik yazilabilir ise (yada baska bir deyisle readonly degil ise)
true degerini dndrr.*/
{
try
{
if(dr[propInfos[i].Name]!=null) /* dataRow degiskeninde, zelligimin
adindaki alanin degerine bakiliyor. Null deger degil ise SetValue ile alanin degeri
zelligimize yazdiriliyor. */
{
propInfos[i].SetValue(this,dr[propInfos[i].Name],null);
}
else
{
propInfos[i].SetValue(this,null,null);
}
}
catch
{
propInfos[i].SetValue(this,null,null);
}
}
}

}
}

/* KitapKoleksiyonu sinifimiz bir koleksiyon olucak ve tablomuzdan alacagimiz iki alana


ait verileri Kitap isimli nesnelerde saklanmasini sagliyacak. Bu nedenle, bir CollectionBase
sinifindan tretildi. Bylece sinifimiz iinde indeksleyiciler kullanabilecegiz.*/
public class KitapKoleksiyonu:System.Collections.CollectionBase
{
public KitapKoleksiyonu()
{
SqlConnection conFriends=new SqlConnection("data source=localhost;initial
catalog=Friends;integrated security=sspi");
SqlDataAdapter da=new SqlDataAdapter("Select Adi,BasimEvi From
Kitaplar",conFriends);
DataTable dtKitap=new DataTable();
da.Fill(dtKitap);

foreach(DataRow drow in dtKitap.Rows)


{
this.InnerList.Add(new Kitap(drow));
}
}

public virtual void Add(Kitap _kitap)


{
this.List.Add(_kitap);
}

public virtual Kitap this[int Index]


{
get
{
return (Kitap)this.List[Index];
}
}
}
}

Ve ite formumuzda kullandmz tek satrlk kod;

private void btnDoldur_Click(object sender, System.EventArgs e)


{
dataGrid1.DataSource = new ReflectDoldur.KitapKoleksiyonu();
}

imdi uygulamamz altralm ve bakalm.


ekil 4. Programn almasnn Sonucu

Grld gibi tablomuzdaki iki Alana ait veriler yazdmz KitapKoleksiyonu snf
yardmyla, her biri Kitap tipinde bir nesne alan koleksyionumuza eklenmi ve bu
sonularda dataGrid kontrolmze balanmtr. Siz bu rnei dahada iyi bir ekilde
gelitirebilirisiniz. Umuyorumki bu rnekte yapmak istediimizi anlamsnzdr. Yansma
tekniini bu kod iinde ksa bir yerde kullandk. Snfn zelliklerinin isminin, tablodaki
alanlarn ismi ile ayn olup olmadn ve ayn iseler yazlabilir olup olmadklarn
renmekte kullandk.

Deerli Okurlarm. Geldik bir makalemizin daha sonuna. Hepinize mutlu gnler dilerim.
C# Komut Satr Derleyicisi(csc.exe) ve Parametreleri

Bu yazda sizlere nemli bir referans kayna olacan dndm C# komut satr
derleyicisinin zelliklerini ve parametrelerini bir arada inceleyeceiz. Byle bir kayna
oluturmamdaki sebep C# komut derleyiciisnin kullanm ile ilgili bana gelen onlarca e-
postaya toplu olarak cevap verebilmek.

Bildiiniz zere .NET ortamnda etkili bir ekilde gelitirme yapabilmek iin Visual
Studio.NET aracna ihtiya duyuyoruz. Ancak bu gelitirme ortam olmadan da her tr
.NET uygulamasn gelitirme imkanna sahibiz. Bu imkan salayan en nemli ara
elbetteki C#'n komut satrndan da alan csc.exe isimli derleyicisidir. C# komut satr
derleyicisi .NET Framework SDK ile birlikte cretsiz olarak datlmaktadr. Dolaysyla
.NET ortamnda uygulama gelitirmek iin yapmamz gereken tek ey www.microsoft.com
sitesinden .NET Farmework SDK'nn son srmn bilgisayarnza indirmek ve kurmaktr.

C# derleyicisi komut satrndan basite kullanlabilmektedir. C# derleyicisini komut


satrndan en etkili bir ekilde kullanabilmek iin iletim sisteminizde bir takm ayarlar
yapmanz gerekmektedir. rnein siz komut satrnda herhangi bir dizin ierisindeyken
bile csc.exe altrlabilir dosyasn altrabilmeniz iin csc.exe dosyasnn bulunduu
dizini sistem zelliklerinde tanmlamanz gerekmektedir. Bu ilemi yapmak iin kontrol
panelden system ikonunu ve ardndan advanced sekmesini aadaki gibi sein.

Advanced sekmesine getikten sonra yukardaki ekilde krmz ile iaretlenen


"Environment Variables" dmesine tklayn.(Kullandnz iletim sistemine gre bu
butonun yeri deiik olabilir. Yukardaki ekran grnts Windows XP iletim sistemine
aittir.) Karnza kacak olan aadaki ekrandan "System Variables" alanndan Path
seeneini sein.

Path seeceni tklanarak alan penceredeki Variable value alannn sonuna ; karakterini
ekledikten sonra csc.exe dosyasnn bulunduu dizini yazn. csc.exe dosyas kullandnz
iletim sistemini gre deiiklik gsterebilir ancak genellikle aadaki gibidir.

C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322

Son dizin kullandnz Framework'un versiyon numarasn gstermektedir.

Yukardaki ilemlerin doru bir ekilde tamamlandn kontrol etmek iin komut satrn
an ve "csc" yazn. Eer aadaki hata ile karlayorsanz ilemleriniz baar ile
gereklemi demektir.

Bu hatann sebebi csc.exe programna derlenecek dosyay parametre olarak


vermememizdir.
Derleme lemi

csc.exe ile en basit derleme ilemi bir girdi dosya ve kt dosya belirtme ile yaplr.
rnein kaynakkod.cs dosyasn Program.exe eklinde derlemek iin aadaki komutu
altrmamz yeterlidir.

> csc kaynakkod.cs /out:Program.exe

Eer out parametresini kullanmayp komutu

> csc kaynakkod.cs

eklinde altrsaydk derleme ilemi baarl olurdu ancak oluturulan altrlabilir


dosyann ad kaynakkod.exe olurdu.

Proje Tipleri ve target parametresi

.NET ortamnda birden fazla proje tipi vardr ve dolaysyla her bir proje tipinin derleme
biimi farkldr. rnein bir nceki komutumuz derlem ilemini bir konsol uygulamasna
gre yapacaktr. Esasnda csc.exe derleyicisnin varsaylan derleme biimide budur. Eer
derleme ilemini farkl uygulama tipleri iin yapacak olursak dereyicinin target
parametresini kullanmamz gerekir. rnein kaynak kodumuzu bir windows uygulamas
olacak ekilde derlemek istiyorsak derleme komutu aadaki gibi olmaldr.

> csc kaynakkod.cs /target:winexe /out:Program.exe

yada

> csc kaynakkod.cs /t:winexe /out:Program.exe

Eer kaynak kodumuzu altrlabilir bir uygulama yerine bir ktphane dosyas olacak
ekilde derlemek istiyorsak aadaki komutu kullanmalyz.

> csc kaynakkod.cs /target:library /out:Program.exe

Dier bir derleme biimi ise modl derlemesidir. Modller iinde manifest dediimiz
metadatalar olmayan yalnzca kod bilgilerini ieren dosyalardr. Modller altrlabilir
deildir. Dolaysyla modller ancak manifest bilgisi olan baka bir derlenmi ktphaneye
eklenmek iin kullanlabilir. Modl eklind derleme iin aadaki kmut kullanlmaldr.

> csc kaynakkod.cs /target:module /out:Program.exe

Referans Bilgileri ve Response Dosyalar

csc.exe derleyicisi derleme ilemini baar ile gerekletriebilmesi iin baz ktphanelere
ihtiya duyar. Bu ktphaneler assembly dosyalar iinde barndrlmtr. Bu
ktphanalerin projemizde kullanldn belirtmek iin reference parametresi kullanlr.
Eer referans vermeniz gereken assembly dosyalar fazla ise bu ii otomatikletirmek iin
response. dosyalar kullanlr. response dosyasnn yerine belirtmek iin @ karakteri
kullanlr. rnek bir derleme biimi aadaki gibidir.

csc @response_dosyas /out:Program.exe kaynakdosya.cs

Derleyici Parametrelerine Toplu Bak


Aadaki listede csc derleyicisi ile kullanlabilecek btn parametrelerin kullanm ve
aklamas verilmitir.

Parametre Kullanm

Kaynak dosyasndaki XML yorumlarn ayrtrarak farkl bir


dosyaya kaydetmek iin kullanlan bir parametredir.
/doc:dosya_ismi Hatrlayacanz zere C# ile yazlm kaynak kodda ///
karakterlerinden sonra XML formatnda yorum
yazlabilmektedir.

Kaynak kodun derlenmesini salar ancak herhangi bir


/nooutput altrlabilir dosya oluturmaz. Bu parametre daha ok
kaynak kodda hata ayklama iin kullanlmaktadr.

Derleme ilemi srasnda kaynak kodda herhangi bir


/optimize
optimizasyonun yaplp yaplmayacan belirten bir
/optimize+
parametredir. optimize ile optimize+ parametresi
/optimize-
edeerdedir.

Daha nce /module parametresi ile oluturulan modllerin


herhangi bir altrlabilir dosyaya eklenmesi amacyla
/addmodule:modl_dosyas
kullanlr. Birden fazla modl dosyasn eklemek iin ;
karakteri ile modl dosyalarn ayrmak gerekir.

.NET'in standart ktphanesi olan System.dll'in otomatik


olarak derlenecek koda eklenip eklenmemesini belirten
/nostdlib
parametredir. Eer System.dll'i kendi kaynak dosyamzda
/nostdlib+
kullanmayacaksak burdaki snflar kendimiz oluturmalyz.
/nostdlib-
ook nadir kullanlabilecek bir parametredir. /nostdlib ile
/nostdlib+ parametresi edeerdedir.

/reference:assembly_adi Baka bir assembly dosyasna ait mata verilere referans


vermek iin kullanlan parametredir. Assembly'nin bulunduu
yada yer greceli adres olabilecei gibi tam adres de olabilir. Eer
birden fazla referans dosyas belirtilecekse ; karakteri ile
/r:assembly_adi ayrlmaldr.

Derleme zamannda nilemci sembol oluturmak iin


/define:SEMBOL
kullanlr. Kaynak kod ierisinden yaplan #define n ilemci
/d:SEMBOL
komutuna karlk gelmektedir.

Derleme ilemi srasnda verilecek uyarlarn derecesini


belirlemek iin kullanlan parametredir. Eer btn uyarlarn
/warn:<0,1,2,3,4> gsterilmesini istiyorsak /warn:4 eklinde kullanmalyz.
/w:<0,1,2,3,4> /warn:0 parametresi ise hibir uyarnn grntlenmemesini
salar. 0 ile 4 arasndaki deerler ise farkl tipteki uyarlarn
gsterilip gsterilmemesini salar.

Derleme srasndaki uyarlarn hata gibi ilenmesini salar.


/warnaserror Bu genellikle idealist programclarn kulland bir
/warnaserror+ parametredir. Eer uyar verecek bir durum varsa kodun
/warnaserror- derlenmemesi salanr. /warnaserror ile /warnaserror+
edeerdedir.

/nowarn:uyar_numaras Belirtilen numaral uyarnn derleme srasnda verilmemesi


iin bu parametre kullanlr. Eer birden fazla uyarnn
verilmemesini istiyorsak uyar numaralarn ; karakteril ile
ayrmamz gerekmektedir.

Derleme sonrasnda eer herhangi bir dosyada hata var ise


/fullpaths hatann olutuu dosyann tam adresinin hata ile
belirtilmesini salayan parametredir.

Hata ayklamada kullanlacak dosyalarn oluturulmas iin


kullanlan pjarametredir. Eer debugging ilemini aktif hale
getirmek istiyorsak bu parametreyi kullanmamz gerekir.
/debug /debug ve /debug+ parametreleri edeerdedir. Hata
/debug+ ayklama ilemi varsaylan olarak aktif durumda deildir.
/debug- /debug parametresinin ayrca full ve pdbonly eklinde iki
seenei vardr. Eer full seecei /debug:full eklinde
yazlrsa hata ayklac program altrlan program ile
ilikilendirilir.

Aritmetik tama ilemlerinde istisnai bir durumun oluup


olumayacan bildiren parametredir. Varsaylan olarak bu
/checked
aktif durumda deildir. Kaynak kod ierisinde bu ilemi
/checked+
checked anahtar szcklerini kullanarakta yapabiliriz. Eer
/checked-
taam oldugunda istisnai durumun olumasn istiyorsak
/checked yada /checked+ parametresini kullanmalyz.

Derleme srasnda kaynak kodda oluabilecek problemlerin


ve bu problemlerin nerilen zmlerinin belirtilen dosyaya
/bugreport:dosya_adi
yazdrlmasn salayan parametredir. Bu parametre
ilebelirtilen dosyaya eitli derleme ktlarda eklenir.

Kaynak kodda unsafe anatar szcnn kullanmn geerli


klnmasn salayacak parametredir. Gstericileri kullanmak
/unsafe
iin unsafe anahtar szcn kullanmamz gerektiini
hatrlayn.

Derleme ilemine katlacak kaynak kodlarn alt klasrlerde


aranmasn salayacak parametrelerdir. dir seenei ile
aramaya balanacak klasr belirtilir. Bu seenek ile belirtilen
/recurse:dir
klasr projenin varsaylan alma kalsrdr. Eer file
/recurse:file
seenei kullanlrsa bu durumda belirtilen dosya iin arama
yaplacaktr. Bu seenekte wildcard dediimiz * karakteri
kullanlabilmektedir.

Eer kaynak kod dosyamzda birden fazla Main() metodu var


ise programmzn hangi snftaki Main dosyasndan
/main:snf_adi balayacan belirten parametredir. Bu da kaynak
kodumuzda birden fazla Main metodunun bulunabileceinin
gstergesidir.

Derleme sonrasnda ekranda gsterilen derleyici bilgilerinin


/nologo kullancya gsterilmemesini salayan parametredir. Kanmca
ok faydal olmayan bir parametredir.

/help
Derleyici parametreleri ile ilgili yardm bilgilerinin
yada
grntlenmesini salayan parametrelerdir.
/?

/incremental Derleme ileminin optimize edilmi biimde meydana


/incremental+
gelmesini salayan parametrelerdir. yleki, bir nceki
/incremental-
derleme bilgileri .dbg ve .pdb dosylarnda tutularak yeni
derleme ilemlerinde sadece deitirilen metotlarn yeninden
yada
derlenmesi salanr. Farkl iki derleme ilemi arasndaki
farklar ise .incr dosyasnda saklanr. Varsaylan olarak bu
/incr
parametre aktif durumda deildir. /incremental ile
/incr+
/incremental+ parametreleri edeerdedir.
/incr-

Derleme ilemlerine katlacak kaynak kod dosyalar iin bir


karakter kodlamas numaras alan parametredir. Bu
/codepage:id_no parametre daha ok kaynak kod dosyalarndaki karakterlerin
sizin sisteminizde bulunmayan karakter kodlamasna denk
dt durumlarda kullanlr.

Yklenecek DLL lerin belirlenecek bir adresten itibaren


/baseaddress:adres bellee yklenmesini salar. adres deeri 8,10 yada 16 lk
say dzeninde olabilir.

Baz derleyici parametrelerini otomatik olarak derleyiciye


@dosya_adi bildirmek iin bu parametrelerin nceden yazld dosyay
bildirmek iin kullanlan parametredir.

/linkresource:dosya_adi
Belirtilen .NET kaynak(resource) dosyasna bir balant
oluturmak iin bu parametreler kullanlabilir.
/linkres:dosya_adi

/resource:dosya_adi Belirtilen .NET kaynak(resource) dosyasn kt dosyasna


gmmek iin kullanlan parametredir. Birden fazla kaynak
/res:dosya_adi dosyas gmlecekse ; karakteri ile ayrmak gerekir.

Belirtilen Win32 ikon dosyasn kt dosyasna eklemek iin


/win32icon:dosya_adi
kullanlan parametredir.

Belirtilen Win32 kaynak(resource) dosyasn(.res) kt


/win32res:dosya_adi
dosyasna eklemek iin kullanlan parametredir.

Bu yazda C# komut derleyicisinin paramtrelerini ve kullanmlarn inceledik. Yukardaki


tablonun sizin iin iyi bir referans kayna olacan umuyorum.

Boxing(Kutulamak) ve Unboxing(Kutuyu Kaldrmak)


Bugnk makalemizde, Boxing ve Unboxing kavramlarn incelemeye alacaz. Boxing,
deer trnden bir deikeni referans trnden bir nesneye aktarmaktr. Unboxing ilemi
ise bunun tam tersidir. Yani referans tr deikenin iaret ettii deeri tekrar , deer
tr bir deikene aktarmaktr. Bu tanmlarda karmza kan ve bilmemiz gereken en
nemli noktalar, deer tr deikenler ile referans tr nesnelerin bellekte tutulu
ekilleridir.

.Net ortamnda iki tr veri tipi vardr. Referans tipleri (reference type) ve deer tipleri
(value type). ki veri trnn bellekte farkl ekillerde tutulmalar nedeni ile boxing ve
unboxing ilemleri gndeme gelmitir. Bu nedenle ncelikle bu iki farkl veri tipinin
bellekte tutulu ekillerini iyice anlamamz gerekmektedir.

Bu anlamda karmza iki nemli bellek blgesi kar. Yn (stack) ve bek(heap). Deer
tipi deikenler, rnein bir integer deiken vb.. bellein stack ad verilen ksmnda
tutulurlar. .Nette yer alan deer trleri aadaki tabloda yer almaktadr. Bu tiplerin
stack blegesinde nasl tutulduuna ilikin aklayc ekli de aada grebilirsiniz.

Value type ( Deer Tipler)

bool long

byte sbyte

char short

decimal Struct ( Yaplar )

double uint

Enum ( Numaralandrclar ) ulong

float ushort

int

Tablo 1. Deer Tipleri

ekil 1. Deer Tiplerinin Bellekte Tutuluu

ekildende grld gibi, Deer Trleri bellekte, Stack dediimiz blgede tutulurlar.
imdi buraya kadar anlalmayan bir ey yok. lgin olan reference( bavuru) tiplerinin
bellekte nasl tutulduudur. Adndanda anlald gibi reference tipleri asl veriye bir
bavuru ierirler. rnein snflardan trettiimiz nesneler bu tiplerdendir. Dier bavuru
tipleri ise aadaki tabloda yer almakdadr.

Reference Type
( Bavuru Tipleri )
Class ( snflar )
Interface
(arayzler )
Delegate ( delegeler
)

Object

String

Tablo 2. Bavuru Tipleri

imdi gelin bavuru trlerinin bellekte nasl tutulduklarna bakalm.

ekil 2. Bavuru tiplerinin bellekte tutuluu.

Grld gibi,bavuru tipleri hakikatende isimlerinin layn vermekteler. Nitekim asl


veriler bekte tutulurken ynda bu verilere bir bavuru yer almaktadr.

ki veri tr arasndaki bir farkta bu verilerle iimiz bittiinde geri iade edili ekilleridir.
Deer trleri ile iimiz bittiinde bunlarn ynda kapladklar alanlar otomatik olarak
yna geri verilir. Ancak referans trlerinde sadece yndaki bavuru sisteme geri
veririlir. Verilerin tutulduu bekteki alanlar, Garbage Collectorun denetimindedirler ve
ne zaman sisteme iade edilicekleri tam olarak bilinmez. Bu ayr bir konu olmakla beraber
olduka karmaktr. lerleyen makalelerimizde bu konudan da bahsetmeye alacam.

Deer trleri ile bavuru trleri arasndaki bu temel farktan sonra gelelim asl
konumuza. .NETte her snf aslnda en st snf olan Object snfndan trer. Yani her snf
aslnda System.Object snfndan kaltm yolu ile otomatik olarak tretilmi olur. Sorun
object gibi referans bir tre, deer tipi bir deerin aktarlmasnda yaanr. .NETte herey
aslnda birer nesne olarak dnlebilir. Bir deer trn bir nesneye atamaya
altmzda, deer trnn ierdii verinin bir kopyasnn yndan alnp, bee
tanmas ve nesnenin bu veri kopyasna bavurmas gerekmektedir. te bu olay
kutulama ( boxing ) olarak adlandrlr. Bu durumu minik bir rnek ile inceleyelim.
using System;

namespace boxunbox
{
class Class1
{
static void Main(string[] args)
{
double db=509809232323;
object obj;

obj=db;

Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());
db+=1;
Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());
}
}
}

Kodumuzun almasn inceleyelim. Db isimli double deikenimiz bir deer tipidir.


rnekte bu deer tipini object tipinden bir nesneye aktaryoruz. Bu halde bu deerler
ierisindeki verileri ekrana yazdryoruz. Sonra db deerimizi 1 arttryor ve tekrar bu
deerlerin ieriini ekrana yazdryoruz. te sonu;

ekil 3 Boxing lemi

Grld gibi db deikenine yaplan arttrm object trnden obj nesnemize


yansmamtr. nk boxing ilemi sonucu, obj nesnesi , db deerinin bekteki
kopyasna bavurmaktadr. Oysaki artm db deikeninin ynda yer alan orjinal deeri
zerinde gereklemektedir. Bu ilemi aklayan ekil aada yer almaktadr.

ekil 4. Boxing lemi


Boxing ilemi otomatik olarak yaplan bir ilemdir. Ancak UnBoxing ileminde durum biraz
daha deiir. Bu kez , bavuru nesnemizin iaret ettii veriyi bekten alp yndaki bir
deer tipi alan olarak kopyalanmas sz konusudur. te burada tip uyumazl denen
bir kavramla karlarz. bekten, yna kopylanacak olan verinin, ynda kendisi iin
ayrlan yerin ayn tipte olmas veya bekteki tipi ierebilecek tipte olmas gerekmektedir.
rnein yukardaki rneimize unboxing ilemini uygulayalm. Bu kez integer tipte bir
deer trne atama gerekletirelim.

using System;

namespace boxunbox
{
class Class1
{
static void Main(string[] args)
{
double db=509809232323;
object obj;

obj=db;

Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());
db+=1;
Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());

int intDb;
intDb=(int)obj;
Console.WriteLine(intDb.ToString());

}
}
}

Bu kodu altrdmzda InvalidCastException istisnasnn frlatlacan grceksiniz.


n referenas tipimizin bekte bavurduu veri tipi integer bir deer iin fazla byktr.
Bu noktada (int) ile aka dnm bildirmi olsak dahi bu hatay alrz.

ekil 5. InvalidCastException stisnas

Ancak kk tipi, byk tipe dntrmek gibi bir serbestliimiz vardr. rnein,

using System;

namespace boxunbox
{
class Class1
{
static void Main(string[] args)
{
double db=509809232323;
object obj;

obj=db;

Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());
db+=1;
Console.WriteLine(db.ToString());
Console.WriteLine(obj.ToString());

/*int intDb;
intDb=(int)obj;
Console.WriteLine(intDb.ToString());*/

double dobDb;
dobDb=(double)obj;
Console.WriteLine(dobDb.ToString());
}
}
}

Bu durumda kodumuz sorunsuz alacaktr. nk ynda yer alan veri tipi daha byk
boyutlu bir deer trnn iine koyulabilir. te buradaki aktarm ilemi unboxing olarak
isimlendirilmitir. Yani boxing ilemi ile kutulanm bir veri kmesi, bekten alnp tekrar
yndaki bir alana konulmu, dolaysyla kutudan kartlmtr. Olayn grafiksel
aklamas aadaki gibidir.

ekil 6. Unboxing lemi

Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dileiyle
hepinize mutlu gnler dilerim.
C# ile ok Kanall(Multithread) Uygulamalar 1

Bugnk makelemiz ile birlikte threading kavramn en basit haliyle tanmaya alacaz,
sonraki makalelerimizde de threading kavramn daha st seviyede ilemeye alacaz.

Bugn hepimiz bilgisayar bandayaken ayn anda pek ok uygulamann sorunsuz bir
ekilde altn grrz. Bir belge yazarken, ayn zamanda mzik dinleyebilir, internet
zerinden program indirebilir ve sistemimizin kaynaklarnn elverdii lde uygulamayla
ezamanl olarak alabiliriz. Bu bize, gnmz ilemcilerinin ve zerlerinde alan
iletim sistemlerinin ne kadar yetenekli oluunu gsterir. Gsterir mi acaba?

Aslnda tek ilemcili makineler gnmzn modern sihirbazlar gibidirler. Gerekte alan
uygulamalarn tm ilemleri ayn anda gereklememektedir. Fakat ilemciler ylesine
byk saat hzlarna sahiptirlerki. ilemcinin yapt, altrlan uygulamaya ait ilemleri i
paracacklar(thread) halinde ele almaktr. Her bir i paraca bir ilemin birden fazla
paraya blnmesinden oluur. lemciler her i parac iin bir zaman dilimi belirler. T
zaman diliminde bir ilem parac yrtlr ve bu zaman dilim bittiinde ilem parac
geici bir sre iin durur. Ardndan kuyrukta bekleyen dier i paraca baka bir zaman
dilimi iinde altrlr. Bu bylece devam ederken, ilemcimiz her i paracna geri
dner ve tm i paracklar sra sra altrlr. Dedik ya, ilemciler bu ilemleri ok
yksek saat ve frekans hznda gerekletirir. te bu yksek hz nedeniyle tm bu olaylar
saniyenin milyon srelerinde gerekleir ve sanki tm bu uygulamalar ayn anda alyor
hissi verilir.

Gerektende uygulamalar birbirleriyle paralel olarak ve e zamanl altrmak aslnda


birden fazla ilemciye sahip sistemler iin gereklenir.

Bugnk uygulamamz ile, bahsetmi olduumuz threading kavramna basit bir giri
yapcaz. Nitekim threading kavram ve teknikleri, uygulamalarda profesyonel olarak kod
yazmay gerektirir. Daha ak ekilde sylemek gerekirse bir uygulama iinde yazdmz
kodlara uygulayacamz thread'ler her zaman avantaj salamaz. Baz durumlarda
dezavantaja dnp programlarn daha yava almasna neden olabilir. Nitekim
thread'lerin alma mantn iyi kavramak ve uygulamalarda titiz davranmak gerekir.

rnein thread'lerin zaman dilimlerine blndklerinde sistemin nasl bir nceki veya
daha nceki thread'i altrabildiini dnelim. lemci zaman dilimini dolduran bir
thread iin donanmda bir kesme iareti brakr, bunun ardndan thread'e ait bir takm
bilgiler bellee yazlr ve sonra bu bellek blgesinde Context ad verilen bir veri yapsna
depolanr. Sistem bu thread'e dnecei zaman Context'te yer alan bilgilere bakar ve
hangi donanmn kesme sinyali verdiini bulur. Ardndan bu sinyal alr ve ilemin bir
sonraki ilem paracnn alaca zaman dilimine girilir. Eer thread ilemini ok fazla
kullanrsanz bu durumda bellek kaynaklarnda fazlas ile tketmi olursunuz. Bu
thread'leri neden titiz bir ekilde programlamamz gerektiini anlatan nedenlerden sadece
birisidir. yleki yanl yaplan thread programlamalar sistemlerin kilitlenmesine dahi yol
aacaktr.

Threading grdnz gibi ok basit olmayan bir kavramdr. Bu nedenle olay daha iyi
aklayabileceimi dndm rneklerime gemek istiyorum. Uygulamamzn formu
aadaki ekildeki gibi olacak.

ekil 1. Form Tasarmmz.

imdi kodlarmz yazalm.

public void z1()


{

for(int i=1;i<60;++i)
{
zaman1.Value+=1;
for(int j=1;j<10000000;++j)
{
j+=1;
}
}
}

public void z2()


{
for(int k=1;k<100;++k)
{
zaman2.Value+=1;

for(int j=1;j<25000000;++j)
{
j+=1;
}
}
}

private void btnBaslat_Click(object sender, System.EventArgs e)


{
z1();
z2();
}

Program kodlarmz ksaca aklayalm. z1 ve z2 isimli metodlarmz progressBar


kontrolllerimizin deerlerini belirli zaman aralklaryla arttryorlar. Bu ilemleri
geekletirmek iin, Balat balkl butonumuza tklyoruz. Burada nce z1 daha sonrada
z2 isimli metodumuz altrlyor. Bunun sonucu olarak nce zaman1 isimli progressBar
kontrolmz doluyor ve dolmas bittikten sonra zaman2 isimli progressBar
kontrolmzn value deeri arttrlarak dolduruluyor.

imdi bu programn yle almasn istediimizi dnelim. Her iki progressBar'da ayn
anda dolmaya balasnlar. stediimiz zaman z1 ve z2 metodlarnn almasn
durduralm ve tekrar balatabilelim. Tekrar balattmzda ise progressBar'lar kaldklar
yerden dolmaya devam etsinler. Szn ettiimiz aslnda her iki metodunda ayn anda
almasdr. te bu ii baarmak iin bu metodlar sisteme birer i paraca ( thread )
olarak tantmal ve bu thread'leri ynetmeliyiz.

.Net ortamnda thread'ler iin System.Threading isim uzayn kullanrz. ncelikle


programmza bu isim uzayn ekliyoruz. Ardndan z1 ve z2 metodlarn birer i parac
olarak tanmlamamz gerekiyor. te kodlarmz.

public void z1()


{

for(int i=1;i<60;++i)
{
zaman1.Value+=1;

for(int j=1;j<10000000;++j)
{
j+=1;
}
}
}

public void z2()


{
for(int k=1;k<100;++k)
{
zaman2.Value+=1;

for(int j=1;j<25000000;++j)
{
j+=1;
}
}
}

private void btnBaslat_Click(object sender, System.EventArgs e)


{
z1();
z2();
}

ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;

private void btnBaslat_Click(object sender, System.EventArgs e)


{
ts1=new ThreadStart(z1); /* ThreadStart i parac olarak kullanlcak metod iin
bir temsilcidir. Bu metod iin tanmlanacak thread snf nesnesi iin paramtere olacak ve
bu nesnenin hangi metodu i parac olarak greceini belirtecektir. */

ts2=new ThreadStart(z2);

t1=new Thread(ts1);

t2=new Thread(ts2);

t1.Start(); /* paran Start metodu ile balatyoruz. */

t2.Start();

btnBaslat.Enabled=false;
}

private void btnDurdur_Click(object sender, System.EventArgs e)


{
t1.Suspend(); /* paraca geici bir sre iin uyku moduna geer. Uyku
modundaki bir i paracan tekrar aktif hale getirmek iin Resume metodu kullanlr. */

t2.Suspend();
}

private void btnDevam_Click(object sender, System.EventArgs e)


{
t1.Resume(); /* Uyku modundaki i paracnn kald yerden devam etmesini
salar. */

t2.Resume();
}

private void btnKapat_Click(object sender, System.EventArgs e)


{
if(t1.IsAlive) /* Eer i paracklar henz sonlanmamsa bunlar canldr ve IsAlive
zellikleri true deerine sahiptir. Programmzda ilk biten i parac t1 olucandan onun
bitip bitmediini kontrol ediyoruz. Eer bitmi ise programmz close metodu sayesinde
kapatlabilir. */
{
MessageBox.Show("alan threadler var program sonlanamaz.");
}
else
{
this.Close();
}
}

Uygulamamzda z1 ve z2 isimli metodlarmz birer i parac (thread) haline getirdik.


Bunun iin System.Threding isim uzaynda yer alan ThreadStart ve Thread snflarn
kullandk. ThreadStart snf , i parac olucak metodu temsil eden bir delegate gibi
davranr. paracklarn balatacak(start), durdurucak(suspend), devam
ettirecek(resume) thread nesnelerimizi tanmladmz yapc metod ThreadStart
snfndan bir temsilciyi parametre olarak alr. Sonu itibariyle kullanc Balat balkl
buton kontrolne tkladnda, her iki progressBar kontrolnnde ayn zamanda dolmaya
baladn ve ilerlediklerini grrz. Bu aamada Durdur isimli button kontrolne
tklarsak her iki progressBar'n ilerleyiinin durduunu grrz. Nitekim i paracklarnn
Suspend metodu arlm ve metodlarn altrlmas durdurulmutur.

ekil 2. Suspend metodu sonras.

Bu andan sonra tekrar Devam buton kontrolne tklarsak thread nesnelerimiz Resume
metodu sayesinde almalarna kaldklar yerden devam ediceklerdir. Dolaysyla
progressBar kontrolllerimizde kaldklar yerden dolmaya devam ederler. Bu srada
program kapatmaya almamz henz sonlanmam i paracklar nedeni ile hataya
neden olur. Bu nedenle Kapat buton kontrolnde IsAlive zellii ile i paracklarnn canl
olup olmad yani metodlarn almaya devam edip etmedii kontrol edilir. Eer
sonlanmamsa kullanc aadaki mesaj kutusu ile uyarlr.

ekil 3. Paracklar henz sonlanmam ise.

Evet geldik Threading ile ilgili makale dizimizin ilk blmnn sonuna . Bir sonraki
makalemizde Threading kavramn daha da derinlemesine incelemeye alacaz.
Hepinize mutlu gnler dilerim.

C# ile ok Kanall(Multithread) Uygulamalar 2

Bugnk makalemizde i paracklarnn belli sreler boyunca nasl


durgunlatrlabileceini yani etkisizletirebilieceimizi ilemeye alcaz. Ayrca i
paracklarnn henz sonlanmadan nce nasl yokedildiklerini greceiz.

Bir nceki makalemizde hatrlayacak olursanz, i paracklar haline getirdiimiz


metodlarmzda ilemeleri yavalatmak amac ile baz dngler kullanmtk. Gerek
hayatta ou zaman, i paracklarnn belirli sreler boyunca beklemesini ve sre sona
erdiinde tekrardan ilemelerine kald yerden devam etmesini istediimiz durumlar
olabilir. nceki makalemizde kullandmz Suspend metodu ile ilgili i paracn
durdurabiliyorduk. Bu ilgili i paracklarn geici sre ile bekletmenin yollarndan
birisidir. Ancak byle bir durumda bekletilen i paracn tekrar hareketlendirmek
kullancnn Resume metodunu altrmas ile olabilir. Oysaki biz, i paracmzn belli
bir sre boyunca beklemsini isteyebiliriz. te byle bir durumda Sleep metodunu
kullanrz. Bu metodun iki adet overload edilmi versiyonu vardr.

public static void Sleep(int);

public static void Sleep(TimeSpan);


Biz bugnk uygulamamzda ilk versiyonu kullanacaz. Bu versiyonda metodumuz
parametre olarak int tipinde bir deer almaktadr. Bu deer milisaniye cinsinden sreyi
bildirir. Metodun Static bir metod olduu dikkatinizi ekmi olmaldr. Static bir metod
olmas nedeni ile, Snf ad ile birlikte arlmak zorundadr. Yani herhangibir thread
nesnesinin ardndan Sleep metodunu yazamassnz. Peki o halde bekleme sresinin hangi
i parac iin geerli olacan nereden bileceiz. Bu nedenle, bu metod i parac
olarak tanmlanan metod bloklar ierisinde kullanlr. Konuyu rnek zerinden inceleyince
daha iyi anlayacaz. Metod altrldnda parametresinde belirtilen sre boyunca
geerli i paracn bekletir. Bu bekleme dier paracklarn almasn engellemez.
Sre sona erince, i paracmz almasna devam edicektir. imdi dilerseniz rnek bir
uygulama gelitirelim ve konuya aklk getirmeye alalm.

Formumuzda bu kez adet ProgressBar kontrolmz var. Baslat balkl dmeye


bastmzda i paracklarmz alyor ve tm ProgressBar'lar ayn anda deiik sreler
ile ilerliyor. Burada i paracklar olarak belirlediimiz metodlarda kullandmz Sleep
metodlarna dikkat edelim. Tabi kodlarmz yazmadan nce System.Threading isim
uzayn eklemeyi unutmayalm.

ekil 1. Form Tasarmmz.

public void pb1Ileri()

{
for(int i=1;i<100;++i)
{
pb1.Value+=1;
Thread.Sleep(800);
}
}

public void pb2Ileri()


{
for(int i=1;i<100;++i)
{
pb2.Value+=1;
Thread.Sleep(500); /* Metodumuz i parac olarak baladktan sonra dng
iince her bir artmdan sonra 500 milisaniye bekler. */
}
}

public void pb3Ileri()

{
for(int i=1;i<100;++i)
{
pb3.Value+=1;
Thread.Sleep(300);
}
}

/* ThreadStart temsilcilerimiz ve Thread nesnelerimizi tanmlyoruz. */

ThreadStart ts1;
ThreadStart ts2;
ThreadStart ts3;

Thread t1;
Thread t2;
Thread t3;

private void btnBaslat_Click(object sender, System.EventArgs e)


{
/* ThreadStart temsilcilerimizi ve Thread nesnelerimizi oluturuyoruz. */
ts1=new ThreadStart(pb1Ileri);

ts2=new ThreadStart(pb2Ileri);

ts3=new ThreadStart(pb3Ileri);

t1=new Thread(ts1);

t2=new Thread(ts2);

t3=new Thread(ts3);

/* Thread nesnelerimizi start metodu ile balatyoruz. */

t1.Start();

t2.Start();

t3.Start();
}

Uygulamamz altralm. Her i parac Sleep metodu ile belirtilen sre kadar
beklemeler ile almasna devam eder. rnein pb3Ileri metodunda i paracmz
ProgressBar'n Value deerini her bir arttrdktan sonra 300 milisaniye bekler ve dng bir
sonraki deerden itibaren devam eder. Sleep metodu ile Suspend metodlar arasnda
nemli bir ba daha vardr. Bildiiniz gibi Suspend metodu ilede bir i paracn
durdurabilmekteyiz. Ancak bu i paracn tekrar devam ettirmek iin Resume
metodunu kullanmamz gerekiyor. Bu iki yntem arasndaki fark idi. Dieri nemli olgu
ise udur; bir i parac metodu iinde, Sleep metodunu kullanm olsak bile, programn
herhangibir yerinden bu i parac ile ilgili Thread nesnesinin Suspend metodunu
ardmzda, bu i parac yine duracaktr. Bu andan itibaren Sleep metodu
geerliliini, bu i parac iin tekrardan Resume metodu arlncaya kadar
kaybedecektir. Resume arsndan sonra ise Sleep metodlar yine ilemeye devam eder.
ekil 2. Sleep Metodunun almas

imdi gelelim dier konumuz olan bir i paracnn nasl yok edileceine. Bir i
paracn yoketmek amac ile Abort metodunu kullanabiliriz. Bu metod altrldnda
derleyici aslnda bir ThreadAbortException istisnas retir ve i paracn yoketmeye
zorlar. Abort yntemi arldnda, ilgili i paracn tekrar resume gibi bir komutla
balatamayz. Dier yandan Abort metodu i parac ile ilgili metod iin
ThreadAbortException istisnasn frlattnda (throw) , bu metod iinde bir
try..catch..finally korumal blounda bu istisnay yakalayabiliriz veya Catch blounda hi
bir ey yazmas isek program kodumuz kesilmeden almasna devam edicektir.

Abort metodu ile bir i parac sonlandrldnda, bu i paracn Start metodu ile
tekrar altrmak istersek;

"ThreadStateException' Additional information: Thread is running or terminated; it can


not restart."

hatasn alrz. Yani i paracmz tekrar batan balatmak gibi bir ansmz yoktur.

imdi bu metodu inceleyeceimiz bir kod yazalm. Yukardaki uygulamamz aadaki


ekilde gelitirelim.

ekil 3. Form Tasarmmz.

Kodlarmza geelim.

public void pb1Ileri()

{
try
{
for(int i=1;i<100;++i)
{
pb1.Value+=1;
Thread.Sleep(800);
}
}
catch(ThreadAbortException hata)
{

}
finally
{

}
}

public void pb2Ileri()


{
for(int i=1;i<100;++i)
{
pb2.Value+=1;
Thread.Sleep(500); /* Metodumuz i parac olarak baladktan sonra dng
iince her bir artmdan sonra 500 milisaniye bekler. */
}
}

public void pb3Ileri()

{
for(int i=1;i<100;++i)
{
pb3.Value+=1;
Thread.Sleep(300);
}
}

/* ThreadStart temsilcilerimiz ve Thread nesnelerimizi tanmlyoruz. */

ThreadStart ts1;

ThreadStart ts2;

ThreadStart ts3;

Thread t1;

Thread t2;

Thread t3;

private void btnBaslat_Click(object sender, System.EventArgs e)


{
/* ThreadStart temsilcilerimizi ve Thread nesnelerimizi oluturuyoruz. */

ts1=new ThreadStart(pb1Ileri);

ts2=new ThreadStart(pb2Ileri);

ts3=new ThreadStart(pb3Ileri);

t1=new Thread(ts1);

t2=new Thread(ts2);

t3=new Thread(ts3);

/* Thread nesnelerimizi start metodu ile balatyoruz. */

t1.Start();

t2.Start();

t3.Start();

btnBaslat.Enabled=false;

btnDurdur.Enabled=true;

btnDevam.Enabled=false;
}

private void btnDurdur_Click(object sender, System.EventArgs e)


{
t1.Abort(); /* t1 isimli Thread'imizi yokediyoruz. Dolaysyla pb1Ileri isimli
metodumuzunda almasn sonlandrm oluyoruz. */

/* Dier iki i paracn uyutuyoruz. */

t2.Suspend();

t3.Suspend();

btnDurdur.Enabled=false;

btnDevam.Enabled=true;
}

private void btnDevam_Click(object sender, System.EventArgs e)


{

/* paracklarn tekrar kaldklar yerden altryoruz. te burada t1 thread


nesnesini Resume metodu ile tekrar kald yerden altramayz. Bu durumda
programmz hataya decektir. Nitekim Abort metodu ile Thread'imiz sonlandrlmtr.
Ayn zamanda Start metodu ile Thread'imizi batanda balatamayz.*/

t2.Resume();

t3.Resume();

btnDurdur.Enabled=true;

btnDevam.Enabled=false;
}

Uygulamamz deneyelim.

ekil 4. Uygulamann almas sonucu.

Deerli okurlarm geldik bir makalemizin daha sonuna. Bir sonraki makalemizde de
Threading konusunu ilemeye devam edeceiz. Hepinize mutlu gnler dilerim.

Visual Basic'ten C#'a Gei

Merhaba, bunca zamandr Visual Basic kullanan biri olarak .NET'e geerken Visual Basic'i
setim. Daha ok Web Programyla ilgilendiim iin internette yyaptm aramalarda aspx
rneklerinin byk bir ounluunun C# ile hazrlandn grdm. Daha sonra baz
makaleler kurcaladm. C#'n gelecein dili olduu fikrine vardm.Elime geen bir ka ufak
kod zerinde inceleme yapmaya baladm. Yaptklarm sizlerle paylamak istedim. Bunu
yaparken VB.Net'i orta seviye bilen, C#' hi bilmeyen programclar dnerek
hazrladm.

lk dikkatimizi ekecek olan Syntax(Szdizimi) olacaktr. VB ile en nemli farkllk buradan


geliyor. Bu noktada baz nemli noktalar aklayacam.
Yorum satrlar: Yorum yazmak iin iki farkl metod var. lki tek satr dieri blok halinde
yazlr.

//Bu bir satrlk yorumdur.


/* Bu da blok halinde
Hazrlanm bir yorumdur.*/

Yukarda bulunan her iki rneimiz de derleyici tarafndan gzard edilecektir. Yorum
kullanmak kodlarnzn anlabilirliini arttrd iin mutlaka kullanlmaldr. Bunu da
belirtmeden gemeyim.

Deikenlerimizi VB'ye gre farkl ekillerde tanmlyoruz. VB'de deikenlerle aranzda


problem yoksa emin olun C#'ta da olmayacaktr.

int a;

ile tek bir deiken tanmlayabiliyoruz. Ayn trde bir ka deiken tanmlamak iin

int a,b,c;

kullanabilirsiniz. Visual Basic'e .Net ile eklenen deikene isim atanrken deer belirtmeyi
de C# da kullanabiliyoruz.

int a=3;

"Merhaba dnya" demek iin ilk admlarmz atalm. lk olarak VS.Net ile Merhaba dnya
demeyi renelim.VS.Net ile yeni bir proje an ama bu sefer C# projesi olsun. Formun
ortasna kocaman bir tu koyalm. ift tklayp alttaki koda gre uyarlayn.

private void button1_Click(object sender, System.EventArgs e)


{
MessageBox.Show("Selam","Merhaba Dnya");
}

lk satrda button1'in click olay olduunu belirttik. Tahmin ettiiniz gibi : bir mesaj
kutusu alacak ve merhaba dnya diyecek. Merhaba Dnya bal olacak. inde sadece
selam yazacak.
Hemen gzmze arpanlar Ssl parantez ve noktal virgl olmutur.C#'da her olay
ssl parantez iinde yer alyor. Bir if dngs veya rnekteki buttonclick olay. Ve
hemen her satrn sonunda noktal virgl konuyor. Eer bilgisayarnz kod yazarken size
syntax hatas verirse ilk bunlar kontrol edin. Almas gerekten zor oluyor.

Bir daha ki konuda konular biraz daha toplayp bir uygulama ve bir aspx sayfas
hazrlayacaz.

Herkese almalarnda baarlar dilerim.

Turul ARAS
C# ile ok Kanall(Multithread) Uygulamalar 3

paracklarn ilediimiz yaz dizimizin bu nc makalesinde, i paracklarnn birbirlerine


kar ncelik durumlarn incelemeye alacaz. paracklar olarak tanmladmz metodlarn
alma ralarn, sahip olduklar neme gre deitirmek durumunda kalabiliriz. Normal artlar
altnda, oluturduumuz her bir i parac nesnesi ayn ve eit ncelie sahiptir. Bu ncelik deeri
Normal olarak tanmlanmtr. Bir i paracnn nceliini deitirmek istediimizde, Priority
zelliinin deerini deitiririz. Priority zelliinin .NET Framework'teki tanm aadaki gibidir.

public ThreadPriority Priority {get; set;}

zelliimiz ThreadPriority numaralandrcs (enumerator) tipinden deerler almaktadr. Bu deerler


aadaki tabloda verilmitir.

ncelik Deeri

Highest

AboveNormal
Normal

BelowNormal

Lowest

Tablo 1. ncelik(Priority) Deerleri

Programlarmz yazarken, i paracklarnn alma ekli verilen ncelik deerlerine gre


deiecektir. Elbette tahmin edeceiniz gibi yksek ncelik deerlerine sahip olan i paracklarnn
iaret ettikleri metodlar dierlerine gre daha sk aralklarda arlacak, dolaysyla dk ncelikli
i paracklarnn referans ettii metodlar daha ge sonlanacaktr. imdi olay daha iyi
canlandrabilmek iin aadaki rneimizi gelitirelim.

Daha nceden sylediimiz gibi, bir i paracnn Priority zelliine her hangibir deer vermez
isek, standart olarak Normal kabul edilir. Buda tm i paracklarnn varsaylan olarak eit
nceliklere sahip olacaklar anlamna gelmektedir. imdi aadaki formumuzu oluturalm.
Uygulamamz iki i paracna sahip. Bu paracklarn iaret ettii metodlardan birisi 1' den 1000' e
kadar sayp bu deerleri bir label kontrolne yazyor. Dieri ise 1000' den 1' e kadar sayp bu
deerleri baka bir label kontrolne yazyor. Formumuzun grnts aadakine benzer olmaldr.

ekil 1. Form Tasarmmz.

imdide program kodlarmz yazalm.

/* Bu metod 1' den 1000' e kadar sayar ve deerleri lblSayac1 isimli label kontrolne yazar.*/
public void Say1()
{
for(int i=1;i<1000;++i)
{
lblSayac1.Text=i.ToString();

lblSayac1.Refresh(); /* Refresh metodu ile label kontrolnn grntsn tazeleriz. Bylece


herbir i deerinin label kontrolnde grlebilmesini salam oluyoruz. */

for(int j=1;j<90000000;++j)
{
j+=1;
}
}
} /* Bu metod 1000' den 1' e kadar sayar ve deerleri lblSayac2 isimli label kontrolne yazar.*/
public void Say2()
{
for(int i=1000;i>=1;i--)
{
lblSayac2.Text=i.ToString();
lblSayac2.Refresh(); for(int j=1;j<45000000;++j)
{
j+=1;
}
}
} /* ThreadStart ve Thread nesnelerimizi tanmlyoruz. */ ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;

private void btnBaslat1_Click(object sender, System.EventArgs e)


{
/* Metodlarmz ThreadStart nesneleri ile ilikilendiriyoruz ve ThreadStart nesnelerimizi
oluturuyoruz.*/
ts1=new ThreadStart(Say1);
ts2=new ThreadStart(Say2);

/* paracklarmz, ilgili metodlarn temsil eden ThreadStart nesnelerimiz ile oluturuyoruz.*/

t1=new Thread(ts1);
t2=new Thread(ts2);
/* paracklarmz altryoruz.*/
t1.Start();
t2.Start();
btnBaslat1.Enabled=false;
btnIptal.Enabled=true;
}

private void btnIptal_Click(object sender, System.EventArgs e)


{
/* paracklarmz iptal ediyoruz. */
t1.Abort();
t2.Abort();
btnBaslat1.Enabled=true;
btnIptal.Enabled=false;
}

private void btnKapat_Click(object sender, System.EventArgs e)


{
/* Uygulamay kapatmak istediimizde, alan i parac olup olmadn kontrol ediyoruz.
Bunun iin i paracklarnn IsAlive zelliinin deerlerine bakyoruz. Nitekim kullancnn,
herhangibir i parac sonlanmadan uygulamay kapatmasn istemiyoruz. Ya iptal etmeli yada
sonlanmalarn beklemeli. ptal ettiimizde yani Abort metodlar altrldnda hatrlayacanz
gibi, i paracklarnn IsAlive deerleri false durumuna dyordu, yani iptal olmu oluyorlard.*/

if((!t1.IsAlive) && (!t2.IsAlive))


{
Close();
}
else
{
MessageBox.Show("Hala kapatlamam i paracklar var. Ltfen bir sre sonra
tekrar deneyin.");
}
}
Uygulamamzda u an iin bir yenilik yok aslnda. Nitekim i paracklarmz iin bir ncelik
ayarlamas yapmadk. nk size gstermek istediim bir husus var. Bir i parac iin
herhangibir ncelik ayar yapmadmzda bu deer varsaylan olarak Normal dir. Dolaysyla her i
parac eit ncelie sahiptir. imdi rneimizi altralm ve kafamza gre bir yerde iptal
edelim.

ekil 2. ncelik deeri Normal.

Ben 11 ye 984 deerinde ilemi iptal ettim. Tekrar i paracklarn Balat balkl butona tklayp
altrrsak ve yine ayn yerde ilemi iptal edersek, ya ayn sonucu alrz yada yakn deerleri elde
ederiz. Nitekim programmz altrdmzda arka planda alan iletim sistemine ait pek ok i
paracda alma sonucunu etkiler. Ancak aa yukar ayn veya yakn deerle ularz. Oysa bu
i paracklarnn ncelik deelerini deitirdiimizde sonularn ok daha farkl olabilieceini
syleyebiliriz. Bunu daha iyi anlayabilmek iin rneimizi gelitirelim ve i paracklarnn ncelik
deerleri ile oynayalm. Formumuzu aadaki gibi tasarlayalm.

ekil 3. Formumuzun yeni tasarm.

Artk i paracklarn balatmadan nce nceliklerini belirleyeceiz ve sonularn incelemeye


alacaz. Kodlarmz u ekilde deitirelim. nemli olan kod satrlarmz, i paracklarnn
Priority zelliklerinin deitii satrlardr.

/* Bu metod 1' den 1000' e kadar sayar ve deerleri lblSayac1 isimli label kontrolne yazar.*/
public void Say1()
{
for(int i=1;i<1000;++i)
{
lblSayac1.Text=i.ToString();
lblSayac1.Refresh(); /* Refresh metodu ile label kontrolnn grntsn tazeleriz.
Bylece herbir i deerinin label kontrolnde grlebilmesini salam oluyoruz. */

for(int j=1;j<90000000;++j)
{
j+=1;
}
}
}

/* Bu metod 1000' den 1' e kadar sayar ve deerleri lblSayac2 isimli label kontrolne yazar.*/
public void Say2()
{
for(int i=1000;i>=1;i--)
{
lblSayac2.Text=i.ToString();
lblSayac2.Refresh();

for(int j=1;j<45000000;++j)
{
j+=1;
}
}
}

ThreadPriority tp1;
/* Priority ncelikleri ThreadPriority tipindedirler. */

ThreadPriority tp2; /* OncelikBelirle metodu, kullancnn TrackBar'da setii deerleri gz nne


alarak, i paracklarnn Priority zelliklerini belirlemektedir. */

public void OncelikBelirle()


{

/* Switch ifadelerinde, TrackBar kontrollnn deerine gre , ThreadPriority deerleri


belirleniyor. */
switch(tbOncelik1.Value)
{
case 1:
{
tp1=ThreadPriority.Lowest; /* En dk ncelik deeri. */
break;
}
case 2:
{
tp1=ThreadPriority.BelowNormal; /* Normalin biraz alt. */
break;
}
case 3:
{
tp1=ThreadPriority.Normal; /* Normal ncelik deeri. Varsaylan deer budur.*/
break;
}

case 4:
{
tp1=ThreadPriority.AboveNormal; /* Normalin biraz st ncelik deeri. */
break;
}
case 5:
{
tp1=ThreadPriority.Highest; /* En st dzey ncelik deeri. */
break;
}

switch(tbOncelik2.Value)
{
case 1:
{
tp2=ThreadPriority.Lowest; /* En dk ncelik deeri. */
break;
}
case 2:
{
tp2=ThreadPriority.BelowNormal; /* Normalin biraz alt. */
break;
}
case 3:
{
tp2=ThreadPriority.Normal; /* Normal ncelik deeri. Varsaylan deer budur.*/
break;
}

case 4:
{
tp2=ThreadPriority.AboveNormal; /* Normalin biraz st ncelik deeri. */
break;
}

case 5:
{
tp2=ThreadPriority.Highest; /* En st dzey ncelik deeri. */
break;
}

/* Paracklarmza ncelik deerleri aktarlyor.*/

t1.Priority=tp1;

t2.Priority=tp2;
}

/* ThreadStart ve Thread nesnelerimizi tanmlyoruz. */

ThreadStart ts1;

ThreadStart ts2;

Thread t1;

Thread t2;

private void btnBaslat1_Click(object sender, System.EventArgs e)


{
/* Metodlarmz ThreadStart nesneleri ile ilikilendiriyoruz ve ThreadStart nesnelerimizi
oluturuyoruz.*/

ts1=new ThreadStart(Say1);

ts2=new ThreadStart(Say2);

/* paracklarmz, ilgili metodlarn temsil eden ThreadStart nesnelerimiz ile


oluturuyoruz.*/

t1=new Thread(ts1);

t2=new Thread(ts2);

OncelikBelirle(); /* ncelik ( Priority ) deerleri, i paracklar Start metodu ile balatlmadan


nce belirlenmelidir. */

/* paracklarmz altryoruz.*/

t1.Start();

t2.Start();

btnBaslat1.Enabled=false;

btnIptal.Enabled=true;

tbOncelik1.Enabled=false;

tbOncelik2.Enabled=false;
}

private void btnIptal_Click(object sender, System.EventArgs e)


{

/* paracklarmz iptal ediyoruz. */

t1.Abort();

t2.Abort();

btnBaslat1.Enabled=true;

btnIptal.Enabled=false;

tbOncelik1.Enabled=true;

tbOncelik2.Enabled=true;
}

private void btnKapat_Click(object sender, System.EventArgs e)


{

/* Uygulamay kapatmak istediimizde, alan i parac olup olmadn kontrol ediyoruz.


Bunun iin i paracklarnn IsAlive zelliinin deerlerine bakyoruz. Nitekim kullancnn,
herhangibir i parac sonlanmadan uygulamay kapatmasn istemiyoruz. Ya iptal etmeli yada
sonlanmalarn beklemeli. ptal ettiimizde yani Abort metodlar altrldnda hatrlayacanz
gibi, i paracklarnn IsAlive deerleri false durumuna dyordu, yani iptal olmu oluyorlard.*/

if((!t1.IsAlive) && (!t2.IsAlive))


{
Close();
}
else
{
MessageBox.Show("Hala kapatlamam i paracklar var. Ltfen bir sre sonra tekrar
deneyin.");
}
}

imdi rneimizi altralm ve birinci i paracmz iin en yksek ncelik deerini (Highest)
ikinci i paracmz iinde en dk ncelik deerini (Lowest) seelim. Sonular aadakine
benzer olucaktr.

ekil 4. nceliklerin etkisi.

Grld gibi ncelikler i paracklarnn almasn olduka etkilemektedir. Geldik bir


makalemizin daha sonuna. Bir sonraki makalemizde i paracklar hakknda ilerlemeye devam
edeceiz. Grmek dileiyle hepinize mutlu gnler dilerim.
XOR Operatr ile Temel Bir ifreleme Algoritmas

ifreleme gnmzde gvenli iletiim iin ok nemli bir konuma gelmitir, uzun yllardan
beri ok fazla ifreleme algortimas gelitirilmitir. Bu ifreleme algoritmalarnn bir
ou .NET snf ktphanesinde zaten varsaylan olarak bulunmaktadr, bu yazda ise
kendi ifreleme algortimalarmz nasl oluturabileceimiz grmek asndan temel bir
ifreleme algoritmasn sizlere gstereceim.

Bir mesajn yada metnin ifrelenmesi genellikle ifrelenecek mesajn eitli operatrler
yardmyla farkl mesajlara dntrlmesi ile olmaktadr. Burada bilmemiz gereken
nokta udur : ifrelenecek mesaj ile ifrelenmi mesajn ayn alfabeden szckleri
iermesidir. rnein ikili(binary) saylardan oluturulan bir mesaj ifrelendii takdirde
yine ikili bir say olacaktr. ifreleme yaplrken genellikle anahtar dedimiz yardmc bir
mesajdan faydalanr. Mesajn ifrelenmesi bu anahtar ile gereklemektedir. Ayn ekilde
ifrelenmi mesajn zlmesinde de bu anahtar kullanlmaktadr. ifreleme ilemi ise bir
yada daha fazla operatr sayesinde yaplmaktadr. Buradaki operatrler tekil bir operatr
olabilecei gibi kullancnn tanmlayaca karmak deikenli operatrler de olabilir.

ifreleme programn yazanlar genellikle ifreyi zen programda yazmak zorunda


kalrlar. Nede olsa ifreler zlmek iindir. zlemeyen ifreli mesajlarn pek bir anlam
olmayaca aktr. Her ne kadar ifreleme ve ifre zme programlar birbirnin tersi de
olsa iki farkl program yazmak yinede zaman kaybettirir. Ayn programn hem ifreleyici
hemde ifre zc olduu bir sistem herhalde hepimizin ilgisini ekecektir. Bu yazda
hem ifre zc hemde ifreleme iine yarayacak zel bir operatr olan XOR(Bitsel zel
Veya) operatrn ve bu operatr kullanarak nasl ifreleyici ve ayn zamanda ifre
zc bir program gelitirebileceimizi inceleyeceiz.

XOR(Bitsel zel Veya) Operatr

"zel veya" operatr iki operand olan bir operatrdr. zel veya operatr ald
operandlarnn btn bitlerini karlkl olarak "zel veya(XOR)" ilemine tutar. sterseniz
biroumzun matematik derslerinden hatrlayaca "zel veya" yani XOR ileminin
tanmn grelim. zel veya operatr iki operand ald iin drt farkl durum
szkonusudur. Bu durumlar ve sonular aadaki tabloda belirtilmitir.

Operand 1 Operand 2 Sonu

1 1 0
1 0 1

0 1 1

0 0 0

Tablodan da grld zere XOR operatrnn sonucu ancak ve ancak her iki operand
da birbirine eitse 1 deerini almaktadr. Bu sonu bize ifreleme algoritmasnda byk
bir kolaylk salayacaktr. XOR operatr bitsel bir operatr olduu iin her iki operandn
da ikili bir say olmas gerekir. C#'taki veri trleri ile XOR operatr kullanldnda veriyi
oluturan her bir deikenin btn bitleri karlkl olarak XOR ilemine tabi tutulur.
rnein byte trnden 1 says ile yine byte trnden 2 saynn XOR ilemin sonra hangi
deeri oluturacan grelim.

ncelikle 1 ve 2 saysnn bitsel almn yazalm :

Not : 1 byte byklnn 8 bite denk dtn hatrlayalm.

1 --> 0 0 0 0 0001

2 --> 0 0 0 0 0010

--------------------- 1 ^ 2 (Not : XOR operatrnn simgesi ^ karakteridir.)

3 --> 0 0 0 0 0011

Dolaysyla 1 ve 2 deerini XOR ilemine tabi tutarsak 3 deerini elde ederiz. Bu sonucu
programlama yoluyla elde etmek iin bir konsol uygulamas an ve aadaki ifadeyi
ekrana yazdrn.

Console.WriteLine((1^2));

XOR operatrnn dier nemli bir zellii ise geri dnml bir operatr olmasdr. Yani
bir sayy "zel veya" ilemine tabi tuttuktan sonra sonucu yine ayn say ile "zel veya"
ilemine tabi tutarsak balangtaki sonucu elde ederiz. rnein 3 saysn 1 ile "zel
veya" ilemine tabi tutarsak 2 saysn, 2 ile "zel veya" ilemine tabi tutarsak bu sefer 1
saysn elde ederiz. Bu zellii bir forml ile gsterirsek;

x = z ^ b;

y = x ^ b;

ise

z = y dir.

XOR ileminin bu zelli yazdmz programa hem ifre zc hemde ifreleyici olma
zellii katacaktr.

ifreleyici ve ifre zc Program

Bu blmde ifre zc ve ayn zamanda ifreleyeci program XOR operatrn


kullanarak gelitireceiz. Program bir dosya ifreleyicisi ve ifre zcs olarak
kullanlacaktr. ifrelenecek dosya bir metin dosyas, altrlabilir exe dosyas olabilecei
gibi bir video ve resim dosyasda olabilir. nk XOR ilemini dosyay oluturan byte'lar
dzeyinde gerekletireceiz. ifreleme ilemi yaparken dosyadaki her bir byte srayla
kullancnn girecei bir anahtardan elde edilen say ile XOR ilemine tabi tutulacaktr.
XOR ilemi sayesinde yazdmz program ayn zamanda bir ifre zc program olarak
ta alacaktr. lk olarak programmzn en temel halini yazalm ardndan programz
zerinde iyiletirme almas yapacaz.

Kaynak kodlar aada verilen program yazn ve derleyin.

using System;
using System.IO;

namespace XOR
{
class csharpnedir
{
static void Main(string[] args)
{
if(args.Length != 2)
{
Console.WriteLine("Hatal kullanm");
Console.WriteLine("rnek kullanm : Sifrele xx.text anahtar");
return ;
}

string kaynakDosya = args[0];


string hedefDosya = args[1];
string anahtar = "";

Console.Write("Anahtar girin :");


anahtar = Console.ReadLine();

int XOR = 0;

for(int i = 0; i
XOR = XOR + (int)(anahtar[i]);

FileStream fsKaynakDosya = new FileStream(kaynakDosya,FileMode.Open);


FileStream fsHedefDosya = new FileStream(hedefDosya,FileMode.CreateNew |
FileMode.CreateNew,FileAccess.Write);

int kaynakByte;//(3 byte'lk 0 dizisi + kaynakByte)


byte hedefByte;

while((kaynakByte = fsKaynakDosya.ReadByte()) != -1)


{
hedefByte = (byte)((int)kaynakByte ^ XOR);
fsHedefDosya.WriteByte(hedefByte);
}

fsHedefDosya.Close();
fsKaynakDosya.Close();
}
}
}
Hemen programn sonucunu grelim :

Aadaki gibi gizlilik derecesi yksek olan bir metin dosyas oluturun.

Not : ifrelenecek dosyann metin tabanl olmas zorunlu deildir. nk ifreleme


ilemini karakter tabanl deil byte dzeyinde yapmaktayz. Ama sonularn daha iyi
grebilmek iin rnei metin tabanl dosya zerinde gsteriyorum.

Program aadaki gibi komut satrndan altrn.

Program altrdktan sonra oluturulan Sifreli isimli dosyay Notepad programnda


grntlediimizde aadaki gibi bir ekran ike karlarz.

Dikkat edin, ifreleme ilemini byte dzeyinde yaptmz iin ifreli dosya artk metin
dosyas deil binary bir dosya haline gelmitir.

ifrelenmi dosyay tekrar eski haline getirmek iin tek yapmamz gereken komut
satrndan ifreleme programn dier bir deyile ifre zc programn altrmamz
gerekir. Anahtar olarak ta tabiki ifrelemede kullandmz anahtar kullanmamz gerekir.
Komut satrndan aadaki gibi program altrdmzda orjinal metin dosyasn elde
edebiliriz.

XOR SifreliMesaj OrjinalMesaj.txt


Anahtar Girin : XkuksAh

Grdnz gibi programmz hem ifreleyici hemde ifre zc olarak


kullanlabilmektedir.
Sonular

Dikkat ederseniz mesaj dosyasnn her byte deeri sabit bir deerle karlkl olarak XOR
ilemine tabi tutulmutur. XOR ilemine tabi tutulan deer kullanc tarafndan girilen
anahtardan oluturulmutur. Anahtar deerin her bi karakterinin ASCII karl
toplanarak elde edilen deer XOR ileminin sabit operand olarak ele alnmtr. Ancak
programmzda ufak bir sorun var. nk ifrelemek iin girilen anahtar deerini
oluturan karakterlerin hepsini ierecek ekilde oluturulan btn kombinasyonlar
ifrelenmi dosyay zecektir. rnein ifrelemek iin kullanlan anahtar deerin
"AxyHMnK2" olduunu dnelim. Bu durumda "xynAHMNK2" ve "2MnKHyxA" gibi
kombinasyonlar dosyann zlmesini salayacaktr.

Yukarda bahsi geen kst engellemek iin XOR ilemine tabi tutulacak operand anahtar
deerden elde ederlen farkl bir yntem kullanlr. Bu operand aadaki gibi yeniden elde
edebiliriz.

int XOR = 0;

for(int i = 0; i
XOR = XOR + (int)(anahtar[i] * 10);

Yukardaki dzenlmeye ramen ifreyi zecek anahtar tek deildir. nk farkl karakter
kombinasyonlarnn toplam ok dk bir ihtimalde olsa orjinal XOR deerine eit olabilir.
Ancak bu durum ifreleme tekniinin gvenirliini azaltmaz. nk orjinal XOR deerinin
tahmin etme olsal ok azdr.

Gelelim dier bir ksta : Dikkat ederseniz ifreleme yaparken dosyadaki her bir byte
deerini sabit bir deerle XOR ilemine tabi tuttuk. Bir byte deikenin snrlar 0- 255
aras olduu iin ifreleme programn zmek iin en fazla 256 ihtimal vardr. Tabi
burada anahtar deerden XOR ilemine tabi tutulacak deerin nasl elde edildiinin
bilindii varsaylmaktadr. Eer bu yntem bilinmiyorsa ifrenin zlme olasl
neredeyse imkanszdr. XOR operandnn elde edilme ynteminin bilindii varsaym
altnda 256 saysn yani ifrenenin zlme olasln azaltmak iin yapmamz gereken
XOR ilemini 1 byte'lk bloklar yerine daha byk bloklar ile yapmaktr. rnein XOR
ilemini 4 byte lk veri bloklar ile yaptmzda XOR ileminin operand 4.294.967.296
ihtimalden birisidir. Eer XOR ilemine sokulan veri blou artrlrsa operandn alabilecei
deerler stel bir biimde artacaktr. Bu arada XOR ilemine sokulacak veri bloklarnn
says arttka xor ilemindeki operandn deerini belirlemek iin farkl yntemler
kullanlmaldr. nk eer aadaki yntemde elde edilen XOR operandn kullanrsak 1
byte yada 4 byte'lk verilerle almann ok nemli bir fark olmayacaktr. (Burada fark,
girilen anahtara gre belirlenir. rnein oluturulan xor operand 256 deerinden kk
ise hi bir fark meydana gelmeyecektir.)

int XOR = 0;

for(int i = 0; i
XOR = XOR + (int)(anahtar[i]);

Bu yntemle gelitirilecek bir ifreleme programn daha etkili hale getirmek iin bir
yntem daha vardr. Program incelerseniz her bir byte blounu sabit bir deerle xor
ilemine soktuk. Bu aslnda biraz risklidir. Zira byk bir ifreli metnin ok kk
blmnn zlmesi tamamnn zlmesi anlamna gelir. Bu yzden her bir byte
blounu farkl bir deerle xor ilemine tabi tutarsak ifreli metnin her bir ifreli blou bir
dierinden bamsz hale gelir. Yani zlm bir ifreli blok dier bloun zlmesine
kesin bir bilgi vermez. Dolaysyla ifre krc programlarn lineer bir yntem izlemesi
engellenmi olur.

Bu tr bir ifreleme ynteminin devlet dzeyinde gvenli olmas gereken mesajlarda


kullanlmas uygun olmasada mesajlarn bakalar tarafndan akca grlmeden
haberleme sistemlerinden geirilmesi iin uygun bir yntemdir. Elbetteki daha basit
yntemlerle de bu ilemi gerekletirebiliriz ancak bu yntemin en nemli zellii hem
ifreleme hemde ifre zc olarak kullanlabilmesidir.

Bu yaznn kendi ifreleme algortimalarnz oluturmada size yol gsterebileceini umuyor


iyi almalar diliyorum.

C# ile ok Kanall(Multithread) Uygulamalar 4

Bundan nceki makalemizde i paracklar hakknda bilgiler vermeye altm, bu makalemde


ise iimize yarayacak tarzda bir uygulama gelitirecek ve bilgilerimizi pekitireceiz. Bir i
paracnn belkide en ok ie yarayaca yerlerden birisi veritaban uygulamalardr. Bazen
programmz ok uzun bir sonu kmesi dndrecek sorgulara veya uzun srecek gncelleme
ifadeleri ieren sql cmlelerine sahip olabilir. Byle bir durumda programn dier eleri ile olan
aktivitemizi devam ettirebilmek isteyebiliriz. Ya da ayn anda bir den fazla i paracnda, birden
fazla veritaban ilemini yaptrarak bu ilemlerin tamamnn daha ksa srelerde bitmesini
salyabiliriz. te bu gibi nedenleri gz nne alarak bu gn birlikte basit ama faydal olacana
inandm bir uygulama gelitireceiz.

Olay iyi anlayabilmek iin ncelikle bir milat koymamz gerekli. paracndan nceki durum ve
sonraki durum eklinde. Bu nedenle uygulamamz nce i parac kullanmadan oluturacaz.
Sonrada i parac ile. imdi programmzdan ksaca bahsedelim. Uygulamamz aadaki sql
sorgusunu altrp, bellekteki bir DataSet nesnesinin referans ettii blgeyi, sorgu sonucu dnen
veri kmesi ile dolduracak.

SELECT Products.* From [Order Details] Cross Join Products

Bu sorgu altrldnda, Sql sunucusunda yer alan Northwind veritaban zerinden, 165936
satrlk veri kmesi dndrr. Elbette normalde byle bir ilemi istemci makinenin belleine
ymamz anlamsz. Ancak sunucu zerinde alan ve zellikle raporlama amac ile kullanlan
sorgularn bu tip sonular dndrmeside olasdr. imdi bu sorguyu altrp sonular bir DataSet'e
alan ve bu veri kmesini bir DataGrid kontrol iinde gsteren bir uygulama gelitirelim. ncelikle
aadaki formumuzu tasarlayalm.
ekil 1. Form Tasarmmz.

imdide kodlarmz yazalm.

DataSet ds;

public void Bagla()


{

dataGrid1.DataSource=ds.Tables[0];
}

public void Doldur()


{

SqlConnection conNorthwind=new SqlConnection("data source=localhost;initial


catalog=Northwind;integrated security=sspi");

conNorthwind.Open();

SqlDataAdapter daNorthwind=new SqlDataAdapter("SELECT Products.* From [Order


Details] Cross Join Products",conNorthwind);

ds=new DataSet();

daNorthwind.Fill(ds);

conNorthwind.Close();

MessageBox.Show("DataTable dolduruldu...");
}

private void btnKapat_Click(object sender, System.EventArgs e)


{
Close();
}

private void btnCalistir_Click(object sender, System.EventArgs e)


{

Doldur();
}

private void btnGoster_Click(object sender, System.EventArgs e)


{

Bagla();
}

Yazdmz kodlar gayet basit. Sorgumuz bir SqlDataAdapter nesnesi ile, SqlConnection'mz
kullanlarak altrlyor ve daha sonra elde edilen veri kmesi DataSet'e aktarlyor. imdi
uygulamamz bu haliyle altralm ve sorgumuzu altr balkl buton ile altrdktan sonra,
textBox kontrolne mouse ile tklayp bir eyler yazmaya alalm.

ekil 2. parac olmadan programn almas.

Grld gibi sorgu sonucu elde edilen veri kmesi DataSet'e doldurulana kadar TextBox
kontrolne bir ey yazamadk. nk ilemcimiz satr kodlarn iletmek ile meguld ve bizim
TextBox kontrolmze olan tklamamz ele almad. Demekki buradaki sorgumuzu bir i parac
iinde tanmlamalyz. Nitekim programmz donmasn ve baka ilemleride yapabilelim. rnein
TextBox kontrolne bir eyler yazabilelim (bu noktada pek ok ey sylenebilir. rnein baka bir
tablonun gncellenmesi gibi). Bu durumda yapmamz gereken kodlamay inanyorumki nceki
makalelerden edindiiniz bilgiler ile biliyorsunuzdur. Bu nedenle kodlarmz detayl bir ekilde
aklamadm. imdi gelin yeni kodlarmz yazalm.

DataSet ds;

public void Bagla()


{
if(!t1.IsAlive)
{
dataGrid1.DataSource=ds.Tables[0];
}
}

public void Doldur()


{

SqlConnection conNorthwind=new SqlConnection("data source=localhost;initial


catalog=Northwind;integrated security=sspi");

conNorthwind.Open();

SqlDataAdapter daNorthwind=new SqlDataAdapter("SELECT Products.* From


[Order Details] Cross Join Products",conNorthwind);

ds=new DataSet();

daNorthwind.Fill(ds);

conNorthwind.Close();

MessageBox.Show("DataTable dolduruldu...");
}

ThreadStart ts1;

Thread t1;

private void btnKapat_Click(object sender, System.EventArgs e)


{
if(!t1.IsAlive)
{
Close();
}

else
{
MessageBox.Show("Is paracigi henz sonlandirilmadi...Daha sonra
tekrar deneyin.");
}
}

private void btnCalistir_Click(object sender, System.EventArgs e)


{
ts1=new ThreadStart(Doldur);

t1=new Thread(ts1);

t1.Start();
}

private void btnIptalEt_Click(object sender, System.EventArgs e)


{
t1.Abort();
}

private void btnGoster_Click(object sender, System.EventArgs e)


{
Bagla();
}

imdi programmz altralm.

ekil 3. Paracnn sonucu.

Grld gibi bu youn sorgu alrken TextBox kontrolne bir takm yazlar yazabildik. stelik
programn almas hi kesilmeden. imdi Gster balkl butona tkladmzda veri kmesinin
DataGrid kontrolne alndn grrz.
ekil 4. Programn almasnn Sonucu.

Geldik bir makalemizin daha sonuna. lerliyen makalelerimizde Thred'leri daha derinlemesine
incelemeye devam edeceiz. Hepinize mutlu gnler dilerim.

Arayz(Interface) Kullanmna Giri

Bugnk makalemizde, nesneye dayal programlamann nemli kavramlarndan birisi olan


arayzleri incelemeye alacaz. ncelikle, arayz'n tanmn yapalm.

Bir arayz, baka snflar iin bir rehberdir. Bu ksa tanmn arkasnda, deryalar gibi
bir kavram denizi olduunu sylemekte yarar buluyorum. Arayzn ne olduunu tam
olarak anlayabilmek iin belkide asl kullanm amacna bakmamz gerekmektedir.

C++ programlama dilinde, snflar arasnda ok kaltmllk sz konusu idi. Yani bir snf,
kaltmsal olarak, birden fazla snftan tretilebiliyordu . Ancak bu teknik bir sre sonra
kodlarn dahada karmaklamasna ve anlalabilirliin azalmasna neden oluyordu. Bu
sebeten tr deerli Microsoft mimarlar, C# dilinde, bir snfn sadece tek bir snf
kaltmsal olarak alabilecei kstlmasn getirdiler. ok kaltmlk grevini ise
anlalmas daha kolay arayzlere braktlar. te arayzleri kullanmamzn en byk
nedenlerinden birisi budur.

Dier yandan, uygulamalarmzn gelecei asndan da arayzlerin ok kullanl


olabileceini sylememiz gerekiyor. Dnnk, bir ekip tarafndan yazlan ve gelitirilen
bir uygulamada grevlisiniz. Kullandnz nesnelerin, tretildii snflar zaman ierisinde,
gelien yeniliklere adapte olabilmek amacyla, saysz yeni metoda, zellie vb.. sahip
olduklarn farzedin. Bir sre sonra, nesnelerin tretildii snflar ierisinde yer alan
kavram kargasn, "bu neyi yapyordu?, kime yapyordu? , ne iin yapyordu?" gibi
sorularn ne kadar ok sorulduunu dnn. Oysa uygulamanzdaki snflarn izleyecei
yolu gsteren rehber(ler) olsa fena m olurdu? te size arayzler. Bir arayz oluturun ve
bu arayz uygulayan snflarn hangi metodlar, zellikleri vb kullanmas gerektiine
karar verin. Programn gelimesimi gerekiyor? Yeni niteliklere mi ihtiyacn var? ster
kullanlan arayzleri, birbirlerinden kaltmsal olarak tretin, ister yeni arayzler
tasarlayn. Tek yapacanz snflarn hangi arayzlerini kullanacan belirtmek olucaktr.

Bu aklamalar nda bir arayz nasl tanmlanr ve hangi yelere sahiptir bundan
bahsedelim.Bir arayz tanmlanmas aadaki gibi yaplr. Yazlan kod blounun bir
arayz olduunu Interface anahtar szc belirtmektedir. Arayz isminin banda I
harfi kullanldna dikkat edin. Bu kullanlan snfn bir arayz olduunu anlamamza
yarayan bir isim kullanma tekniidir. Bu sayede, snflarn kaltmsal olarak ald
elemanlarn arayz olup olmadn daha kolayca anlayabiliriz.

public inteface IArayuz


{

Tanmlama grld gibi son derece basit. imdi arayzlerin yelerine bir gz atalm.
Arayzler, sadece aadaki yelere sahip olabilirler:

Arayz yeleri
A. zellikler (properties)
B. Metodlar (methods)
C. Olaylar (events)
D. ndeksleyiciler (indexers)
Tablo 1. Arayzlerin sahip olabilecei yeler

Dier yandan, arayzler ierisinde aadaki yeler kesinlikle kullanlamazlar:

Arayzlerde Kullanlamayan
yeler

i. Yapclar (constructors)

ii. Yokediciler (destructors)

iii. Alanlar (fields)


Tablo 2. Arayzlerde kullanlamayan yeler.

Arayzler Tablo1 deki yelere sahip olabilirler. Peki bu yeler nasl tanmlanr. Hereyden
nce arayzler ile ilgili en nemli kural onun bir rehber olmasdr. Yani arayzler sadece,
kendisini rehber alan snflarn kullanaca yeleri tanmlarlar. Herhangi bir kod satr
iermezler. Sadece zelliin, metodun, olayn veya indeksleyicinin tanm vardr. Onlarn
kolay okunabilir olmalarn salayan ve oklu kaltm iin tercih edilmelerine neden olan
sebepte budur. rnein;

public interface IArayuz


{
/* double tipte bir zellik tanm. get ve set anahtar
szcklerinin herhangibir blok {} iermediine dikkat edin. */

double isim
{
get;
set;
}

/* Yanlz okunabilir (ReadOnly) string tipte bir zellik tanm. */

string soyisim
{
get ;
}

/* integer deer dndren ve ili integer parametre alan bir metod


tanm. Metod tanmlarndada metodun dn tipi, parametreleri, ismi
dnda herhangibir kod satr olmadna dikkat edin. */

int topla(int a, int b);

/* Dn deeri olmayan ve herhangibir parametre almayan bir metod


tanm. */

void yaz();

/* Bir indeksleyici tanm */


string this [ int index]
{
get;
set;
}
}

Grld gibi sadece tanmlamalar mevcut. Herhangibir kod satr mevcut deil. Bir
arayz tasarlarken uymamz gereken bir takm nemli kurallar vardr. Bu kurallar
aadaki tabloda ksaca listelenmitir.

Bir arayz'n tm yeleri public kabul edilir. Private, Protected gibi belirtiler
kullanamayz. Bunu yaptmz takdirde rnein bir eleman private tanmladmz
1
takdirde, derleme zamannda u hatay alrz. "The modifier 'private' is not valid
for this item"
Dier yandan bir metodu public olarakta tanmlayamayz. nk zaten
varsaylan olarak btn yeler public tanmlanm kabul edilir. Bir metodu public
2
tanmladmzda yine derleme zamannda u hatay alrz. "The modifier 'public' is
not valid for this item"
Bir arayz, bir yap(struct)'dan veya bir snf(class)'tan kaltmla tretilemez.
3 Ancak, bir arayz baka bir arayzden veya arayzlerden kaltmsal olarak
tretebiliriz.
4 Arayz elemanlarn static olarak tanmlayamayz.
Arayzlerin uyguland snflar, arayzde tanmlanan btn yeleri
5
kullanmak zorundadr.
Tablo 3. Uyulmas gereken kurallar.

imdi bu kadar aklamadan sonra konuyu daha iyi anlayabilmek iin basit ve aklayc
bir rnek gelitirelim. nce arayzmz tasarlayalm:
public interface IArayuz
{
void EkranaYaz();
int Yas
{
get;
set;
}

string isim
{
get;
set;
}
}

imdide bu arayz kullanacak snfmz tasarlayalm.

public class Kisiler:IArayuz


{

imdi bu anda uygulamay derlersek, IArayuz'ndeki elemanlar snfmz iinde


kullanmadmzdan dolay aadaki derleme zaman hatalarn alrz.

Interfaces1.Kisiler' does not implement interface member


'Interfaces1.IArayuz.EkranaYaz()'
Interfaces1.Kisiler' does not implement interface member
'Interfaces1.IArayuz.isim'
Interfaces1.Kisiler' does not implement interface member
'Interfaces1.IArayuz.Yas'

Grld gibi kullanmadmz tm arayz yeleri iin bir hata mesaj olutu. Bu
noktada unu tekrar hatrlatmak istiyorum,

Arayzlerin uyguland snflar, arayzde(lerde)


tanmlanan tm yeleri kullanmak, yani kodlamak
zorundadr.

imdi snfmz dzgn bir ekilde gelitirelim:

public class Kisiler:IArayuz /* Snfn kullanaca arayz burada


belirtiliyor.*/
{

private int y;
private string i;

/* Bir snfa bir arayz uygulamamz, bu snfa baka yeler


eklememizi engellemez. Burada rnein snfn yapc metodlarnda
dzenledik. */

public Kisiler()
{
y=18;
i="Yok";
}

/* Dikkat ederseniz zelliin hereyi, arayzdeki ile ayn


olmaldr. Veri tipi, ismi vb... Bu tm dier arayz yelerinin, snf
ierisinde uygulanmasnda da geerlidir. */

public Kisiler(string ad,int yas)


{

y=yas;
i=ad;
}

public int Yas


{
get
{
return y;
}

set
{
y=value;
}
}

public string Isim


{
get
{
return i;
}

set
{
i=value;
}
}

public void EkranaYaz()


{
Console.WriteLine("Adm:"+i);
Console.WriteLine("Yam:"+y);
}
}

imdi oluturduumuz bu snf nasl kullanacamza bakalm.

class Arayuz_Deneme
{
{
Kisiler kisi=new Kisiler("Burak",27);
Console.WriteLine("Yam "+kisi.Yas.ToString());
Console.WriteLine("Adm "+kisi.Isim);
Console.WriteLine("-----------");
kisi.EkranaYaz();
}
}

Uygulamamz altrdmzda aadaki sonucu elde ederiz.

ekil 1. Uygulamann almas Sonucu.

Bu makalemizde arayzlere ksa bir giri yaptk. Bir sonraki makalemizde ise, bir snfa
birden fazla arayzn nasl uygulanacan inceleyeceiz. Hepinize mutlu gnler dilerim.

Temsilci(Delegate) Kavramna Giri

Bugnk makalemizde, C# programlama dilinde ileri seviye kavramlardan biri olan


Temsilcileri(delegates) incelemeye balayacaz. Temsilciler ileri seviye bir kavram
olmasna ramen, her seviyden C# programcsnn bilmesi gereken unsurlardandr.
Uygulamalarmz temsilciler olmadan da gelitirebiliriz. Ancak bu durumda,
yapamyacaklarmz, yapabileceklerimizin nne geecektir. Dier yandan temsilcilerin
kullanmn grdke bize getirecei avantajlar daha iyi anlayacamz kansndaym. Bu
makalemizde temsilcileri en basit haliyle anlamaya alcaz.

Temsilci (delegate), program ierisinde bir veya daha fazla metodu gsteren(iaret
eden), referans trnden bir nesnedir. Programlarmzda temsilciler kullanmak
istediimizde, ncelikle bu temsilcinin tanmn yaparz. Temsilci tanmlar, arayzlerdeki
metod tanmlamalar ile neredeyse ayndr. Tek fark delegate anahtar szcnn yer
almasdr. Bununla birlikte, bir temsilci tanmlandnda, aslnda iaret edebilecei
metod(larn) imzalarnda belirlemi olur. Dolaysyla, bir temsilciyi sadece tanmlad
metod imzasna uygun metodlar iin kullanabiliceimizi syleyebiliriz. Temsilci tanmlar
tasarm zamannda yaplr. Bir temsilciyi, bir metodu iaret etmesi iin kullanmak
istediimizde ise, alma zamannda onu new yaplandrcs ile oluturur ve iaret
etmesini istediimiz metodu ona parametre olarak veririz. Bir temsilci tanm genel
haliyle, aadaki ekildeki gibidir.
ekil 1. Temsilci tanmlamas.

ekildende grld gibi, temsilciler aslnda bir metod tanmlarlar fakat bunu
uygulamazlar. te bu zellikleri ile arayzlerdeki metod tanlamalarna benzerler.
Uygulamalarmzda, temsilci nesneleri ile gstermek yani iaret etmek istediimiz
metodlar bu imzaya sahip olmaldr. Bildiiniz gibi metod imzalar, metodun geri dn
tipi ve ald parametreler ile belirlenmektedir.

Bir temsilcinin tanmlanmas, onu kullanmak iin yeterli deildir elbette. Hereyden nce
bir amacmz olmaldr. Bir temsilciyi alma zamannda oluturabiliriz ve kullanabiliriz.
Bir temsilci sadece bir tek metodu iaret edebilecei gibi, birden fazla metod iin
tanmlanm ve oluturulmu temsilcileride kullanabiliriz. Dier yandan, tek bir temsilcide
birden fazla temsilciyi toplayarak bu temsilcilerin iaret ettii, tm metodlar tek bir
seferde altrma lksnede sahibizdir. Ancak temsilciler gerek anlamda iki amala
kullanlrlar. Bunlardan birincisi olaylardr(events). Dier yandan, bugnk makalemizde
ileyeceimiz gibi, bir metodun alma zamannda, hangi metodlarn altrlacana
karar vermesi gerektii durumlarda kullanrz. Elbette bahsetmi olduumuz bu amac,
herhangibir temsilye ihtiya duymadan da gerekletirebiliriz. Ancak temsilcileri
kullanmadmzda, bize salad stn programlama teknii, kullanm kolayl ve artan
verimliliide gz ard etmi oluruz.

imdi dilerseniz bahsetmi olduumuz bu amala ilgili bir rnek verelim ve konuyu daha
iyi kavramaya alalm. rnein, personelimizin yapm olduu sat tutarlarna gre,
prim hesab yapan ve ilgili yerlere bu deiiklikleri yazan bir projemiz olsun. Burada
primlerin hesaplanmas iin deiik katsaylar, yaplan satn tutarna gre belirlenmi
olabilir. rnein bu oranlar dk, orta ve yksek olarak tanmlanm olsun. Personel
hangi gruba giriyorsa, metodumuz ona uygun metodu arsn. te bu durumda karar
verici metodumuz, altrabilecei metodlar temsil eden temsilci nesnelerini parametre
olarak alr. Yani, alma zamannda ilgili metodlar iin temsilci nesneleri oluturulur ve
karar verici metoda , hangi metod altrlacak ise onun temsilcisi gnderilir. Bylece
uygulamamz altnda, tek yapmamz gereken hangi metodun altrlmas
isteniyorsa, bu metoda ilikin temsilcinin, karar verici metoda gnderilmesi olacaktr.

Olduka kark grnyor. Ancak rnekleri yazdka daha iyi kavrayacanza


inanyorum. imdiki rneimizde, temsilcilerin tasarm zamannda nasl tanmlandn,
alma zamannda nasl oluturulduklarn ve karar verici bir metod iin temsilcilerin nasl
kullanlacan incelemeye alacaz.

using System;

namespace Delegates1
{
public class Calistir
{
public static int a;
public delegate void temcilci(int deger); /* Temsilci tanmlamamz yapyoruz. Ayn
zamanda temsilcimiz , deer dndrmeyen ve integer tipte tek bir parametre alan bir
metod tanmlyor. Temsilcimizin ad ise temsilci.*/

* imdi bu temsilciyi kullacanak bir metod yazyoruz. te karar verici metodumuz


budur. Dikkat ederseniz metodumuz parametre olarak, temsilci nesnemiz tipinden bir
temsilci(Delegate) alyor. Daha sonra metod blou iinde, parametre olarak geirilen bu
temsilcinin iaret ettii metod arlyor ve bu metoda parametre olarak integer tipte bir
deer geiriliyor. Ksaca, metod iinden, temsilcinin iaret ettii metod arlyor.
Burada, temsilci tanmna uygun olan metodun arlmas garanti altna alnmtr. Yani,
programn almas srasnda, new yaplandrcs kulllanarak oluturacamz bir
temsilci(delegate), kendi metod tanm ile uyumayan bir metod iin yaratlmaya
alldnda bir derleyici hatas alacazdr. Dolaysyla bu, temsilcilerin yksek gvenlikli
iaretiler olmasn salar. Bu , temsilcileri, C++ dilindeki benzeri olan iaretilerden
ayran en nemli zelliktir. */

public void Metod1(Calistir.temcilci t)


{
t(a);
}
}

class Class1
{

/* IkKat ve UcKat isimli metodlarmz, temsilcimizin programn almas srasnda


iaret etmesini istediimiz metodlar. Bu nedenle imzalar, temsilci tanmmzdaki metod
imzas ile ayndr. */

public static void IkiKat(int sayi)


{
sayi=sayi*2;
Console.WriteLine("IkiKat isimli metodun temsilcisi tarafindan
agirildi."+sayi.ToString());
}

public static void UcKat(int sayi)


{
sayi=sayi*3;
Console.WriteLine("UcKat isimli metodun temsilcisi tarafindan
agirildi."+sayi.ToString());
}

static void Main(string[] args)


{

/* Temsilci nesnelerimiz ilgili metodlar iin oluturuluyor. Burada, new


yaplandrcs ile oluturulan temsilci nesneleri parametre olarak, iaret edecekleri
metodun ismini alyorlar. Bu noktadan itibaren t1 isimli delegate nesnemiz IkiKat isimli
metodu, t2 isimli delegate nesnemizde UcKat isimli metodu iaret ediceklerdir. */

Calistir.temcilci t1=new Delegates1.Calistir.temcilci(IkiKat);


Calistir.temcilci t2=new Delegates1.Calistir.temcilci(UcKat);

Console.WriteLine("1 ile 20 aras deer girin");

Calistir.a=System.Convert.ToInt32(Console.ReadLine());

Calistir c= new Calistir();

/* Kullancnn Console penceresinden girdii deer gre, Calistir snfnn a


isimli integer tipteki deerini 10 ile karlatrlyor. 10 dan bykse, karar verici
metodumuza t1 temsilcisi gnderiliyor. Bu durumda Metod1 isimli karar verici
metodumuz, kendi kod blou iinde t1 delegate nesnesinin temsil ettii IkKat metodunu,
Calistir.a deikeni ile aryor. Ayn ilem tarz t2 delegate nesnesi iinde geerli.*/

if(Calistir.a>=10)
{
c.Metod1(t1);
}
else
{
c.Metod1(t2);
}
}
}
s}

Uygulamamz altralm ve bir deer girelim.

ekil 2. Programn almasnn sonucu.

Bu basit rnek ile umarm temsilciler hakknda biraz olsun bilgi sahibi olmusunuzdur.
imdi temsilciler ile ilgili kavramlarmza devam edelim. Yukardaki rneimiz nda
temsilcileri programlarmzda temel olarak nasl kullandmz aadaki ekil ile daha
kolay anlayabileceimizi sanyorum.
ekil 3. Temsilcilerin Karar Verici metodlar ile kullanm.

Yukardaki rneimizde, her bir metod iin tek bir temsilci tanmladk ve temsilcileri teker
teker ardk. Bu Single-Cast olarak adlandrlmaktadr. Ancak programlarmz da bazen,
tek bir temsilciye birden fazla temsilci ekleyerek, birden fazla metodu tek bir temsilci ile
altrmak isteyebiliriz. Bu durumda Multi-Cast temsilciler tanmlarz. imdi multi-cast
temsilciler ile ilgili bir rnek yapalm. Bu rneimizde t1 isimli temsilcimiz, multi-cast
temsilcimiz olucak.

using System;
namespace Delegates2
{
public class temsilciler
{
public delegate void dgTemsilci(); /* Temsilcimiz tanmlanyor. Geri dn deeri
olmayan ve parametre almayan metodlar temsil edebilir. */

/* Metod1, Metod2 ve Metod3 temsilcilerimizin iaret etmesini istediimiz metodlar


olucaktr.*/
public static void Metod1()
{
Console.WriteLine("Metod 1 altrld.");
}

public static void Metod2()


{
Console.WriteLine("PI deeri 3.14 alnsn");
}

public static void Metod3()


{
Console.WriteLine("Mail gnderildi...");
}

/* Temsilcilerimizi altran metodumuz. Parametre olarak gnderilen temsilciyi,


dolaysyla bu temsilcinin iaret ettii metodu alyor. */

public static void TemsilciCalistir(temsilciler.dgTemsilci dt)


{
dt(); /* Temsilcinin iaret ettii metod altrlyor.*
}
}

class Class1
{
static void Main(string[] args)
{
/* metodumuz iinde temsilci nesnelerimiz oluturuluyor .*/

temsilciler.dgTemsilci t1=new
Delegates2.temsilciler.dgTemsilci(temsilciler.Metod1);

temsilciler.dgTemsilci t2=new
Delegates2.temsilciler.dgTemsilci(temsilciler.Metod2);

temsilciler.dgTemsilci t3=new
Delegates2.temsilciler.dgTemsilci(temsilciler.Metod3);

Console.WriteLine("sadece t1");

temsilciler.TemsilciCalistir(t1);

Console.WriteLine("---");

/* Burada t1 temsilcimize, t2 temsilcisi ekleniyor. Bu durumda,


t1 temsilcimiz hem kendi metodunu hemde, t2 temsilcisinin iaret ettii metodu iaret
etmeye balyor. Bu halde iken TemsilciCalistir metodumuza t1 temsilcisini gndermemiz
her iki temsilcinin iaret ettii metodlarn altrlmasna neden oluyor.*/

t1+=t2;

Console.WriteLine("t1 ve t2");

temsilciler.TemsilciCalistir(t1);

Console.WriteLine("---");

t1+=t3; /* imdi t1 temsilcimiz hem t1, hem t2, hem de t3 temsilcilerinin


iaret ettii metodlar iaret etmi olucak.*/

Console.WriteLine("t1,t2 ve t3");
temsilciler.TemsilciCalistir(t1);

Console.WriteLine("---");

t1-=t2; /* Burada ise t2 metodunu t1 temsilcimizden kartyoruz.


Bylece, t1 temsilcimiz sadece t1 ve t3 temsilcilerini ieriyor. */
Console.WriteLine("t1 ve t3");

temsilciler.TemsilciCalistir(t1);

Console.WriteLine("---");
}
}
}

Uygulamamz altrdmzda aadaki sonucu elde ederiz.

ekil 4. Multi-Cast temsilciler.

Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde temsilcilerin kullanld
olaylar(events) kavramna gireceiz. Hepinize mutlu gnler dilerim.

Huffman Veri Sktrma Algoritmas ve Uygulamas

Bu makalede bilgisayar bilimlerinin nemli konularndan biri olan veri sktrma


algoritmalarndan Huffman algoritmasn inceledikten sonra uygulamasn gerekletirip
sonularn greceiz.

Saysal haberleme tekniklerinin nemli lde artt gnmzde, saysal verilen


iletilmesi ve saklanmas bir hayli nem kazanmtr. Saysal veriler eitli saklayclarda
saklanrken hedef daima minimum alanda maksimum veriyi saklamadr. Veriler eitli
yntemlerle sktrlarak kaplad alandan ve iletim zamanndan tasarruf edilir. Saysal
iletiim(digital communication) kuramnda veriler ok eitli yntemlerle sktrlabilir. Bu
yntemlerden en ok bilineni David Huffman tarafndan ne srlmtr. Bu yazda bu
teknik "Huffman algoritmas" olarak adlandrlacaktr. Bu yazda Huffman Algoritmas
detayl olarak aklandktan sonra bu algoritmann C# dili ile ne ekilde uygulanaca
gsterilecektir.

Sktrma algoritmalar temel olarak iki kategoride incelenir. Bunlar, kaypl ve kaypsz
sktrma algoritmalardr. Kaypl algoritmalarda sktrlan veriden orjinal veri elde
edilemezken kaypsz sktrma algoritmalarnda sktrlm veriden orjinal veri elde
edilebilir. Kaypl sktrma tekniklerine verilebilecek en gzel rnekler MPEG ve JPEG gibi
standartlarda kullanlan sktrmalardr. Bu tekniklerde sktrma oran artrldnda
orjinal veride bozulmalar ve kayplar grlr. rnein sktrlm resim format olan JPEG
dosyalarnn kaliteli yada az kaliteli olmasnn nedeni sktrma katsaysdr. Yani benzer
iki resim dosyasndan daha az disk alan kaplayan daha kt kalitededir deriz. Kaypsz
veri sktrmada durum ok farkldr. Bu tekniklerde nemli olan orjinal verilerin aynen
sktrlm veriden elde edilmesidir. Bu teknikler daha ok metin tabanl verilen
sktrlmasnda kullanlr. Bir metin dosyasn sktrdktan sonra metindeki baz
cmlelerin kaybolmas istenmedii iin metin sktrmada bu yntemler kullanlr.

Bu yaznn konusu olan Huffman sktrma algoritmas kaypsz bir veri sktrma
tekniini ierir. Bu yzden bu yntemin en elverili olduu veriler metin tabanl verilerdir.
Bu yazda verilecek rnek programdaki hedef metin tabanl verilerin sktrlmas
olacaktr.

Huffman algoritmas, bir veri kmesinde daha ok rastlanan sembol daha dk


uzunluktaki kodla, daha az rastlanan sembolleri daha yksek uzunluktaki kodlarla temsil
etme mant zerine kurulmutur. Bir rnekten yola kacak olursak : Bilgisayar
sistemlerinde her bir karakter 1 byte yani 8 bit uzunluunda yer kaplar. Yani 10
karakterden oluan bir dosya 10 byte byklndedir. nk her bir karakter 1 byte
byklndedir. rneimizdeki 10 karakterlik veri kmesi "aaaaaaaccs" olsun. "a"
karakteri ok fazla sayda olmasna ramen "s" karakteri tektir. Eer btn karakterleri 8
bit deilde veri kmesindeki sklklarna gre kodlarsak veriyi sembolize etmek iin
gereken bitlerin says daha az olacaktr. Sz gelimi "a" karakteri iin "0" kodunu "s"
karakteri iin "10" kodunu, "c" karakteri iin "11" kodunu kullanabiliriz. Bu durumda 10
karakterlik verimizi temsil etmek iin

(a kodundaki bit says)*(verideki a says) + (c kodundaki bit says)*(verideki c says) +


(s kodundaki bit says)*(verideki s says) = 1*7 + 2*2 + 2*1 = 12 bit

gerekecektir. Halbuki btn karakterleri 8 bit ile temsil etseydik 8*10 = 80 bite
ihtiyacmz olacakt. Dolaysyla %80 'in zerinde bir sktrma oran elde etmi olduk.
Burada dikkat edilmesi gereken nokta udur : Veri kmesindeki sembol saysna ve
sembollerin tekrarlanma sklklarna bal olarak Huffman sktrma algoritmas %10 ile
%90 arasnda bir sktrma oran salayabilir. rnein iinde 2000 tane "a" karakteri ve
10 tane "e" karakteri olan bir veri kmesi Huffman teknii ile sktrlrsa %90'lara varan
bir sktrma oran elde edilir.

Huffman tekniinde semboller(karakterler) ASCII'de olduu gibi sabit


uzunluktaki kodlarla kodlanmazlar. Her bir sembol deiken sayda uzunluktaki
kod ile kodlanr.

Bir veri kmesini Huffman teknii ile sktrabilmek iin veri kmesinde bulunan her bir
semboln ne sklkta tekrarlandn bilmemiz gerekir. rnein bir metin dosyasn
sktryorsak her bir karakterin metin ierisinde ka adet getiini bilmemiz gerekiyor.
Her bir semboln ne sklkta tekrarlandn gsteren tablo frekans tablosu olarak
adlandrlmaktadr. Dolaysyla sktrma ilemine gemeden nce frekans tablosunu
karmamz gerekmektedir. Bu ynteme Statik Huffman teknii de denilmektedir. Dier
bir teknik olan Dinamik Huffman tekniinde sktrma yapmak iin frekans tablosuna
nceden ihtiya duyulmaz. Frekans tablosu her bir sembolle karlatka dinamik olarak
oluturulur. Dinamik Huffman teknii daha ok haberleme kanallar gibi hangi verinin
gelecei nceden belli olmayan sistemlerde kullanlmaktadr. Bilgisayar sistemlerindeki
dosyalar sktrmak iin statik huffman metodu yeterlidir. Nitekim bir dosyay batan
sona tarayarak herbir semboln hangi sklkla yer aldn tespit edip frekans tablosunu
elde etmemiz ok basit bir ilemdir.

Huffman sktrma tekniinde frekans tablosunu elde etmek iin statik ve dinamik
yaklamlarnn olduunu syledik. Eer statik yntem seilmise iki yaklam daha
vardr. Birinci yaklam, metin dosyasnn diline gre sabit bir frekans tablosunu
kullanmaktr. rnein Trke bir metin dosyasnda "a" ve "e" harflerine ok sk
rastlanrken "" harfine ok az rastlanr. Dolaysyla "" harfi daha fazla bitle "a" ve "e"
harfi daha az bitle kodlanr. Frekans tablosunu elde etmek iin kullanlan dier bir ytem
ise metni batan sona tarayarak her bir karakterin frekansn bulmaktr. Sizde takdir
edersinizki ikinci yntem daha gereki bir zm retmekle beraber metin dosyasnn
dilinden bamsz bir zm retmesi ile de n plandadr. Bu yntemin dezavantaj ise
sktrlan verilerde geen sembollerin frekansnn da bir ekilde saklanma
zorunluluunun olmasdr. Sktrlan dosyada her bir semboln frekansda saklanmaldr.
Bu da kk boyutlu dosyalarda sktrma yerine geniletme etkisi yaratabilir. Ancak bu
durum Huffman ynteminin kullanlabililiini zedelemez. Nitekim kk boyutlu dosyalarn
sktrlmaya pek fazla ihtiyac yoktur zaten.

Frekans tablosunu metin dosyasn kullanarak elde ettikten sonra yapmamz gereken
"Huffman Aacn" oluturmaktr. Huffman aac hangi karakterin hangi bitlerle temsil
edileceini(kodlanacan) belirlememize yarar. Birazdan rnek bir metin zerinden
"Huffman Aacn" teorik olarak oluturup algoritmann derinliklerine ineceiz. Bu rnei
iyi bir ekilde incelediinizde Huffman algoritmasnn aslnda ok basit bir temel zerine
kurulduunu greceksiniz.

Huffman Aacnn Oluturulmas

Bir huffman aac aadaki admlar izlenerek oluturulabilir.

Bu rnekte aadaki frekans tablosu kullanlacaktr.

Sembol(Karakter) Sembol Frekans

a 50

b 35

k 20

m 10

d 8

Bu tablodan karmamz gereken udur : Elimizde yle bir metin dosyas varki "a"
karakteri 50 defa, "b" karakteri 35 defa .... "" karakteri 2 defa geiyor. Amacmz ise her
bir karakteri hangi bit dizileriyle kodlayacamz bulmak.

1 - ncelikle "Huffman Aacn" ndaki en son dmleri(dal) oluturacak btn semboller


frekanslarna gre aadaki gibi kkten bye doru sralanrlar.
2 - En kk frekansa sahip olan iki semboln frekanslar toplanarak yeni bir dm
oluturulur. Ve oluturulan bu yeni dm dier varolan dmler arasnda uygun yere
yerletirilir. Bu yerletirme frekans bakmndan kklk ve bykle gredir. rnein
yukardaki ekilde "" ve "d" sembolleri toplanarak "12" frakansnda yeni bir "d"
dm elde edilir. "12" frekansl bir sembol ekilde "m" ve "k" sembolleri arasnda
yerletirilir. "" ve "d" dmleri ise yeni oluturulan dmn dallar eklinde kalr. Yeni
dizimiz aadaki ekilde olacaktr.

3 - 2.admdaki ilem tekrarlanarak en kk frekansl iki dm tekrar toplanr ve yeni


bir dm oluturulur. Bu yeni dmn frekans 22 olaca iin "k" ve "b" dmleri
arasna yerleecektir. Yeni dizimiz aadaki ekilde olacaktr.

4 - 2.admdaki ilem tekrarlanarak en kk frekansl iki dm tekrar toplanr ve yeni


bir dm oluturulur. Bu yeni dmn frekans 42 olaca iin "b" ve "a" dmleri
arasna yerleecektir. Yeni dizimiz aadaki ekilde olacaktr. Dikkat ederseniz her daln
en ucunda sembollerimiz bulunmaktadr. Dallarn ucundaki dmlere zel olarak
yaprak(leaf) denilmektedir. Sona yaklatka Bilgisayar bilimlerinde nemli bir veri
yaps olan Tree(aa) veri yapsna yaklatmz gryoruz.
5 - 2.admdaki ilem tekrarlanarak en kk frekansl iki dm tekrar toplanr ve yeni
bir dm oluturulur. Bu yeni dmn frekans 77 olaca iin "a" dmnden sonra
yerleecektir. Yeni dizimiz aadaki ekilde olacaktr. Dikkat ederseniz her bir dmn
frekans o dmn sa ve sol dmlerinin frekanslarnn toplamna eit olmaktadr.
Ayn durum dm sembolleri iinde geerlidir.
6 - 2.admdaki ilem en tepede tek bir dm kalana kadar tekrar edilir. En son kalan
dm Huffman aacnn kk dm(root node) olarak adlandrlr. Son dmn
frekans 127 olacaktr. Bylece huffman aacnn son hali aadaki gibi olacaktr.
Not : Dikkat ederseniz Huffman aacnn son hali simetrik bir yapda kt. Yani yaprak
dmler hep sol tarafta kt. Bu tamamen setiimiz sembol frekanslarna bal olarak
rastlantsal bir sonutur. Bu rastlantnn olumas oluturduumuz her bir yeni dmn
yeni dizide ikinci sraya yerlemesinden kaynaklanmaktadr. Sembol frekanslarnda
deiiklik yaparak aacn eklindeki deiiklikleri kendinizde grebilirsiniz.

7 - Huffman aacnn son halini oluturduumuza gre her bir semboln yeni kodunu
oluturmaya geebiliriz. Sembol kodlarn oluturuken Huffman aacnn en tepesindeki
kk dmden balanr. Kk dmn sa ve sol dmlerine giden dala srasyla "0" ve
"1" kodlar verilir. Sras ters ynde de olabilir. Bu tamamen seime baldr. Ancak ilk
setiiniz sray bir sonraki seimlerde korumanz gerekmektedir. Bu durumda "a"
dmne gelen dal "0", "bkmd" dmne gelen dal "1" olarak seilir. Bu ilem
aataki tm dallar iin yaplr. Dallarn kodlarla iaretlenmi hali aadaki gibi olacaktr.
8 - Sra geldi her bir semboln hangi bit dizisiyle kodlanacan bulmaya. Her bir sembol
dallarn ucunda bulunduu iin ilgili yapraa gelene kadar dallardaki kodlar birletirilip
sembollerin kodlar oluturulur. rnein "a" karakterine gelene kadar yalnzca "0" dizisi
ile karlarz. "b" karakterine gelene kadar nce "1" dizisine sonra "0" dizisi ile
karlarz. Dolaysyla "b" karakterinin yeni kodu "10" olacaktr. Bu ekilde btn
karakterlerin sembol kodlar karlr. Karakterlerin sembol kodlar aada bir tablo
halinde gsterilmitir.

Frekans Sembol(Karakter) Bit Says Huffman Kodu

50 a 1 0

35 b 2 10

20 k 3 110
10 m 4 1110

8 d 5 11111

4 5 11110

Sktrlm veride artk ASCII kodlar yerine Huffman kodlar kullanlacaktr. Dikkat
ederseniz hibir Huffman kodu bir dier Huffman kodunun n eki durumunda deildir.
rnein n eki "110" olan hi bir Huffman kodu mevcut deildir. Ayn ekilde n eki "0"
olan hi bir Huffman kodu yoktur. Bu Huffman kodlar ile kodlanm herhangi bir veri
dizisinin "tek zlebilir bir kod" olduunu gstermektedir. Yani sktrlm veriden
orjinal verinin dnda baka bir veri elde etme ihtimali sfrdr. (Tabi kodlamann doru
yapldn varsayyoruz.)

imdi rneimizdeki gibi bir frekans tablosuna sahip olan metnin Huffman algoritmas ile
ne oranda skacan bulalm :

Sktrma ncesi gereken bit saysn bulacak olursak : Her bir karakter eit uzunlukta
yani 8 bit ile temsil edildiinden toplam karakter says olan (50+35+20+10+8+4) = 127
ile 8 saysn arpmamz lazm. Orjinal veriyi sktrmadan saklarsak 127*8 = 1016 bit
gerekmektedir.

Huffman algoritmasn kullanarak sktrma yaparsak ka bitlik bilgiye ihtiya


duyacamz hesaplayalm : 50 adet "a" karakteri iin 50 bit, 35 adet "b" karakteri iin
70 bit, 20 adet "k" karakteri iin 60 bit....4 adet "" karakteri iin 20 bite ihtiya duyarz.
(yukardaki tabloya baknz.) Sonu olarak gereken toplam bit says = 50*1 + 35*2 +
20*3 + 10*4 + 8*5 + 4*5 = 50 + 70 + 60 + 40 + 40 + 20 = 280 bit olacaktr.

Sonu : 1016 bitlik ihtiyacmz 280 bite indirdik. Yani yaklak olarak %72 gibi bir
sktrma gerekletirmi olduk. Gerek bir sistemde sembol frekanslarnda saklamak
gerektii iin sktrma oran %72'ten biraz daha az olacaktr. Bu fark genelde sktrlan
veriye gre ok ok kk olduu iin ihmal edilebilir.

Huffman Kodunun zlmesi

rnekte verilen frekans tablosuna sahip bir metin ierisindeki "aabkdmma" veri
kmesinin sktrlm hali her karakter ile karakterin kodu yer deitirilerek aadaki
gibi elde edilir.

aab k d m m a
0 0 10 110 11111 11110 1110 1110 0 --> 00101101111111110111011100

Eer elimizde frekans tablosu ve sktrlm veri dizisi varsa ilemlerin tersini yaparak
orjinal veriyi elde edebiliriz. yleki; sktrlm verinin ilk biti alnr. Eer alnan bit bir
kod szcne denk geliyorsa, ilgili kod szcne denk den karakter yerine koyulur,
eer alnan bit bir kod szc deilse sonraki bit ile birlikte ele alnr ve yeni dizinin bir
kod szc olup olmadna baklr. Bu ilem dizinin sonuna kadar yaplr ve huffman
kodu zlr. Huffman kodlar tek zlebilir kod olduu iin bir kod dizisinden farkl
semboller elde etmek olanakszdr. Yani bir huffman kodu ancak ve ancak bir ekilde
zlebilir. Bu da aslnda yaznn banda belirtilen kaypsz sktrmann bir sonucudur.

C# ile Huffman Algoritmasnn Gerekletirilmesi

Huffman algoritmas bilgisayar bilimlerinde genellikle metin dosyalarnn sktrlmasnda


kullanlr. Bu yazda rnek bir program ile Huffman algoritmasnn ne ekilde
uygulanacabileceini de greceiz. Dil olarak tabiki C#' kullanlacaktr.
Huffman algoritmasnn uygulanmasndaki ilk adm frekans tablosunun bulunmasdr. Bu
yzden bir dosyay sktrmadan nce dosyadaki her bir karakterin ne sklkla yer aldn
bulmak gerekir. rnek programda sembol frekanslarn bellekte tutmak iin
System.Collections isim alandan bulunan Hashtable koleksiyon yaps kullanlmtr.
rnein "c" karakterinin frekans 47 ise,

CharFrequencies["c"] = 47

eklinde sembolize edilir. rnek programda frekans tablosu aadaki metot ile elde
edilebilir. Sktrlacak dosya batan sona taranarak frekanslar hashtable nesnesine
yerletirilir.

[Not : rnek uygulamada kullandm deiken ve metot isimlerini baz zel nedenlerden
dolay ngilizce yazmak zorunda kaldm iin tm okurlardan zr dilerim.]

private Hashtable CharFrequencies = new Hashtable();

private void MakeCharFrequencies()


{
FileStream fs = File.Open(file,FileMode.Open,FileAccess.Read);

StreamReader sr = new StreamReader(fs,System.Text.Encoding.ASCII);

int iChar;
char ch;
while((iChar = sr.Read()) != -1)
{
ch = (char)iChar;
if(!CharFrequencies.ContainsKey(ch.ToString()))
{
CharFrequencies.Add(ch.ToString(),1);
}
else
{
int oldFreq = (int)CharFrequencies[ch.ToString()];
int newFreq;
newFreq = oldFreq + 1;
CharFrequencies[ch.ToString()] = newFreq;
}
}

sr.Close();
fs.Close();
sr = null;
fs = null;
}

Frekans tablosunu yukardaki metot yardmyla oluturduktan sonra huffman


algoritmasnn en nemli adm olan huffman aacnn oluturulmasna sra geldi. Huffman
aacnn oluturulmas en nemli ve en kritik noktadr. Huffman aac oluturulurken
Tree(aa) veri yapsndan faydalanlmtr. Aataki her bir dm temsil etmek iin bir
snf yazlmtr. Huffman aacndaki dmleri temsil etmek iin kullanlabilecek en basit
dm snfnn yaps aadaki gibidir.
Yukardaki dm yaps algoritmay uygulamak iin gereken en temel dm yapsdr.
Bu yap istenildii gibi geniletilebilir. nemli olan minimum gereklilii salamaktr.
Dm snfndaki SagDm ve SolDm zellikleri de dm trndendir.
Balangtaki dmler iin bu deerler null dr. Her bir yeni dmm oluturulduunda
yeni dmn sa ve sol dmleri oluur. Ancak unutmamak gerekir ki sadece
sembollerimizi oluturan yaprak dmlerde bu zellikler null deerdedir.

rnek uygulamadaki HuffmanNode snfnda ayrca ilgili dmn yaprak olup


olmadn gsteren IsLeaf ve ilgili dmn ana(parent) dmn gsteren
HuffmanNode trnden ParentNode zellikleri bulunmaktadr.

HuffmanNode dm snfnn yaps aadaki gibidir.

using System;

namespace Huffman
{
public class HuffmanNode
{
private HuffmanNode leftNode;
private HuffmanNode rightNode;

private HuffmanNode parentNode;

private string symbol;


private int frequency;
private string code = "";

private bool isLeaf;

public HuffmanNode LeftNode


{
get{return leftNode;}
set{leftNode = value;}
}

public HuffmanNode RightNode


{
get{return rightNode;}
set{rightNode = value;}
}

public HuffmanNode ParentNode


{
get{return parentNode;}
set{parentNode = value;}
}

public string Symbol


{
get{return symbol;}
set{symbol = value;}
}

public string Code


{
get{return code;}
set{code = value;}
}

public int Frequency


{
get{return frequency;}
set{frequency = value;}
}

public bool IsLeaf


{
get{return isLeaf;}
set{isLeaf = value;}
}

public HuffmanNode()
{

}
}

public class NodeComparer : IComparer


{
public NodeComparer()
{
}

public int Compare(object x, object y)


{
HuffmanNode node1 = (HuffmanNode)x;
HuffmanNode node2 = (HuffmanNode)y;

return node1.Frequency.CompareTo(node2.Frequency);
}
}
}

Balangta sembol says kadar HuffmanNode nesnesi yani huffman dm


oluturmamz gerekecektir. Oluturulan bu dmler Arraylist koleksiyon yapsnda
tutulmaktadr. Her bir yeni dm oluturulduunda Arraylist kolaksiyonun yeni bir
dm eklenir ve iki dm karlr. Yeni dmn sa ve sol dmleri karlan
dmler olacaktr. lk oluturulan dmlerin sa ve sol dmlerinin null olduunu
hatrlaynz. Yeni dm eklendiinde Arraylist snfnn Sort() metodu yardmyla
dmler frekanslarna gre kkten bye doru sralanr. Yani Arraylist elemann ilk
eleman en kk frekansl dmdr. Sort() metodu IComparer arayzn kullanan
NodeComparer snfn kullanmaktadr. Yani bu snftaki Compare() metodu yukardaki
kodda belirtildii gibi dm nesnelerinin neye gre sralancan tanmlar.

Yukardaki tanmlar nda Huffman aac aadaki metot yardmyla bulunabilir. Dikkat
ettiyseniz, metodun icras bittiinde Nodes koleksiyonunda tek bir dm nesnesi
kalacaktr, bu da huffman aacndaki kk dmden(root node) bakas deildir.

private ArrayList Nodes;

public void MakeHuffmanTree()


{
Nodes = new ArrayList();

//Balang dmleri oluturuluyor.


foreach(Object Key in CharFrequencies.Keys)
{
HuffmanNode node = new HuffmanNode();
node.LeftNode = null;
node.RightNode = null;
node.Frequency = (int)(CharFrequencies[Key]);
node.Symbol = (string)(Key);
node.IsLeaf = true;
node.ParentNode = null;

Nodes.Add(node);
}

//Dmlerin neye gre sralanaca NodeComparer snfndaki Compare metodunda


tanmldr.
Nodes.Sort(new NodeComparer());

while(Nodes.Count > 1)
{
HuffmanNode node1 = (HuffmanNode)Nodes[0];
HuffmanNode node2 = (HuffmanNode)Nodes[1];

HuffmanNode newnode1 = new HuffmanNode();


newnode1.Frequency = node1.Frequency + node2.Frequency;
newnode1.IsLeaf = false;
newnode1.LeftNode = node1;
newnode1.RightNode = node2;
newnode1.Symbol = node1.Symbol + node2.Symbol;

node1.ParentNode = newnode1;
node2.ParentNode = newnode1;

Nodes.Add(newnode1);

Nodes.Remove(node1);
Nodes.Remove(node2);
Nodes.Sort(new NodeComparer());
}
}

Algoritmann son adm ise Huffman kodlarnn oluturulmasdr. Programatik olarak


kodlamann en zor olduu blm burasdr. Zira burada huffman aac z-
yineli(recursive) olarak taranarak her bir dmn huffman kodu atanacaktr.
Performans artrmak iin semboller ve kod szckleri ayrca bir Hashtable
koleksiyonunda saklanmtr. Bylece her bir kodun zlmesi srasnda aa yaps
taranmayacak, bunun yerine Hashtable'dan ilgili kod bulunacaktr. Kodlamay yapan
metot aadaki gibidir.

private void FindCodeWords(HuffmanNode Node)


{
HuffmanNode leftNode = Node.LeftNode;
HuffmanNode rightNode = Node.RightNode;

if(leftNode == null && rightNode == null)


Node.Code = "1";

if(Node == this.RootHuffmanNode)
{
if(leftNode != null)
leftNode.Code = "0";

if(rightNode != null)
rightNode.Code= "1";
}
else
{
if(leftNode != null)
leftNode.Code = leftNode.ParentNode.Code + "0";

if(rightNode != null)
rightNode.Code= rightNode.ParentNode.Code + "1";
}

if(leftNode != null)
{
if(!leftNode.IsLeaf)
FindCodeWords(leftNode);
else
{
CodeWords.Add(leftNode.Symbol[0].ToString(),leftNode.Code);
}
}

if(rightNode != null)
{
if(!rightNode.IsLeaf)
FindCodeWords(rightNode);
else
{
CodeWords.Add(rightNode.Symbol[0].ToString(),rightNode.Code);
}
}
}

Huffman algoritmasnn temel basamaklar bitmi durumda. Bundan sonraki kodlar elde
edilen sktrlm verinin ne ekilde dosyaya kaydedilecei ve sktrlm dosyann nasl
tekrar geri elde edilecei ile ilgilidir. Bu noktada uygulamamz iin bir dosya format
belirlememiz gerekmektedir. Hatrlanaca zere sktrlm veriyi tekrar eski haline
getirmek iin frekans tablosuna ihtiyacmz vardr. Dolaysyla sktrlm veriyi dosyaya
yazmadan nce dosya formatmzn kurallarna gre sembol frekanslarn dosyaya
yazmamz gerekir.

Benim program yazarken gelitirdiim dosya format aadaki gibidir.

dosya.huff
-----------
1- ) lk 4 byte --> Orjinal verideki toplam sembol says.(ilk byte yksek anlaml byte
olacak ekilde)
2 -) Sonraki 1 byte --> Data blmnde bulunan son byte'taki ilk ka bitin data'ya dahil
olduunu belirtir. (Data blmndeki bitlerin says 8'in kat olmayabilir.)
3 -) 2 byte Sembol + 4 byte sembol frekans (bu blm ilk 4 byte'ta belirtilen sembol
says kadar tekrar edecektir.-ilk byte yksek anlaml byte olacak ekilde-)
4 -) Son blmde ise sktrlm veri bit dizisi eklinde yer alr.

Aadaki metot yukarda belirlenen kurallara gre sktrlm veriyi dosyaya .huff
uzantl olarak kaydedir.

[Not : Yazlacak programa gre bu dosya format deiebilir. rnein birden fazla dosyay
ayn anda sktran bir program iin bu format tamamen deiecektir.]

public void WriteCompressedData()


{
/// 4 byte ->(uint) Sembol Says(K adet)
/// 1 byte ->(uint) Data blmnde bulunan son byte'taki ilk ka bitin data'ya dahil
olduunu belirtir.
///
/// ------------------SEMBOL FREKANS BLM------------------------------------------
///
/// 2 byte Sembol + 4 byte Sembol Frekans
/// .
/// . K adet
/// .
/// 2 byte Sembol + 4 byte Sembol Frekans
///
///
/// ------------------DATA BLM----------------------------------------------------
///
/// Bu blmde Sktrlm veriler byte dizisi eklinde yer alr.
///
/// Data blm (6*K + 6) numaral byte'tan itibaren balar.
///

int K = CharFrequencies.Keys.Count;
/*K = 4 ise
*
* byte[0] = 0 0 0 0 0 1 0 0
* byte[1] = 0 0 0 0 0 0 0 0
* byte[2] = 0 0 0 0 0 0 0 0
* byte[3] = 0 0 0 0 0 0 0 0
*
* K(bits) = 00000100 00000000 00000000 00000000
* */

byte[] byteK = BitConverter.GetBytes(K);

FileStream fs = File.Open(this.NewFile,FileMode.Create,FileAccess.ReadWrite);

byte[] CompressedByteStream = GenerateCompressedByteStream();


WriteByteArrayToStream(byteK,fs);
fs.WriteByte(RemainderBits);

foreach(string sembol in CharFrequencies.Keys)


{
byte[] byteC = BitConverter.GetBytes((char)sembol[0]);
byte[] bytesFreqs = BitConverter.GetBytes((int)CharFrequencies[sembol]);

WriteByteArrayToStream(byteC,fs);
WriteByteArrayToStream(bytesFreqs,fs);
}

WriteByteArrayToStream(CompressedByteStream,fs);

fs.Flush();
fs.Close();
}

Sktrlan bir veri geri elde edilemedii srece sktrmann bir anlam ifade etmeyecei
dnlrse sktrma ileminin tersinide yazmamz gerekmektedir. Sktrma ilemi
yaparken yaptmz ilemlerin tersini yaparak orjinal veriyi elde edebiliriz. Sktrlm bir
dosyay amak iin aadaki admlar izlenir.

1 -) .huff uzantl dosyadan sembol frekanslar okunur ve Hashtable nesnesine


yerletirilir.
2 -) Frekans tablosu kullanlarak Huffman aac oluturulur.
3 -) Huffman aac kullanlarak Huffman kodlar oluturulur.
4 -) .huff uzantl dosyann data blmnden sktrlm veri dizisi okunarak huffman
kodlar ile karlatrlarak orjinal metin bulunur ve .txt uzantl dosyaya yazlr.

2. ve 3. admlardaki ilemler sktrma yapldnda kullanlan ilemler ile ayndr. Burada


ayrca deenmeye gerek yoktur. Bu aamada nemli olan verilen okunmas ve
yazlmasnda izlenen yoldur. Verilerin okunmasnda ve tekrar yazlmasnda StringBuilder
snf kullanlmtr. Bu snf string nesnesine gre olduka iyi performans gstermektedir.
rnein ayn ilemi string ile yaptmda 75 K'lk bir dosya ama ilemi 30 sn srerken
StringBuilder kullandmda 2 sn srmektedir.

1.aamdaki ilemi yapacak metot aadaki gibidir.


private System.Text.StringBuilder CompressedData = new
System.Text.StringBuilder("");

private void ReadCompressedFile()


{
FileStream fs = File.Open(file,FileMode.Open,FileAccess.Read);

//lk nce sembol saysn bulalm.


byte[] byteK = new byte[4];

for(int i=0 ; i<4 ; i++)


{
byteK[i] = (byte)fs.ReadByte();
}

int SymbolCount = BitConverter.ToInt32(byteK,0);

int RemainderBitCount = (byte)fs.ReadByte();

for(int k = 0; k < SymbolCount ; k++)


{
//Sembollerin elde edilmesi(2 byte)
byte[] symbolB = new byte[2];
symbolB[0] = (byte)fs.ReadByte();
symbolB[1] = (byte)fs.ReadByte();

char cSymbol = BitConverter.ToChar(symbolB,0);

//Frekans bilgisinin elde edilmesi(4 byte)


byte[] freqB = new byte[4];
for(int j=0 ; j<4 ; j++)
{
freqB[j] = (byte)fs.ReadByte();
}

int freq = BitConverter.ToInt32(freqB,0);

CharFrequencies.Add(cSymbol.ToString(),freq);
}

//Data blmnn okunmas


int readByte;
while((readByte = fs.ReadByte()) != -1)
{
byte b = (byte)readByte;

bool[] bits = new bool[8];


bits = GetBitsOfByte(b);
BitArray ba = new BitArray(bits);

for(int m=0 ; m < ba.Length ; m++)


{
if(ba[m])
CompressedData.Append("1");
else
CompressedData.Append("0");
}
}

//Son byte'taki fazla veriler atlyor


int removingBits = 8 - RemainderBitCount;

if(RemainderBitCount != 0)
{
CompressedData.Remove(CompressedData.Length - removingBits, removingBits);
}

fs.Flush();
fs.Close();
}

Dosyay aarken son yaplmas gereken adm okunan verilerin dosyaya yazlmasdr. Bir
nceki admda okunan veriler aadaki metot araclyla yeni bir dosyaya kaydedilir.

System.Text.StringBuilder OriginalData = new System.Text.StringBuilder("");

private void WriteOrginalData()


{
FileStream fs = File.Open(this.NewFile,FileMode.Create,FileAccess.ReadWrite);

StreamWriter sw = new StreamWriter(fs,System.Text.Encoding.ASCII);

System.Text.StringBuilder sb = new System.Text.StringBuilder("");

//Hashtable'n performansndan faydalanmak iin kod szckleri ters evrilip yeni bir
hashtable oluturuluyor.
ReverseCodeWordsHashtable();

for(int i=0 ; i < CompressedData.Length ; i++)


{
sb.Append(CompressedData[i]);

string symbol = "";


bool found = false;

if(CodeWords.ContainsValue(sb.ToString()))
{
symbol = (string)ReversedCodeWords[sb.ToString()];
found = true;
}

if(found)
{
OriginalData.Append(symbol);
sb.Remove(0,sb.Length);
}
}
sw.Write(OriginalData.ToString());

sw.Flush();
fs.Flush();
sw.Close();
fs.Close();
}

Yukardaki metotlarn tamam Huffman isimli bir metotta toplanmtr. Dosya sktrma ve
dosya ama iin farkl nesnelerin kullanlmas gerekmektedir. Huffman snfnn rnek
kullanm aada verilmitir.

//Sktrma
Huffman hf1 = new Huffman("deneme.txt");
hf1.Compress();

//Ama
Huffman hf2 = new Huffman("deneme.huff");
hf2.Decompress();

Uygulamay 75 K'lk bir ngilizce metin tabanl dosya zerinde altrdmda dosyann 43
K'ya dtn aadaki gibi gzlemledim.

Umarm faydal bir prgram ve faydal bir yaz olmutur.

Uygulamann btn kodlarn ve proje dosyasn indirmek iin tklaynz.

Not : Bu makalenin son cmlesini yazdmda programn ama modlnde Trke


karakterler ile ilgili bir bug'n olduunu farkettim. Yani u anda herhangi bir trke
karakter ieren dosyay sktrp dosyay tekrar atnzda Trke karakterler yerine "?"
karakterini grecekseniz. En ksa zamanda bug' dzeltip kaynak kodlar yeniden
ykleyeceim. Bug'n nedenini bulup dzelten kiiye spriz bir dl vereceimide
belirtmek isterim.
Bir Arayz, Bir Snf ve Bir Tablo

Bugnk makalemizde, bir arayz uygulayan snf nesnelerinden faydalanarak, bir Sql
tablosundan nasl veri okuyacamz ve deiiklikleri veritabanna nasl gndereceimizi
incelemeye alacaz. Gelitireceimiz rnek, arayzlerin nasl oluturulduu ve bir
snfa nasl uygulandn incelemekle yetinmeyecek, Sql veritabanmzdaki bir tablodaki
belli bir kayda ait verilerin bu snf nesnelerine nasl aktarlacan da ileyecek. Ksacas
uygulamamz, hem arayzlerin hem snflarn hemde Sql nesnelerinin ksa bir tekrar
olucak.

ncelikle uygulamamzn amacndan bahsedelim. Uygulamamz bir Windows uygulamas


eklinde gelitireceiz. Kullanacamz veri tablosunda arkadalarmzla ilgili bir ka veriyi
tutuyor olacaz. Kullanc, Windows formunda, bu tablodaki alanlar iin Primary Key
nitelii tayan bir ID deerini girerek, buna karlk gelen tablo satrna ait verilerini elde
edicek. stedii deiiklikleri yaptktan sonra ise bu deiiklikleri tekrar veritabanna
gnderecek. Burada kullanacamz teknik makalemizin esas amac olucak. Bu kez veri
tablosundan ekip aldmz veri satrnn programdaki edeeri, oluturacamz snf
nesnesi olucak. Bu snfmz ise, yazm olduumuz arayz uygulayan bir snf olucak.
Veriler snf nesnesine, satrdaki her bir alan deeri, ayn isimli zellie denk gelicek
ekilde yklenecek. Yaplan deiiklikler yine bu snf nesnesinin zelliklerinin sahip
olduu deerlerin veri tablosuna gnderilmesi ile gerekletirilecek.

Uygulamamzda, verileri Sql veritabanndan ekmek iin, SqlClient isim uzaynda yer alan
SqlConnection ve SqlDataReader nesnelerini kullanacaz. Hatrlayacanz gibi
SqlConnection nesnesi ile , balanmak istediimiz veritabanna, bu veritabannn
bulunduu sunucu zerinden bir balant tanmlyoruz. SqlDataReader nesnemiz ile de,
sadece ileri ynl ve yanlz okunabilir bir veri akm salayarak, aradmz kayda ait
verilerin elde edilmesini salyoruz. imdi uygulamamz gelitirmeye balayalm.
ncelikle vs.net ortamnda bir Windows Application oluturalm. Burada aadaki gibi bir
form tasarlayalm.

ekil 1. Form tasarmmz.


Kullanc bilgilerini edinmek istedii kiinin IDnosunu girdikten sonra, Getir balkl butona
tklayarak ilgili satrn tm alanlarna ait verileri getirecek. Ayrca, kullanc veriler
zerinde deiiklik yapabilecek ve bunlarda Gncelle balkl butona tklayarak Sql
veritabanndaki tablomuza aktarabilecek. Sql veritabannda yer alan Kisiler isimli
tablomuzun yaps aadaki gibidir.

ekil 2. Tablomuzun yaps.

imdi gelelim iin en nemli ve anahtar ksmlarna. Program kodlarmz. ncelikle


arayzmz tasarlayalm. Arayzmz, sonra oluturacamz snf iin bir rehber
olucak. Snfmz, veri tablomuzdaki alanlar birer zellik olarak tayacana gre
arayzmzde bu zellik tanmlarnn yer almas gerektiini syleyebiliriz. Ayrca ilgili
kiiye ait verileri getirecek bir metodumuzda olmaldr. Elbette bu arayze baka amalar
iin ye tanmlamalarda ekleyebiliriz. Bu konuda tek snr bizim hayal gcmz. in
gerei bu makalemizde hayal gcm biraz ksdm konunun daha fazla dalmamas
amacyla :) . (Ama siz, rnein kullancnn yeni girdii verileri veritabanna yazcak bir
metod tanmnda bir ye olarak ekleyebilir ve gerekli kodlamalar yapabilirsiniz.) te
arayzmzn kodlar.

public interface IKisi


{
/* ncelikle tablomuzdaki her alana karlk gelen zellikler iin tanmlamalarmz
yapyoruz.*/
int KisiID /* KisiID, tablomuzda otomatik artan ve primary key olan bir alandr.
Dolaysyla programcnn var olan bir KisiIDsini deitirmemesi gerekir. Bu nedenle
sadece okunabilir bir zellik olarak tanmlanmasna izin veriyoruz. */
{
get;
}
string Ad /* Tablomuzdaki char tipindeki Ad alanmz iin string tipte bir alan.*/
{
get;set;
}
string Soyad
{
get;set;
}
DateTime DogumTarihi /* Tablomuzda, DogumTarihi alanmz datetime tipinde
olduundan, DateTime tipinde bir zellik tanmlanmasna izin veriyoruz.*/
{
get;set;
}
string Meslek
{
get;set;
}
void Bul(int KID); /* Bul metod, KID parametresine gre, tablodan ilgili satra ait
verileri alcak ve alanlara karlk gelen zelliklere atayacak metodumuzdur.*/
}

imdide bu arayzmz uygulayacamz snfmz oluturalm. Snfmz IKisi


arayznde tanmlanan her yeyi uygulamak zorundadr. Bu bildiiniz gibi arayzlerin bir
zelliidir.

public class CKisi:IKisi /* IKisi arayzn uyguluyoruz.*/


{
/* ncelikle snftaki zelliklerimiz iin, verilerin tutulaca alanlar tanmlyoruz.*/
private int kisiID;
private string ad;
private string soyad;
private DateTime dogumTarihi;
private string meslek;
/* Arayzmzde yer alan yeleri uygulamaya balyoruz.*/
public int KisiID
{
get{ return kisiID;}
}
public string Ad
{
get{return ad;}set{ad=value;}
}
public string Soyad
{
get{return soyad;}set{soyad=value;}
}
public DateTime DogumTarihi
{
get{return dogumTarihi;}set{dogumTarihi=value;}
}
public string Meslek
{
get{return meslek;}set{meslek=value;}
}
public void Bul(int KID)
{
/* ncelikle Sql Veritabanmza bir balant ayoruz.*/
SqlConnection conFriends=new SqlConnection("data source=localhost;integrated
security=sspi;initial catalog=Friends");
/* Tablomuzdan, kullancnn bu metoda parametre olarak gnderdii KID deerini
baz alarak, ilgili KisiIDye ait verileri elde edicek sql kodunu yazyoruz.*/
string sorgu="Select * From Kisiler Where KisiID="+KID.ToString();
/* SqlCommand nesnemiz yardmyla sql sorgumuzu altrlmak zere
hazrlyoruz.*/
SqlCommand cmd=new SqlCommand(sorgu,conFriends);
SqlDataReader rd;/* SqlDataReader nesnemizi yaratyoruz.*/
conFriends.Open(); /* Balantmz ayoruz. */
rd=cmd.ExecuteReader(CommandBehavior.CloseConnection); /* ExecuteReader
ile sql sorgumuzu altryoruz ve sonu kmesi ile SqlDataReader nesnemiz arasnda bir
akm(stream) ayoruz. CommandBehavior.CloseConnection sayesinde, SqlDataReader
nesnemizi kapattmzda, SqlConnection nesnemizinde otomatik olarak kapanmasn
salyoruz.*/
while(rd.Read())
{
/* Eer ilgili KisiIDye ait bir veri satr bulunursa, SqlDataReader nesnemizin
Read metodu sayesinde, bu satra ait verileri snfmzn ilgili alanlarna aktaryoruz.
Bylece, bu alanlarn atand snf zellikleride bu veriler ile dolmu oluyor.*/
kisiID=(int)rd["KisiID"];
ad=rd["Ad"].ToString();
soyad=rd["Soyad"].ToString();
dogumTarihi=(DateTime)rd["DogumTarihi"];
meslek=rd["Meslek"].ToString();
}
rd.Close();
}
public CKisi()
{
}
}

Artk IKisi arayzn uygulayan, CKisi isimli bir snfmz var.imdi Formumuzun kodlarn
yazmaya balayabiliriz. ncelikle module dzeyinde bir CKisi snf nesnesi tanmlayalm.

CKisi kisi=new CKisi();


Bu nesnemiz veri tablosundan ektiimiz veri satrna ait verileri tayacak. Kullanc Getir
balkl button kontrolne bastnda olucak olaylar gerekletirecek kodlar yazalm.

private void btnGetir_Click(object sender, System.EventArgs e)


{
int id=Convert.ToInt32(txtKisiID.Text.ToString()); /* Kullancnn TextBox kontrolne
girdii ID deeri Convert snfnn ToInt32 metodu ile Integera eviriyoruz.*/
kisi.Bul(id); /* Kisi isimli CKisi snfndan nesne rneimizin Bul metodunu
aryoruz.*/
Doldur(); /* Doldur Metodu, kisi nesnesinin zellik deerlerini, Formumuzdaki ilgili
kontrollere alarak, bir nevi veri balama ilemini gerekletirmi oluyor.*/
}

imdide Doldur metodumuzun kodlarn yazalm.

public void Doldur()


{
txtAd.Text=kisi.Ad.ToString(); /* txtAd kontrolne, kisi nesnemizin Ad zelliinin u
anki deeri ykleniyor. Yani ilgili veri satrnn ilgili alan bu kontrole balam oluyor.*/
txtSoyad.Text=kisi.Soyad.ToString();
txtMeslek.Text=kisi.Meslek.ToString();
txtDogumTarihi.Text=kisi.DogumTarihi.ToShortDateString();
lblKisiID.Text=kisi.KisiID.ToString();
}

Evet grld gibi artk aradmz kiiye ait verileri formumuzdaki kontrollere
ykleyebiliyoruz. imdi TextBox kontrollerimizin TextChanged olaylarn kodlayacaz.
Burada amacmz, TextBoxlarda meydana gelen deiikliklerin annda, CKisi snfndan
trettiimiz Kisi nesnesinin ilgili zelliklerine yanstlabilmesi. Bylece yaplan deiiklikler
annda nesnemize yansyacak. Bu nedenle aadaki kodlar ekliyoruz.

/* Metodumuz bir switch case ifadesi ile, ald ozellikAdi parametresine gre, CKisi isimli
snfmza ait Kisi nesne rneinin ilgili zelliklerini deitiriyor.*/
public void Degistir(string ozellikAdi,string veri)
{
switch(ozellikAdi)
{
case "Ad":
{
kisi.Ad=veri;
break;
}
case "Soyad":
{
kisi.Soyad=veri;
break;
}
case "Meslek":
{
kisi.Meslek=veri;
break;
}
case "DogumTarihi":
{
kisi.DogumTarihi=Convert.ToDateTime(veri);
break;
}
}
}
private void txtAd_TextChanged(object sender, System.EventArgs e)
{
Degistir("Ad",txtAd.Text);
}
private void txtSoyad_TextChanged(object sender, System.EventArgs e)
{
Degistir("Soyad",txtSoyad.Text);
}
private void txtDogumTarihi_TextChanged(object sender, System.EventArgs e)
{
Degistir("DogumTarihi",txtDogumTarihi.Text.ToString());
}
private void txtMeslek_TextChanged(object sender, System.EventArgs e)
{
Degistir("Meslek",txtMeslek.Text);
}
private void btnGuncelle_Click(object sender, System.EventArgs e)
{
int id;
id=Convert.ToInt32(lblKisiID.Text.ToString());
Guncelle(id);
}

Grld gibi kodlarmz gayet basit. imdi gncelleme ilemlerimizi


gerekletireceimiz kodlar yazalm. Kullancmz, TextBox kontrollerinde yapt
deiikliklerin veritabannada yanstlmasn istiyorsa Guncelle balkl button kontrolne
tklayacaktr. te kodlarmz.

private void btnGuncelle_Click(object sender, System.EventArgs e)


{
/* Gncelleme ilemi, u anda ekranda olan Kii iin yaplacandan, bu kiiye ait KisiID sini ilgili Labe
alyoruz ve Guncelle isimli metodumuza parametre olarak gnderiyoruz. Asl gncelleme ilemi Guncelle
yaplyor. */
int id;
id=Convert.ToInt32(lblKisiID.Text.ToString());
Guncelle(id);
}
public void Guncelle(int ID)
{
/* Sql Servermza balantmz oluturuyoruz.*/
SqlConnection conFriends=new SqlConnection("data source=localhost;integrated security=sspi;initia
/* Update sorgumuzu oluturuyoruz. Dikkat edicek olursanz alanlara atanacak deerler, kisi isimli ne
deerleridir. Bu zellik deerleri ise, TextBox kontrollerinin TextChanged olaylarna ekldeimiz kodlar ile
tutulmaktadr. En ufak bir deiiklik dahi buraya yansyabilecektir.*/
string sorgu="Update Kisiler Set
Ad="+kisi.Ad+",Soyad="+kisi.Soyad+",Meslek="+kisi.Meslek+",DogumTarihi="+kisi.DogumTarihi.T
Where KisiID="+ID;
SqlCommand cmd=new SqlCommand(sorgu,conFriends); /* SqlCommand nesnemizi sql cmleciimi
balantmz ile oluturuyoruz. */
conFriends.Open(); /* Balantmz ayoruz.*/
try
{
cmd.ExecuteNonQuery(); /* Komutumuzu altryoruz.*/
}
catch
{
MessageBox.Show("Baarsz");
}
finally /* Update ilemi herhangibir neden ile baarsz olsada, olmasada sonu olarak(finally) ak ola
balantmz kapatyoruz. */
{
conFriends.Close();
}
}

te uygulama kodlarmz bu kadar. imdi gelin uygulamamz altrp deneyelim.


ncelikle KisiID deeri 1000 olan satra ait verileri getirelim.

ekil 3. KisiID=1000 Kaydna ait veriler Kisi nesnemize yklenir.


imdi verilerde bir ka deiiklik yapalm ve gncelleyelim. Ben Ad alannda yer alan "S."
deerini "Selim" olarak deitirdim. Bu durum sonucunda yaplan deiikliklerin
veritabanna yazlp yazlmadn ister programmzdan tekrar 1000 nolu satr getirerek
bakabiliriz istersekde Sql Serverdan direkt olarak bakabiliriz. te sonular.

ekil 4. Gncelleme ileminin sonucu.

Programmz elbette gelimeye ok, ama ok ak. rnein kodumuzda hata denetimi
yapmadmz bir ok l nokta var. Bunlarn gelitirilmesini siz deerli okurlarmza
brakyorum. Bu makalemizde zetle, bir arayz bir snfa nasl uyguladmz, bu
arayz nasl yazdmz hatrlamaya altk. Ayrca, snfmza ait bir nesne rneine, bir
tablodaki belli bir veri satrna ait verileri nasl alabileceimizi, bu nesne zelliklerinde
yaptmz deiiklikleri tekrar nasl veri tablosuna gnderebileceimizi inceledik. Bylece
geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dileiyle
hepinize mutlu gnler dilerim.
Arayz(Interface), Snf(Class) ve oklu Kaltm

Bugnk makalemizde, arayzleri incelemeye devam ediceiz. Arayzlerin anlatld ilk


makalemizde, arayzleri kullanmann en byk nedenlerinden birisinin snflara oklu
kaltm destei vermesi olduunu sylemitik. te bu makalemizde, arayzlerin,
snflara oklu kaltm desteini nasl saladn ok basit bir ekilde incelemeye
alacaz. Hi vakit kaybetmeden, basit bir uygulama zerinde bunu gsterelim. Bu
uygulamamzda, snfmza, tanmlam olduumuz iki arayz uygulayacaz. Bylece
snfmz bu iki arayz kaltmsal olarak alm, oklu kaltm uygulam olucak.

using System;
namespace Interfaces2
{
public interface IMusteri /* lk arayzmz tanmlyoruz. */
{
void MusteriDetay();
int ID{get;}
string Isim{get;set;}
string Soyisim{get;set;}
string Meslek{get;set;}
}
public interface ISiparis /* kinci arayzmz tanmlyoruz. */
{
int SiparisID{get;}
string Urun{get;set;}
double BirimFiyat{get;set;}
int Miktar{get;set;}
void SiparisDetay();
}
public class Sepet:IMusteri,ISiparis /* Sepet isimli snfmz hem IMusteri
arayzn hemde ISiparis arayzn uygulayacaktr. */
{
private int id,sipId,mkt;
private string ad,soy,mes,ur;
private double bf;
public int ID
{
get{return id;}
}
public string Isim
{
get{return ad;}
set{ad=value;}
}
public string Soyisim
{
get{return soy;}
set{soy=value;}
}
public string Meslek
{
get{return mes;}
set{mes=value;}
}
public void MusteriDetay()
{
Console.WriteLine(ad+" "+soy+" "+mes);
}
public int SiparisID
{
get{return sipId;}
}
public string Urun
{
get{return ur;}
set{ur=value;}
}
public double BirimFiyat
{
get{return bf;}
set{bf=value;}
}
public int Miktar
{
get{return mkt;}
set{mkt=value;}
}
public void SiparisDetay()
{
Console.WriteLine("----Siparisler----");
Console.WriteLine("Urun:"+ur+" Birim Fiyat"+bf.ToString()+"
Miktar:"+mkt.ToString());
}
}
class Class1
{
static void Main(string[] args)
{
Sepet spt1=new Sepet();
spt1.Isim="Burak";
spt1.Soyisim="Software";
spt1.Meslek="Mat.Mh";
spt1.Urun="Modem 56K";
spt1.BirimFiyat=50000000;
spt1.Miktar=2;
spt1.MusteriDetay();
spt1.SiparisDetay();
}
}
}

ekil 1. Programn almasnn Sonucu.

Yukardaki kodlarda aslnda deiik olarak yaptmz bir ey yok. Sadece


oluturduumuz arayzleri bir snfa uyguladk ve oklu kaltmll gerekletirmi
olduk. Ancak bu noktada dikkat etmemiz gereken bir unsur vardr. Eer arayzler ayn
isimli metodlara sahip olurlarsa ne olur? Bu durumda arayzlerin uyguland snfta,
ilgili metodu bir kez yazmamz yeterli olucaktr. Sz gelimi, yukardaki rneimizde,
Baslat isimli ortak bir metodun arayzlerin ikisi iinde tanmlanm olduunu
varsayalm.

public interface IMusteri


{
void MusteriDetay();
int ID{get;}
string Isim{get;set;}
string Soyisim{get;set;}
string Meslek{get;set;}
void Baslat();
}
public interface ISiparis
{
int SiparisID{get;}
string Urun{get;set;}
double BirimFiyat{get;set;}
int Miktar{get;set;}
void SiparisDetay();
void Baslat();
}

imdi bu iki arayzde ayn metod tanmna sahip. Snfmzda bu metodlar iki kez
yazmak anlamsz olucaktr. O nedenle snfmza aadaki gibi tek bir Baslat metodu
ekleriz. Snf nesnemizi oluturduumuzda, Baslat isimli metodu aadaki gibi
altrabiliriz.
spt1.Baslat();

Fakat baz durumlarda, arayzlerdeki metodlar ayn isimlide olsalar, arayzlerin


uyguland snf ierisinde sz konusu metod, arayzlerin her biri iin ayr ayrda
yazlmak istenebilir. Byle bir durumda ise snf ierisindeki metod yazmlarnda arayz
isimlerini de belirtiriz.rnein;

void IMusteri.Baslat()
{
Console.WriteLine("Mteriler hazrland...");
}
void ISiparis.Baslat()
{
Console.WriteLine("Sipariler hazrland...");
}

Metodlarn isimleri banda hangi arayz iin yazldklarna dikkat edelim. Dier nemli
bir nokta public belirtecinin kullanlmaydr. Public belirtecini kullanmamz durumunda,
"The modifier public is not valid for this item" (public belirleyicisi bu e iin geerli
deildir ) derleyici hatasn alrz. nk, metodumuzu public olarak tanmlamaya gerek
yoktur. Nitekim, bu metodlarn kullanld snflara ait nesnelerden, bu metodlar
armak istediimizde dorudan aramadmz grrz. nk derleyici hangi
arayzde tanmlanm metodun arlmas gerektiini bilemez. Bu metodlar
kullanabilmek iin, nesne rneini ilgili arayz tiplerine dntrmemiz gerekmektedir.
Bu dntrmenin yaplmas ilgili snf nesnesinin, arayz tipinden deikenlere ak bir
ekilde dntrlmesi ile oluur. te bu yzdende bu tip metodlar, tanmlandklar
snf iinde public yaplamazlar. Bu aka dntrme ilemide aadaki rnek
satrlarda grld gibi olur.

IMusteri m=(IMusteri)spt1;
ISiparis s=(ISiparis)spt1;

te imdi istediimiz metodu, bu deiken isimleri ile birlikte aadaki rnek satrlarda
olduu gibi arabiliriz.

m.Baslat();
s.Baslat();

ekil 2. Programn almasnn Sonucu.

Grdnz gibi arayzleri yazmak ve snflara oklu kaltm amacyla uygulamak son
derece kolay. Bylece geldik bir makalemizin daha sonuna. lerleyen makalelerimizde
arayzleri incelemeye devam edeceiz. Hepinize mutlu gnler dilerim.
Arayzler'de is ve as Anahtar Szcklerinin Kullanm

Bugnk makalemizde, arayzlerde is ve as anahtar kelimelerinin kullanmn


inceleyeceiz. Bir snfa arayz(ler) uyguladmzda, bu arayzlerde tanmlanm
metodlar armak iin ounlukla tercih edilen bir teknik vardr. O da, bu snfa ait
nesne rneini, altrlacak metodun tanmland arayz tipine dntrmek ve bu
ekilde armaktadr. Bu teknik, her eyden nce, program kodlarnn okunabilirliini ve
anlalabilirliini arttrmaktadr. yleki, bir isim uzaynda yer alan ok sayda arayzn ve
snfn yer ald uygulamalarda be teknii uygulayarak, hangi arayze ait metodun
altrld daha kolay bir ekilde gzlemlenebilmektedir. Dier yandan bu teknik, ayn
metod tanmlamalarna sahip arayzler iin de kullanlr ki bunu arayzlere oklu kaltmn
nasl uygulandn gsteren bir nceki makalemizde ilemitik.

Bu teknik ile ilgili olarak, dikkat edilmesi gereken bir noktada vardr. Bir snfa ait nesne
rneini, bu snfa uygulamadmz bir arayze ait herhangibir metodu altrmak iin,
ilgili arayz tipine dntrdmzde InvalidCastException istisnasn alrz. Bu
noktay daha iyi vurgulayabilmek iin aadaki rneimizi gz nne alalm. Bu rnekte
iki arayz yer almakta olup, tanmladmz snf, bu arayzlerden sadece bir tanesini
uygulamtr. Ana snfmzda, bu snfa ait nesne rnei, uygulanmam arayz tipine
dntrlm ve bu arayzdeki bir metod arlmak istenmitir.

using System;
namespace Interface3
{
public interface IKullanilmayan
{
void Yaz();
void Bul();
}
public interface IKullanilan
{
void ArayuzAdi();
}
public class ASinifi:IKullanilan
{
public void ArayuzAdi()
{
Console.WriteLine("Arayz adl:IKullanilan");
}
}
class Class1
{
static void Main(string[] args)
{
ASinifi a=new ASinifi();
IKullanilan Kul=(IKullanilan)a;
Kul.ArayuzAdi();
IKullanilmayan anKul=(IKullanilmayan)a;
anKul.Yaz();
}
}
}

Bu rnei derlediinizde herhangibi derleyici hatas ile karlamassnz. Ancak alma


zamannda "System.InvalidCastException: Specified Cast Is Invalid" alma
zaman hatasn alrz. te bu sorunu is veya as anahtar szcklerinin kullanld iki
farkl teknikten birisi ile zebiliriz. Is ve as bu sorunun zmnde ayn amaca hizmet
etmekle beraber aralarnda nemli iki fark vardr. Is anahtar kelimesi aadaki
formasyonda kullanlr.

nesne is tip

Is anahtar kelimesi nesne ile tipi karlatrr. Yani belirtilen nesne ile, bir snf veya
arayz kyaslarlar. Bu sz dizimi bir if karlatrmasnda kullanlr ve eer nesnenin
retildii snf, belirtilen tipteki arayzden uygulanmsa bu koullu ifade true deerini
dndrecektir. Aksi durumda false deerini dndrr. imdi bu teknii yukardaki
rneimize uygulayalm. Yapmamz gereken deiiklik Main metodunda yer almaktadr.

static void Main(string[] args)


{
ASinifi a=new ASinifi();
IKullanilan Kul=(IKullanilan)a;
Kul.ArayuzAdi();
if(a is IKullanilmayan)
{
IKullanilmayan anKul=(IKullanilmayan)a;
anKul.Yaz();
}
else
{
Console.WriteLine("ASinifi, IKullanilmayan arayzn uygulamamtr.");
}
}

ekil 1: is Anahtar Kelimesinin Kullanm.

If koullu ifadesinde, a isimli nesneyi oluturduumuz ASinifi snfna, IKullanilmayan


arayzn uygulayp uyguladmz kontrol etmekteyiz. Sonu false deerini
dndrecektir. Nitekim, ASinifi snfna, IKullanilmayan arayzn uygulamadk.
Is anahtar szc arayzler dnda snflar iinde kullanabiliriz. Bununla birlikte is
anahtar szc kullanldnda, program kodu Intermediate Language (IL) (Ortak Dile)
evrildiinde, yaplan denetlemenin iki kere tekrar edildiini grrz. Bu verimlilii
drc bir etkendir. te is yerine as anahtar szcn tercih etmemizin
nedenlerinden biriside budur. Dier taraftan is ve as teknikleri, dndrdkleri deerler
bakmndan da farkllk gsterir. Is anahtar kelimesi, bool tipinde ture veya false
deerlerini dndrr. As anahtar kelimesi ise, bir nesneyi , bu nesne snfna uygulanm
bir arayz tipine dntrr. Eer nesne snf, belirtilen arayz uygulamamsa,
dntrme ilemi yinede yaplr, fakat dntrlmenin aktarld deiken null
deerine sahip olur. As anahtar kelmesinin formu aadaki gibidir.

snf nesne1=nesne2 as tip

Burada eer nesneye belirtilen tipi temsil eden arayz uygulanmamsa, nesne null
deerini alr. Aksi durumda nesne belirtilen tipe dntrlr. te is ile as arasndaki
ikinci farkta budur. Konuyu daha iyi anlayabilmek iin as anahtar kelimesini yukardaki
rneimize uygulayalm.

static void Main(string[] args)


{
ASinifi a=new ASinifi();
IKullanilan Kul=(IKullanilan)a;
Kul.ArayuzAdi();
IKullanilmayan anKul=a as IKullanilmayan;
if(anKul!=null)
{
anKul.Yaz();
}
else
{
Console.WriteLine("ASinifi IKullanilmayan tipine dntrlemedi");
}
}

Burada a nesnemiz ASinifi snfnn rneidir. As ile bu rnei IKullanilmayan arayz


tipinden anKul deikenine aktarmaya alyoruz. te bu noktada, ASinifi,
IKullanilmayan arayzn uygulamad iin, anKul deikeni null deerini alcaktr. Sonra
if koullu ifadesi ile, anKul un null olup olmad kontrol ediyoruz. Uygulamay
altrdmzda aadaki sonucu elde ederiz.

ekil 2: as Anahtar Kelimesinin Kullanm

Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dileiyle
hepinize mutlu gnler dilerim.
Snf (Class) Kavamna Giri

Bu makalemizde ADONET kavram ierisinde snflar nasl kullanabileceimizi incelemeye


alacak ve snf kavramna ksa bir giri yapcaz. Nitekim C# dili tam anlamyla nesne
ynelimli bir dildir. Bu dil ierisinde snf kavramnn nemli bir yeri vardr. Bu kavram iyi
anlamak, her trl teknikte, snflarn avantajlarndan yararlanmanz ve kendinize zg
nesnelere sahip olabilmenizi salar. Zaten .net teknolojisinde yer alan her nesne, mutlaka
snflardan tretilmektedir.

evremize baktmz zaman, ok eitli canllar grrz. rnein iekler. Dnya


zerinde ka tr(cins) iek olduunu bileniniz var m ? Ama biz bir iek grdmzde
ona ounlukla iek diye hitap ederiz zellikle adn bilmiyorsak. Sonra ise bu iein
renginden, yapraklarnn eklinden, ait olduu trden, adndan bahsederiz. iek tm bu
iekler iin temel bir snf olarak kabul edilebilir. Dnya zerindeki tm iekler iin ortak
nitelikleri vardr. Her iein bir renginin(renklerinin) olmas gibi. te nesne ynelimli
programlama kavramnda bahsedilen ve her eyin temelini oluturan snf kavram bu
benzetme ile tamamen ayndr. iek bir snf olarak alglanrken, sokakta grdmz
her iek bu snfn ortak zelliklerine sahip birer nesne olarak nitelendirilebilir. Ancak
tabiki iekler arasnda da trler mevcuttur. Bu trler ise, iek temel snfndan treyen
kendi belirli zellikleri dnda iek snfnn zelliklerinide kaltsal olarak alan baka
snflardr. Bu yaklam inheritance (kaltm) kavram olarak ele alnr ve nesne ynelimli
programlamann temel esinden biridir. Kaltm konusuna ve dierlerine ilerliyen
makalelerimizde deinmeye alacaz.

Bugn yapacamz bir snfn temel yap talarna ksaca deinmek ve kendimize ait
iimize yarayabiliecek bir snf tasarlamak. iek snfndan gerek C# ortamna
getiimizde, her eyin bir nesne olduunu grrz. Ancak her nesne temel olarak Object
snfndan tremektedir. Yani hereyin stnde bir snf kavram vardr. Snflar, bir takm
yelere sahiptir. Bu yeler, bu snftan rneklendirilen nesneler iin farkl deerlere sahip
olurlar. Yani bir snf varken, bu snftan rneklendirilmi n sayda nesne oluturabiliriz.
Kaldki bu nesnelerin her biri, tanmland snf iin ayr ayr zelliklere sahip olabilirler.

ekil 1. Snf (Class) ve Nesne (Object) Kavram

Bir snf kendisinden oluturulacak nesneler iin bir takm yeler iermelidir. Bu yeler,
alanlar (fields), metodlar (methods), yapclar (constructor), zellikler (properties),
olaylar(events), delegeler (delegates) vb dr. Alanlar verileri snf ierisinde tutmak
amacyla kullanlrlar. Bir takm ilevleri veya fonksiyonellikleri gerekletirmek iin
metodlar kullanrz. ounlukla snf iinde yer alan alanlarn veya zelliklerin ilk
deerlerin atanmas gibi hazrlk ilemlerinde ise yapclar kullanrz. zellikler kapslleme
dediimiz Encapsulating kavramnn bir parasdr. ounlukla, snf iersinden
tanmladmz alanlara, dardan dorudan eriilmesini istemeyiz. Bunun yerine bu
alanlara erien zellikleri kullanrz. te bu snf iindeki verileri d dnyadan
soyutlamaktr yani kapsllemektir. Bir snfn genel hatlar ile ierecei yeleri aadaki
ekilde de grebilirsiniz.

ekil 2 . Bir snfn yeleri.

Snflar ile ilgili bu ksa bilgilerden sonra dilerseniz snf kavramn daha iyi anlamamz
salyacak basit bir rnek gelitirelim. Snflar ve yeleri ile ilgili dier kavramlar kodlar
ierisinde yer alan yorum satrlarnda aklamaya devam edeceiz. Bu rnek
almamzda, Sql Suncusuna balanrken, balant ilemlerini kolaylatracak birtakm
yeler salyan bir snf gelitirmeye alacaz. Kodlar yazdka bunu ok daha iyi
anlayacaksnz. te bu uygulama iin gelitirdiimiz, veri isimli snfmzn kodlar.

using System;
using System.Data.SqlClient;
namespace Veriler /* Snfmz Veriler isimli isim uzaynda yer alyor. ou zaman ayn
isme sahip snflara sahip olabiliriz. te bu gibi durumlarda isim uzaylar bu snflarn
birbirinden farkl olduunu anlamamza yardmc olurlar.*/
{
public class Veri /* Snfmzn ad Veri */
{
/* zleyen satrlarda alan tanmlamalarnn yapldn grmekteyiz. Bu alanlar
private olarak tanmlanmtr. Yani sadece bu snf ierisinden eriilebilir ve deerleri
deitirilebilir. Bu alanlar tanmladmz zelliklerin deerlerini tutmak amacyla
tanmlyoruz. Amacmz bu deerlere snf dndan dorudan eriilmesini engellemek.*/
private string SunucuAdi;
private string VeritabaniAdi;
private string Kullanici;
private string Parola;
private SqlConnection Kon; /* Burada SqlConnection tipinden bir deiken
tanmladk. */
private bool BaglantiDurumu; /* Sql sunucumuza olan balantnn ak olup
olmadna bakcaz.*/
private string HataDurumu; /* Sql sunucusuna balanrken hata olup olmadna
bakacaz.*/
/* Aada sunucu adnda bir zellik tanmladk. Herbir zellik, get veya set
bloklarndan en az birini iermek zorundadr. */
public string sunucu /* public tipteki yelere snf iinden, snf dndan veya
tretilmi snflardan yani ksaca heryerden eriilebilmektedir.*/
{
get
{
return SunucuAdi; /* Get ile, sunucu isimli zellie bu snfn bir
rneinden eriildiinde okunacak deerin alnabilmesi salanr . Bu deer bizim private
olarak tanmladmz SunucuAdi deikeninin deeridir. */
}
set
{
SunucuAdi=value; /* Set blounda ise, bu zellie, bu snfn bir
rneinden deer atamak istediimizde yani zelliin gsterdii private SunucuAdi
alannn deerini deitirmek iin kullanrz. zellie snf rneinden atanan deer,
value olarak tanmakta ve SunucuAdi alanna aktarlmaktadr.*/
}
}
public string veritabani
{
get
{
return VeritabaniAdi;
}
set
{
VeritabaniAdi=value;
}
}
public string kullanici /* Bu zellik sadece set blouna sahip olduu iin sadece
deer atanabilir ama ierii grntlenemez. Yani kullanici zelliini bir snf rneinde,
Kullanici private alannn deerini renmek iin kullanamayz.*/
{
set
{
Kullanici=value;
}
}
public string parola
{
set
{
Parola=value;
}
}
public SqlConnection con /* Buradaki zellik SqlConnection nesne trndendir ve
sadece okunabilir bir zelliktir. Nitekim sadece get blouna sahiptir. */
{
get
{
return Kon;
}
}
public bool baglantiDurumu
{
get
{
return BaglantiDurumu;
}
set /* Burada set blounda baka kodlar da ekledik. Kullancmz bu snf
rnei ile bir Sql balants yarattktan sonra eer bu balanty amak isterse
baglantiDurumu zelliine true deerini gndermesi yeterli olucaktr. Eer false deeri
gnderirse balant kapatlr. Bu ilemleri gerekletirmek iin ise BaglantiAc ve
BaglantiKapat isimli sadece bu snfa zel olan private metodlarmz kullanyoruz.*/
{
BaglantiDurumu=value;
if(value==true)
{
BaglantiAc();
}
else
{
BaglantiKapat();
}
}
}
public string hataDurumu
{
get
{
return HataDurumu;
}
}
public Veri() /* Her snf mutlaka hi bir parametresi olmayan ve yandaki satrda
grld gibi, snf ad ile ayn isme sahip bir metod ierir. Bu metod snfn yapc
metodudur. Yani Constructor metodudur. Bir yapc metod iersinde ounlukla, snf
iinde kullanlan alanlara balang deerleri atanr veya ilk atamalar yaplr. Eer siz bir
yapc metod tanmlamaz iseniz, derleyici aynen bu metod gibi bo bir yapc oluturacak
ve saysal alanlara 0, mantksal alanlara false ve string alanlara null balang
deerlerini atayacaktr.*/
{
}
/* Burada biz bu snfn yapc metodunu ar yklyoruz. Bu snftan bir nesneyi
izleyen yaplandrc ile oluturabiliriz. Bu durumda yapc metod ierdii drt
parametreyi alcaktr. Metodun amac ise belirtilen deerlere gre bir Sql balants
yaratmaktr.*/
public Veri(string sunucuAdi,string veritabaniAdi,string kullaniciAdi,string sifre)
{
SunucuAdi=sunucuAdi;
VeritabaniAdi=veritabaniAdi;
Kullanici=kullaniciAdi;
Parola=sifre;
Baglan();
}
/* Burada bir metod tanmladk. Bu metod ile bir Sql balants oluturuyoruz.
Eer bir metod geriye herhangibir deer gndermiyecek ise yani vb.net teki
fonksiyonlar gibi almayacak ise void olarak tanmlanr. Ayrca metodumuzun sadece
bu snf ierisinde kullanlmasn istediimiz iin private olarak tanmladk. Bu sayede bu
snf dndan rnein formumuzdan ulaamamalarn salam oluyoruz.*/
private void Baglan()
{
SqlConnection con=new SqlConnection("data source="+SunucuAdi+";initial
catalog="+VeritabaniAdi+";user id="+Kullanici+";password="+Parola);
Kon=con;
}
/* Bu metod ile Sql sunucumuza olan balanty ayoruz ve BaglantiDurumu
alanna true deerini aktaryoruz.*/
private void BaglantiAc() /* Bu metod private tanmlanmtr. nk sadece bu
snf ierisinden arlabilsin istiyoruz. */
{
Kon.Open();
try
{
BaglantiDurumu=true;
HataDurumu="Baglanti salandi";
}
catch(Exception h)
{
HataDurumu="Baglanti Salanamd. "+h.Message.ToString();
}
}
/* Bu metod ilede Sql balantmz kapatyor ve BaglantiDurumu isimli alanmza
false deerini akataryoruz.*/
private void BaglantiKapat()
{
Kon.Close();
BaglantiDurumu=false;
}
}
}

imdi ise snfmz kullandmz rnek uygulama formunu tasarlayalm . Bu uygulamamz


aadaki form ve kontrollerinden oluuyor.
ekil 3. Form Tasarmmz.

Formumuza ait kodlar ise yle.

Veriler.Veri v;
private void btnBaglan_Click(object sender, System.EventArgs e)
{
/* Bir snf rnei yaratmak iin new anahtar kelimesini kullanrz. New anahtar
kelimesi bize kullanabileceimiz tm yapc metodlar gsterecektir. (IntelliSense
zellii). */
v=new Veri(txtSunucu.Text,txtVeritabani.Text,txtKullanici.Text,txtParola.Text);

}
private void btnAc_Click(object sender, System.EventArgs e)
{
v.baglantiDurumu=true;
stbDurum.Text="Sunucu Balants Ak? "+v.baglantiDurumu.ToString();
}
private void btnKapat_Click(object sender, System.EventArgs e)
{
v.baglantiDurumu=false;
stbDurum.Text="Sunucu Balants Ak? "+v.baglantiDurumu.ToString();
}

imdi uygulamamz bir altralm.


ekil 5. Balanty amamz halinde.

ekil 6. Balanty kapatmamz halinde.

Deerli okurlarm, ben bu snfn gelitirilmesini size brakyorum. Umarm snf kavram ile
ilgili bilgilerimizi hatrlam ve yeni ufuklara yelken amaya hazr hale gelmisinizdir. Bir
sonraki makalemizde snflar arasnda kaltm kavramna bakcak ve bylece nesneye
dayal programlama terminolojisinin en nemli kavramlarndan birini incelemeye
alsacaz. Hepinize mutlu gnler dilerim.

Burak Selim ENYURT

You might also like