Professional Documents
Culture Documents
Csharp Burakselimsenyurt 2004 PDF
Csharp Burakselimsenyurt 2004 PDF
//dosya ad : Merhaba.cs
using System;
namespace MerhabaDunya
{
class Snf1
{
static void Main(string args[])
{
Console.WriteLine("Merhaba Dnya");
}
}
}
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.
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
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.
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;
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.
te bu da bizim kodumuz :
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#, 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.
.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.
Dersimizin hedefleri :
using System;
class Booleans
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.
Ondalkl saylar ksuratl ilemlerde kullanmak iyi olur. Bunun yannda muhasebe ve
finansal ilemler iin decimal veri tipi daha uygun olacak ekilde tasarlanmtr.
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
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);
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.
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
using System;
class Binary
{
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);
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.
Dersimizin hedefleri :
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.
using System;
class IfSelect
{
public static void Main()
{
string myInput;
int 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);
}
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.
using System;
class SwitchSelect
{
public static void Main()
{
tring myInput;
int myInt;
begin:
decide:
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.
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
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.
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.
}
imdi sra elemanlarla ilgili olaylarn birbirleri ile ilikisine.Mesela bir buton formunun click
olaynn form tarafndan yakalanabilmesi iin aadaki satrlar yazmalyz.
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.
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#, 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.
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.
Visual Studio.NET iinde bir Visual C# projesi bulunan bir solution oluturdu. Proje
assemblyinfo.cs ve class1.cs adl iki tane dosya iermektedir.
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.
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.
Programmzn kts
imdi basit bir Hello World uygulamas gelitirmi olduk, imdi de bir Visual C#
uygulamasnn basit componentlerini inceleyelim.
// 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.
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 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.
Main() Fonksiyonu
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");
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
Programmz sralama yapmadan nce giriten satrlar alarak bir dizi iinde saklamas
gerekir. imdi .NET temel snflarndan olan ArrayList snfn inceleyeceiz.
// isimalan tanmlama
namespace c#nedircom
{
// uygulama snf tanmlama
class QuickSortApp
{
// uygulama balangc
static void Main (string[] szArgs)
{
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.
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
{
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.
1. class1.cs dosyasna aada krmz ile yazlanlar yazn. Burada snf ismi ve
isimalan ismi bizim iin ok nemli deildir.
namespace c#nedircom
{
class QuickSortApp
{
// QuickSort fonksiyonu
static void QuickSort (ArrayList szArray, int nLower, int nUpper)
{
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.
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.
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 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.
Debugger 'n kontrol bizde iken farenin imlecini kaynak kodda istediimiz deiken
zerine gtrerek deikenin o anki deerini renebiliriz.
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.
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
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 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.
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)
Bu metod ile Soketin baglanip baglanmadigini geri dnen bool degeri ile anliyoruz.Eger
soket hedef kaynaga bagliysa true degilse false degerine geri dner.
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.
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.
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
//Bilgi alisverisi iin bilgi almak istedigimiz port numarasini TcpListener sinifi ile
gereklestiriyoruz
Console.WriteLine("Sunucu baslatildi...") ;
//StreamReader ile String veri tipine aktarma islemi nceden bir hata olursa bunu
handle etmek gerek
try
{
string IstemciString = AkimOkuyucu.ReadLine();
AkimYazici.Flush() ;
}
catch
{
Console.WriteLine("Sunucu kapatiliyor...");
return ;
}
}
}
IstemciSoketi.Close();
Console.WriteLine("Sunucu Kapatiliyor...");
}
}
//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 Form1()
{
InitializeComponent();
}
string yazi;
AkimYazici.WriteLine(textbox.Text);
AkimYazici.Flush();
yazi = AkimOkuyucu.ReadLine();
MessageBox.Show(yazi,"Sunucudan Mesaj var");
}
catch
{
MessageBox.Show("Sunucuya baglanmada hata oldu...");
}
}
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.
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.
using System;
using System.IO;
using System.Text;
class TextFile
{
public static void Main(string[] args)
{
// Metin dosyamza bireyler yazan fonksiyon..
DosyayaYaz();
Console.ReadLine();
}
//Dosyamzn kapatlm..
dosya.Close();
while(yazi!=null)
{
Console.WriteLine(yazi);
yazi=dosyaOku.ReadLine();
}
// dosyamz kapatyoruz..
dosyaOku.Close();
}
// Dosyamz kapatyoruz..
dosya.Close();
}
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.
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.
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;
this.soyadi=null;
this.kullandigiDil=null;
}
this.kullandigiDil=null;
}
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.
[C#]
using System;
[VB.NET]
Imports System
sub Main()
End Sub
[Managed C++]
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.
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;
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;
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.
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
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.
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.
Bu konu snflarla ilgili bir konu olduu iin detaylarna girmeyeceiz ama imdilik byle
bir kullanmn geerli olduunu bilmenizde fayda var.
Sabitler
const double pi = 3.14 ; // double, kesirli saylar tutmak iin tanmlanm bir veri
trdr.
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 ;)
.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.
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 :
float fl = 3.14f ;
decimal d = 65.25M;
bool b = false ;
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.
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.
Escape sequence 'leri kullanmak yerine string iinde grnen ifadenin ayns belirtmek
iin string ifadesinin nne @ iareti kullanlr.Mesela ;
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.
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.
:: OpenSubKey() Metodu ::
Bu metod iki ekilde kullanlabilir, overload edilmi iki metod aadaki gibidir.
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.
:: 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 ::
:: 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.
:: GetValue() Metodu ::
lgili anahtardaki deerin ieriini object tr olarak geri dnderir.ki ekilde kullanlabilir.
Parametrik yaps aadaki gibidir.
:: GetValueNames() Metodu ::
lgili anahtardaki btn deerleri bir string dizine aktarr.Parametrik yaps aadaki
gibidir
:: SetValue() Metodu ::
Birinci parametresi ile belirtilen anahtara ikinci parametresi ile belirtilen bilgi
aktarlr.Parametrik yaps aadaki gibidir.
:: Name zellii ::
:: ValueCount zellii ::
RegistryKey snfnn ye elmanlar ve oluturduu exception snflar ile ilgili detayl bilgiyi
MSDN Online' dan yada .NET Framework SDK Documentation ' dan edinebilirsiniz.
//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
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.
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.
using System;
namespace assembly1
{
class csnedir1
{
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
{
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.)
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.
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
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
...............
[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
Kaynaklar
Pointer = Gsterici
Function = Fonksiyon
Array = Dizi
Template = ablon
yazilar.txt
resgen yazilar.txt
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;
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.
Son olarak Close ilevi ile hafzada bulunan bilgiler yazilar.resource dosyasna yazlr. Bu
ilevi kullanmadmzda bilgiler dosyaya kaydedilmeyecektir.
Formumuzu tasarladktan sonra Form1 'in load metodunu aadaki gibi dzenleyin.
label1.Text = rsm.GetString("Pointer");
label2.Text = rsm.GetString("Function");
label3.Text = rsm.GetString("array");
label4.Text = rsm.GetString("Template");
}
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.
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.
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();
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.
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:
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();
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.
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.
.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.
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();
Console.ReadLine();
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();
// 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();
Console.ReadLine();
}
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.
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();
Console.ReadLine();
}
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
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.
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.
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;
}
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
* 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);
}
}
yada
int* ptr1;
*ptr1 = 50;
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:
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.
.NET Mimarisi
Yeni bir dil - C#
.NET Mimarisi
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.
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.
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:
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, 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.
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.
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.
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.
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.
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 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.
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.
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.
JAVA daki extends ve implements anahtar szckleri C# te yerini iki nokta iaretine(:)
brakmtr.
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?
----------------------------
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.
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)
{
}
}
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.
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)
{
}
}
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.
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);
}
}
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.
+ , - , -- , ++ , -=, +=
using System;
class Gosterici
{
unsafe static void Main()
{
int* ptr1 = (int*)500;
int* ptr2 = (int*)508;
Console.WriteLine(fark);
}
}
Diger bir ilgin nokta iki gstericinin adres bilesenlerinin farki gsterici trlerinin
byklgnn tam kati olmadiginda grlr. rnegin ptr2 gstericisini tanimlanmasini
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.
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);
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);
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.
Gstericilerle ilgili son yazda, yap gstericileri, gstericiler ile dizi ilemleri ve stackalloc
ile dinamik alan tahsisat yapma gibi konular inceleyeceiz.
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.
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.
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.
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;
scaklk=15;
this.renk=renk;
this.marka= marka;
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.
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
{
Console.ReadLine();
}
class t
{
public int scaklk;
public string renk;
public string marka;
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 t2 = new t("","");
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?"
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."
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.
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};
1
2
3
4
*(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]
*(ptr+0) == ptr[0]
*(ptr+1) == ptr[1]
*(ptr+2) == ptr[2]
*(ptr+3) == ptr[3]
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};
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.
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];
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];
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);
}
Bu program ile alma zamannda 7 elemanl stack tabanl bir dizinin oluturulduunu
aadaki ekran grntsnden grebilirsiniz.
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;
class StackAlloc
{
unsafe static void Main()
{
Yapi yapi = new Yapi(2,'a',"Deneme");
using System;
struct Yapi
{
int x;
char c;
class StackAlloc
{
unsafe static void Main()
{
Yapi yapi = new Yapi(2,'a');
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.
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
Not: Gstericilerle ilgili yaynlanan bu makale dizisi yazm olduum ve yaknda Pusula
yaynclktan kacak olan C# kitabndan alnmtr.
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.
Yukardaki deyimleri bir dng iinde yapp oluturduumuz Button kontrollerinin ilgili
zelliklerini deitirdikten sonra dama tahtasn rahatlkla oluturabiliriz.
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);
tb.Location = p;
tb.FlatStyle = FlatStyle.Standard;
tb.Click += new System.EventHandler(this.button1_Click);
Butonlar.Add(tb);
this.Controls.Add(tb);
sutun++;
}
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.
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).
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.
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.
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
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>*/
Bunlarn dnda bir nceki versiyonla yeni versiyondaki kullanmlar birletirip ayn
kaynak kod iinde aadaki gibi de kullanabiliriz.
/**
<summary>Yorum
satiri
*/
/// <summary>
Yapsal Deiiklikler
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;
}
}
//Geersiz Bildirim
public int IArayuz.get_a()
{
}
//Geersiz Bildirim
public int IArayuz.set_a(int deger)
{
}
}
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.
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);
}
}
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.
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.
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.
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
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.
using System;
namespace Property_Makale
{
class Otomobil
{
public int model;
public string marka;
public string renk;
this.marka=marka;
this.renk=renk;
}
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;
this.marka=marka;
this.renk=renk;
}
class OtomobilTest
{
static void Main(string[] args)
{
Otomobil oto1 = new Otomobil(2000, "BMW" , "Siyah");
oto1.OzellikleriGoster();
oto1.ModelDegistir(300);
oto1.OzellikleriGoster();
}
}
}
using System;
namespace Property_Makale
{
class Otomobil
{
private int model;
public string marka;
public string renk;
this.marka=marka;
this.renk=renk;
}
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();
}
}
}
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.
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.
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.
using System;
using System.Runtime.InteropServices;
class Class1
{
[DllImport("user32.dll")]
public static extern int MessageBox(int tip,string mesaj,string baslik,int secenek);
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.
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);
imdi de DllImport nitelii ile ilgili dier zelliklere ve nemli noktalara bakalm.
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.
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.
.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
{
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
{
if(sira.Contains(7))
Console.WriteLine("Sramzda " + sayi + " var.");
else
Console.WriteLine("Sramzda " + sayi + " yok.");
while ( Enum.MoveNext() )
Console.Write( "\t{0}", Enum.Current );
Console.WriteLine();
}
}
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
{
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.
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.
}
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.
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.
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.
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.
7) Kapat Dmesi
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
}
}
else
{
Close();
}
}
Burada yaplanlardan farkl olan hi bir ey yok. Degisim deerini kontrol ediyoruz ve ona
gre ilem yapyoruz..
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.
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.
2 - Iterators
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
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];
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);
int a = (int)Pop();
class Stack
{
private int current_index;
private Veri tr[] elemanlar;
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.
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.
}
}
}
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.
}
}
}
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.
}
}
}
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 :
foreach(object o in alist)
{
BiseylerYap(o);
}
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.
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.
Yukardaki Snf nesneler ile foreach dngs kullanldnda her bir iterasyonda
elemanlar dizisinin bir sonraki elemanna ulalr.
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 Form
{
dugme = new Button();
dugme.Click += new EventHandler(OnClick);
}
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 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
//Dosya2.cs
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.
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.
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.
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.
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 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.
XML yorum etiketleri yukarda anlatlanlar ile snrl deildir. Aada kullanlabilecek
standart etiketler alfabetik sraya gre toplu bir ekilde tablo halinde aklamalaryla
birlikte verilmitir.
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)
{
...
}
<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 :
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 :
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;
}
rnek :
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
{
...
}
rnek :
///<value>
/// Kontroln rengini belirtir.
///</value>
public int Renk
{
get { return a;}
set { a = value;}
}
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.
II. Daha sonra .Netin Ana Proje Penceresindeki MenuBardan ToolsI tklayn
alan menuItemlardan Add/Remove ToolBoxItems tklayn.
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
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.)
using System;
using System.Windows.Forms;
namespace Miras
public Person()
}
}
using System.Windows.Forms;
namespace Miras
{
this.Name=name;
this.Age = age;
this.Gender=gender;
using System;
using System.Windows.Forms;
namespace Miras
// miras alyor
}
public Teacher(string name,int age,string gender,string unvan)
this.Name=name;
this.Age = age;
this.Gender=gender;
this.Unvan=unvan;
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.
.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?
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.
o Kod standardize olduu iin daha sonra programnzn kodunu baka bir
program yardmyla iyiletirebilirsiniz.
Dier baz notasyonlar ise Sun Java notation, SmallTalk Roll Based Naming,
Taligent Form dur.
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
Evet bu kadarlk giri yeter. imdi yukarda anlattm 3 maddeyi enine boyuna
tartalm.
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.
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.
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.)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
.Net'te ise bu skntlar atlatld. imdi projemiz ile ilgili birok veriyi saklayabileceimiz,
gvenli bir dosyaya kavutuk. te bu dosyann ad web.config
<configuration>
<appSettings>
<add key="strConn"
value="server=localhost;uid=dtuser;pwd=dtpass;database=dotnet" />
</appSettings>
</configuration>
Tablomuz:
registerUser
Stored 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
@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>
register.aspx
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;
try
{
//parolanz ifrelenmesi iin fonksiyona gnderiyoruz.
//ifrelenmi verimiz byte haline gelecei iin
deikenimizi
//byte olarak tanmlyoruz.
byte[] encyrptedPassword =
md5Password(txtParola);
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();
}
}
login.aspx
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;
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();
}
}
}
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! )
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
tp = new Bitmap("tp.bmp");
//anlayacagiz.
Yhareket=-Yhareket;
pos.X += Xhareket;
pos.Y += Yhareket;
//burada saglayacagiz.
//top ekrandaysa,
Xhareket = -Xhareket;
}
if(pos.Y < 0)
Yhareket = -Yhareket;
}// yanarsa,
//top durur
Xhareket = 0;
Yhareket = 0;
//hakki 1 azalt
hak -= 1;
pos.X += Xhareket;
pos.Y += Yhareket;
Blok.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
int LastposY = 0;
return myRect;
LastposX = pos.X;
LastposY = pos.Y;
if (pos.X <= 0) //eger pencerenin en solundaysa hareket etmeyecek, degilse sola dogru
hareketine devam edecektir.
return;
pos.X -= inc;
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
this.yukseklik=yuk;
this.genislik=gen;
this.basx=startx;
this.basy=starty;
Grup.cs:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace alleyway
{
Bitmap br=null;
public Brick[,] yapi; //brick sinifinda nesneleri tutan matrisimiz burada yaratiliyor.
int sat=8;
public Grup()
reset(); //vurulmus duurmda olan bloklar varsa bunlari da vurulmadi olarak isaretleyen
ve ilk haline dndren metod agrilir.
if (yapi[i,j].vuruldu==false)
g.DrawImage(br,temp.basx,temp.basy,br.Width,br.Height);
if (br==null)
{
br = new Bitmap("Brick.bmp");
yapi[i,j].vuruldu=false;
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
private Blok blok = new Blok(275, 490); //alttaki ubugun yeri belirlenir.
public Form1()
InitializeComponent();
//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 );
///
///
this.timer1.Enabled = true;
this.timer1.Interval = 50;
this.KeyPreview = true;
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);
#endregion
[STAThread]
Application.Run(new Form1());
Graphics g = e.Graphics;
top.Draw (g);
grup.Draw(g);
//yapilir.
Invalidate(blok.GetFrame());
switch (result)
break;
blok.MoveRight(ClientRectangle);
break;
default:
break;
{ //timer 'in her tikinde top ve bloklar kesisti mi? kontrol yapilir ve kesisme
varsa o blok vuruldugu iin ekrandan silinir.
flag=true;
if(top.GetFrame().IntersectsWith(r_brick))
if (grup.yapi[i,j].vuruldu==false)
grup.yapi[i,j].vuruldu=true;
if (top.pos.Y>500)
form3.ShowDialog(this);
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();
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
///
///
int ppuan;
///
///
//
ppuan=puan;
InitializeComponent();
//
//
///
///
if( disposing )
if(components != null)
components.Dispose();
base.Dispose( disposing );
///
///
this.SuspendLayout();
//
// label1
//
this.label1.Name = "label1";
this.label1.TabIndex = 0;
//
// label2
//
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.Name = "OK";
this.OK.TabIndex = 2;
this.OK.Text = "Baslat";
//
// button2
//
this.button2.Name = "button2";
this.button2.TabIndex = 3;
this.button2.Text = "Yeter";
//
// label3
//
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 24);
this.label3.TabIndex = 4;
//
// Form3
//
this.BackColor = System.Drawing.Color.SkyBlue;
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.ResumeLayout(false);
#endregion
{
this.label3.Text = ppuan.ToString();
Application.Exit();
Form2.cs:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace alleyway
///
///
int hhak;
///
//
//
hhak=hak;
InitializeComponent();
//
//
///
///
if( disposing )
if(components != null)
{
components.Dispose();
base.Dispose( disposing );
///
///
this.SuspendLayout();
//
// label2
//
this.label2.Name = "label2";
this.label2.TabIndex = 5;
//
// button1
//
this.button1.Name = "button1";
this.button1.TabIndex = 4;
this.button1.Text = "Devam";
//
// label1
//
this.label1.Name = "label1";
this.label1.TabIndex = 3;
//
// Form2
//
this.BackColor = System.Drawing.Color.SkyBlue;
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.ResumeLayout(false);
#endregion
label2.Text=hhak.ToString();}
this.Close();
}
C# ile Yazc kts Alma lemleri
.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
Cancel : kt alma ileminin iptal edilip edilemeyecei ile ilgili bilgi veren bool trnden
bir elemandr. Eer deeri true ise kt alma ilemi iptal edilecektir.
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();
}
}
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.
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;
try
{
PD.Print();
}
catch
{
Console.WriteLine("Yazici iktisi alinamiyor...");
}
finally
{
PD.Dispose();
}
}
string line=null;
LineCount++;
}
if (line = = null)
e.HasMorePages = false ;
else
e.HasMorePages = true ;
}
}
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.
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
}
PrinterSettings yolu ile elde edebileceimiz dier nemli zellikler aada listelenmitir.
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.
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.
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
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.
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.
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 :
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.
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.
(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.
// Gn tanm :
((0?[1-9])|([12][0-9])|(3[01]))
(0?[1-9])
// 1, 2, .., 9, 01, 02, .., 09 gibi yazlm aylar tanmlar.
(1[0-2])
// 10, 11, 12 aylarn tanmlar.
// Ay Tanm :
((0?[1-9])|(1[0-2]))
([12][0-9][0-9][0-9])
//1000 ile 2999 yllar arasndaki tm yllar ierir.
((0?[1-9])|([12][0-9])|(3[01]))(/)(0?[1-9]|1[0-2])(/)([12][0-9][0-9][0-9]))
using System.Text.RegularExpressions;
class Test
string tarihDeseni=@"(?((0?[1-9])|([12][0-9])|(3[01]))(/)(0?[1-
9]|1[0-2])(/)([12][0-9][0-9][0-9]))";
string metin=Console.ReadLine();
MatchCollection benimMatchCollection=benimRegex.Matches(metin);
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.
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 :
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.
"(href=)((')|(""))"
"(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.
"(href=)((')|(""))(mailto:)(?<mail>(.*))((')|(""))"
Ksaca, "mailto:" ile trnak karakterleri arasndaki her ifade bizim iin mail grubuna dahil
oldu.
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
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
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();
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:
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
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.
Abstract Factory
Builder
Factory Method
Prototype
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.
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.
private SingletonDeseni()
{
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
private SingletonDeseni()
{
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.
yada
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.
private 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)
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.
private 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.
private SingletonDeseni()
{
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.
Bir dier "Creational Patterns" deseni olan "Abstract Factory" desenini anlatacam yazda
grmek zere.
XP Stilinde Kontroller ile alma
Microsoft Framework v1.1 de bu zellik henz pratik bir ekilde yok. Bu yzden yolumuz
biraz uzun.
File/New/Project i tklayn.
Ayn pencerede Location alannda mevcut yolun sonundaki klasr isminide XPStyle
yapn.
Alan pencerede Templates ksmnda XML File(herhangi bir .cs dosyas da olabilir)
sein.
<dependentAssembly>
</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 dosyay kopyalayp, Obj klasrnn iine girin, buradan da Debug klasrne tklayp
iine girin ve dosyay buraya yaptrn.
Alan Custom Resource Type penceresinde Resource Type alanna RT_MANIFEST yazn
ve Okey butonuna tklayn.
Bu dosyay kapatn.
Projeyi altrn.
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
1. kme : 000
2. kme : 000
3. kme : 032
4. kme : 313
5. kme : 234
3.aama
rakam[0] = "000"
rakam[5] = "234"
olur
olur.
4.aama
rn:
yuzler.SetValue("ikiyuz",2);
onlar.SetValue("otuz",3);
birler.SetValue("drt",4);
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
{
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
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.
using System;
namespace numbereader
{
public class SayiOkuma
{
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
*/
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);
return sonuc;
else
cozum = sorun;
return cozum;
}
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:
// 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.
// 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.
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.
//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.
sayac = sayac+1;
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.
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.
Yukardaki kodun tamam ana formumuz iinde yer alan kodlard. imdi de ana formda
tua baslnca oluturulan formun iinde koda bakalm.
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.
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
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.
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.
using System;
namespace ConsoleApplication2
{
class Class1
{
static void Main()
{
int x = 10;
int y = 20;
Degistir(x,y);
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);
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.
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;
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
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 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.
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.
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;
Console.WriteLine(b);
}
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.
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.
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.
UML Modeli
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.
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.
using System;
namespace DesignPattern
{
abstract class SoyutArabaFabrikasi
{
abstract public SoyutArabaKasasi KasaUret();
abstract public SoyutArabaLastigi LastikUret();
}
class FabrikaOtomasyon
{
private SoyutArabaKasasi ArabaKasasi;
private SoyutArabaLastigi ArabaLastigi;
class UretimBandi
{
public static void Main()
{
SoyutArabaFabrikasi fabrika1 = new MercedesFabrikasi();
FabrikaOtomasyon fo1 = new FabrikaOtomasyon( fabrika1 );
fo1.LastikTak();
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.
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.
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.
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.
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:
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:
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.
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)
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?
class Debug
{
[conditional("TRACE")]
public void Trace(string s)
{
Console.WriteLine(s);
}
}
class MyClass
{
public static void Main()
{
Debug.Trace("hello");
}
}
class B
{
B(int i)
{ }
}
class C : B
{
C() : base(5) //
B(5) i arr.
{ }
ifade is tr
namespace Foo
{
enum Colors
{
BLUE,
GREEN
}
class Bar
{
Colors color;
Bar() { color = Colors.GREEN;}
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.
S - 11 : Her birinde farkl Main() metodu olan birden fazla kaynak kod dosyam var:
derleme srasnda hangi Main() metodunun kullanlacan nasl bildirebilirim?
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)
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.
using System.Runtime.InteropServices;
class C
{
[DllImport("user32.dll")]
public static extern int MessageBoxA(int h, string m, string c, int type);
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]);
}
}
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 )
class Test
{
public void foo(ref
int i)
{
i = 1;
}
Console.WriteLine("It
worked");
}
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.
class C
{
~C()
{
// your code
}
S - 27 : Derleme srasnda neden "CS5001: does not have an entry point defined -
tanmlanm giri noktas yok- " hatasn alyorum?
class test
{
static void Main(string[] args) {}
}
class C
{
public void Run()
{
lock(this)
{
// function body
}
}
lock(obj)
{
// code
}
try
{
CriticalSection.Enter(obj);
// code
}
finally
{
CriticalSection.Exit(obj);
}
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.
using System;
class Class1
{
private string[] MyField;
class MainClass
{
public static int Main(string[] args)
{
Class1 c = new Class1();
return 0;
}
}
S - 34 : Birden fazla assembly ile oklu dil destei salanabilirmi?
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.
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.");
}
}
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.
using System;
kt
1
2
3
1
a
test
10
11
12
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 - 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 {}
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.
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");
kt
Null Object is []
Real Object is [StringTest]
i is [10]
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
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.
char c = 'f';
System.Console.WriteLine((int)c);
System.Console.WriteLine((int)s[3]);
kodunu kullanabilirsiniz.
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.
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
gotoif A, lab1
goto lab2:
lab1:
kodu
koduna dntrlr.
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);
}
}
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;
}
MyConstants.A eklindeki kullanm ile 1 saysnn kullanm arasnda bir fark yoktur. Yani
ayn kod retilecektir.
using System;
using System.Diagnostics;
[Obsolete]
public int Foo() {...}
yada
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.
C - 60 : Evet. rnek :
using System;
using System.Threading;
class ThreadTest
{
public void runme()
{
Console.WriteLine("Runme Called");
}
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.
try bloundan nde deikeni null deere atamakla derleyicinin CS0165 (Use of possibly
unassigned local variable 'conn' ) hatasn vermesini engellemi oluruz.
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.
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.
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
XmlNodeList Isimler,Isimler2,Isimler3,Isimler4,Isimler5;
//XmlNodeList trinden deikenlerimizi tanmlyoruz.
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.
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.
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.
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:
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++
Viusal C#
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.
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.
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.
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]);
}
return sb.ToString();
"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
....
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";
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.
// Degisken tanimlari
string str="";
for(int i=0;i<10000;i++)
str +=i.ToString();
//-------------------------------------------------------
Console.WriteLine();
for(int i=0;i<10000;i++)
sb.Append(i.ToString());
//-------------------------------------------------------
Console.WriteLine();
Console.ReadLine();
}
"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.
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.
UML Modeli
Bu ksa aklamadan sonra yukardaki diyagram baz alarak modern bir programlama
dili olan C# ile bu deseni nasl gerekletirebileceimizi inceleyelim.
using System;
namespace BuilderPattern
{
public interface IBilgisayarToplayicisi
{
Bilgisayar Bilgisayar{get;}
void CDROM_Olustur();
void HDD_Olustur();
void Monitor_Olustur();
void RAM_Olustur();
}
public GoldPC()
{
mBilgisayar = new Bilgisayar("Gold-PC");
}
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();
tekniksevis.BilgisayarTopla(BT1);
teknikservis.BilgisayarTopla(BT2);
BT1.Bilgisayar.BilgisayariGoster();
Console.WriteLine("-------------");
BT2.Bilgisayar.BilgisayariGoster();
}
}
}
Desenlerle ilgili bir sonraki yazmda Creational desenlerden olan "Prototype" desenini
ele alacam. Herkese iyi almalar.
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.
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
....
using System;
using System.Threading;
class Test
{
public static int result;
public static volatile bool finished;
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.
private 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.
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.
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;
}
[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:
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
{
/* 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";
}
}
string veritabaniAdi;
stbDurumBilgisi.Text=lstDatabase.SelectedItem.ToString()+"
"+kv.BaglantiDurumu;
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.
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.
using System;
namespace enumSample1
{
class Class1
{
enum Gunler
{
Pazartesi,
Sali,
Carsamba,
Persembe,
Cuma,
Cumartesi,
Pazar
}
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,
}
using System;
namespace enumSample
{
class Class1
{
}
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
{
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.
.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.
"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 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.
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.
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.
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, uygulama retkenliini hzlandracak dier .NET dillerinde olmayan bir takm
zellikleri iinde barndrr.
ifadesi de geerlidir.
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.
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+ +
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.
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.
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.
Gelimi hata ayklama(debug) : Visual Studio hata ayklaycs ayn anda hem
native hemde ynetilebilir kodda hata ayklama desteini benzer bir ekilde sunar.
Visual C#
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.
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.
Tm CLR trleri iin destek : C# dili tm CLR veri tiplerini destekler , programclar
zm sunarken .NET ortamnn ynetilen alma ortamnn tm zelliklerinden
yararlanrlar.
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.
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.
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.
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.
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.
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
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;
return sonuc;
}
Console.WriteLine("8*5={0}",cl.Carpim(8,5));
Console.ReadLine();
}
}
}
Bu rnei altracak olursak, aadaki sonucu elde ederiz.
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,
kinci admda,
dizi[0]=8
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.
Console.ReadLine();
}
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.
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
{
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);
}
public CDataSet()
{
}
}
}
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.*/
}
}
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);
Umuyorumki params anahtar szc ile ilgili yeterince bilgi sahibi olmusunuzdur. Bir sonraki makalemizde
grmek dileiyle hepinize mutlu gnler dilerim.
C#'ta zyenilemeli Algoritmalar (Recursion)
sterseniz konunun kafanzda daha iyi canlanmas iin klasik faktoriyel rneiyle devam
edelim. Sfrdan byk herhangi bir n tamsaysnn faktoriyelinin forml udur:
Bir saynn, mesela n, faktoriyelini zyenilemeli deilde dng kullanarak bulmak istersek
aadakine benzer bir kod kullanabiliriz:
int faktoriyel = 1;
n! = n * (n-1)!
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.
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.
MessageBox.Show(sonucMetin.ToString(),"Faktoriyel Hesab");
}
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:
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:
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.
Program test etmek iin Fibonacci(15) deerini bulmak istersek aadaki sonucu elde
ederiz.
zyenilemeli Algoritma rnei: Fibonacci Serisi
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
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.
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;
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());
}
}
}
Zaman z;
Satr yerine
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.
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
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. */
/* Bir dizi zellik tanmlayarak private olarak tanmladmz asl alanlarn kullanmn kolaylatryoruz. */
public string Kosucu
{
get
{
return kosucuAdi;
}
set
{
kosucuAdi =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 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;
}
}
}
Bir sonraki makalemizde grmek dileiyle. Hepinize mutlu gnler dilerim
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();
}
}
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.
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.
"
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).
["Yaayan Matematik",s.53]
Tavsiyeler
Referans
"Yaayan Matematik", Theoni PAPPAS, Trke'ye eviren: Yldz SLER, Sarmal Yaymevi,
Ekim 1993.
Windows XP Stillerinin Kontrollere Uyarlanmas
imdi snfmzn boyanmas iin OnPaint metoduna geebiliriz. lknce Normal deerini
grelim.
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);
e.Graphics.FillRectangle(Brushes.Blue,rect);
}
else
{
//Burada Styles.System deerini uygulayacaz.
}
}
Dikkat edeceiniz gibi standart bir ProgressBarn yapaca ilemleri gerekletirdik. imdi
asl amacmz XP sitillerinin uygulanmas olduuna gre bu aamaya geelim.
bool IsThemedos()
{
if(Environment.OSVersion.Platform != PlatformID.Win32NT
|| Environment.OSVersion.Version.Major < 5
|| Environment.OSVersion.Version.Minor < 1)
return false;
return true;
}
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:
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 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:
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 (rect.Width>(Width-2*3))
{
rect.Width = rc.Width;
}
DrawThemeBackground(g,3,1,rect);
}
Not : XP stilindeki kontrolleri grmeniz iin iletim sisteminizin temasn XP Stil olarak
deitirmeniz gerekmektedir.
Hashtable Koleksiyon Snfnn Kullanm
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.
MessageBox.Show(deger,lstAnahtar.SelectedItem.ToString());
}
lstAnahtar.Items.Remove(lstAnahtar.SelectedItem);
stbDurum.Text="ikartildi";
stbDurum.Text=htTeknikSozluk.Count.ToString();
}
}
Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dieiyle hepinize
mutlu gnler dilerim.
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;
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.
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
{
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.*/
}
}
}
}
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);
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.*/
}
}
}
}
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. */
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.*/
}
}
}
}
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.
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.*/
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("----");
}
}
}
}
namespace ReflectionSample3
{
public class OrnekSinif
{
private int deger;
int yas=27;
string dogum="istanbul";
}
}
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.
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
{
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);
}
}
}
}
}
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.
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
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.
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.
.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.
yada
Eer kaynak kodumuzu altrlabilir bir uygulama yerine bir ktphane dosyas olacak
ekilde derlemek istiyorsak aadaki komutu kullanmalyz.
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.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.
Parametre Kullanm
/help
Derleyici parametreleri ile ilgili yardm bilgilerinin
yada
grntlenmesini salayan parametrelerdir.
/?
/linkresource:dosya_adi
Belirtilen .NET kaynak(resource) dosyasna bir balant
oluturmak iin bu parametreler kullanlabilir.
/linkres:dosya_adi
.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.
bool long
byte sbyte
char short
double uint
float ushort
int
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
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());
}
}
}
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());
}
}
}
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.
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.
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.
for(int i=1;i<60;++i)
{
zaman1.Value+=1;
for(int j=1;j<10000000;++j)
{
j+=1;
}
}
}
for(int j=1;j<25000000;++j)
{
j+=1;
}
}
}
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.
for(int i=1;i<60;++i)
{
zaman1.Value+=1;
for(int j=1;j<10000000;++j)
{
j+=1;
}
}
}
for(int j=1;j<25000000;++j)
{
j+=1;
}
}
}
ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;
ts2=new ThreadStart(z2);
t1=new Thread(ts1);
t2=new Thread(ts2);
t2.Start();
btnBaslat.Enabled=false;
}
t2.Suspend();
}
t2.Resume();
}
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.
Evet geldik Threading ile ilgili makale dizimizin ilk blmnn sonuna . Bir sonraki
makalemizde Threading kavramn daha da derinlemesine incelemeye alacaz.
Hepinize mutlu gnler dilerim.
{
for(int i=1;i<100;++i)
{
pb1.Value+=1;
Thread.Sleep(800);
}
}
{
for(int i=1;i<100;++i)
{
pb3.Value+=1;
Thread.Sleep(300);
}
}
ThreadStart ts1;
ThreadStart ts2;
ThreadStart ts3;
Thread t1;
Thread t2;
Thread t3;
ts2=new ThreadStart(pb2Ileri);
ts3=new ThreadStart(pb3Ileri);
t1=new Thread(ts1);
t2=new Thread(ts2);
t3=new Thread(ts3);
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;
hatasn alrz. Yani i paracmz tekrar batan balatmak gibi bir ansmz yoktur.
Kodlarmza geelim.
{
try
{
for(int i=1;i<100;++i)
{
pb1.Value+=1;
Thread.Sleep(800);
}
}
catch(ThreadAbortException hata)
{
}
finally
{
}
}
{
for(int i=1;i<100;++i)
{
pb3.Value+=1;
Thread.Sleep(300);
}
}
ThreadStart ts1;
ThreadStart ts2;
ThreadStart ts3;
Thread t1;
Thread t2;
Thread t3;
ts1=new ThreadStart(pb1Ileri);
ts2=new ThreadStart(pb2Ileri);
ts3=new ThreadStart(pb3Ileri);
t1=new Thread(ts1);
t2=new Thread(ts2);
t3=new Thread(ts3);
t1.Start();
t2.Start();
t3.Start();
btnBaslat.Enabled=false;
btnDurdur.Enabled=true;
btnDevam.Enabled=false;
}
t2.Suspend();
t3.Suspend();
btnDurdur.Enabled=false;
btnDevam.Enabled=true;
}
t2.Resume();
t3.Resume();
btnDurdur.Enabled=true;
btnDevam.Enabled=false;
}
Uygulamamz deneyelim.
Deerli okurlarm geldik bir makalemizin daha sonuna. Bir sonraki makalemizde de
Threading konusunu ilemeye devam edeceiz. Hepinize mutlu gnler dilerim.
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.
Yukarda bulunan her iki rneimiz de derleyici tarafndan gzard edilecektir. Yorum
kullanmak kodlarnzn anlabilirliini arttrd iin mutlaka kullanlmaldr. Bunu da
belirtmeden gemeyim.
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.
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.
Turul ARAS
C# ile ok Kanall(Multithread) Uygulamalar 3
ncelik Deeri
Highest
AboveNormal
Normal
BelowNormal
Lowest
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.
/* 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();
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;
t1=new Thread(ts1);
t2=new Thread(ts2);
/* paracklarmz altryoruz.*/
t1.Start();
t2.Start();
btnBaslat1.Enabled=false;
btnIptal.Enabled=true;
}
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.
/* 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. */
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;
}
t1.Priority=tp1;
t2.Priority=tp2;
}
ThreadStart ts1;
ThreadStart ts2;
Thread t1;
Thread t2;
ts1=new ThreadStart(Say1);
ts2=new ThreadStart(Say2);
t1=new Thread(ts1);
t2=new Thread(ts2);
/* paracklarmz altryoruz.*/
t1.Start();
t2.Start();
btnBaslat1.Enabled=false;
btnIptal.Enabled=true;
tbOncelik1.Enabled=false;
tbOncelik2.Enabled=false;
}
t1.Abort();
t2.Abort();
btnBaslat1.Enabled=true;
btnIptal.Enabled=false;
tbOncelik1.Enabled=true;
tbOncelik2.Enabled=true;
}
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.
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.
"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.
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.
1 --> 0 0 0 0 0001
2 --> 0 0 0 0 0010
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.
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 ;
}
int XOR = 0;
for(int i = 0; i
XOR = XOR + (int)(anahtar[i]);
fsHedefDosya.Close();
fsKaynakDosya.Close();
}
}
}
Hemen programn sonucunu grelim :
Aadaki gibi gizlilik derecesi yksek olan bir metin dosyas oluturun.
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.
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.
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.
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.
DataSet ds;
dataGrid1.DataSource=ds.Tables[0];
}
conNorthwind.Open();
ds=new DataSet();
daNorthwind.Fill(ds);
conNorthwind.Close();
MessageBox.Show("DataTable dolduruldu...");
}
Doldur();
}
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.
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;
conNorthwind.Open();
ds=new DataSet();
daNorthwind.Fill(ds);
conNorthwind.Close();
MessageBox.Show("DataTable dolduruldu...");
}
ThreadStart ts1;
Thread t1;
else
{
MessageBox.Show("Is paracigi henz sonlandirilmadi...Daha sonra
tekrar deneyin.");
}
}
t1=new Thread(ts1);
t1.Start();
}
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.
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.
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.
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
Arayzlerde Kullanlamayan
yeler
i. Yapclar (constructors)
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;
double isim
{
get;
set;
}
string soyisim
{
get ;
}
void yaz();
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;
}
}
Grld gibi kullanmadmz tm arayz yeleri iin bir hata mesaj olutu. Bu
noktada unu tekrar hatrlatmak istiyorum,
private int y;
private string i;
public Kisiler()
{
y=18;
i="Yok";
}
y=yas;
i=ad;
}
set
{
y=value;
}
}
set
{
i=value;
}
}
class Arayuz_Deneme
{
{
Kisiler kisi=new Kisiler("Burak",27);
Console.WriteLine("Yam "+kisi.Yas.ToString());
Console.WriteLine("Adm "+kisi.Isim);
Console.WriteLine("-----------");
kisi.EkranaYaz();
}
}
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), 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.
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.*/
class Class1
{
Calistir.a=System.Convert.ToInt32(Console.ReadLine());
if(Calistir.a>=10)
{
c.Metod1(t1);
}
else
{
c.Metod1(t2);
}
}
}
s}
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. */
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("---");
t1+=t2;
Console.WriteLine("t1 ve t2");
temsilciler.TemsilciCalistir(t1);
Console.WriteLine("---");
Console.WriteLine("t1,t2 ve t3");
temsilciler.TemsilciCalistir(t1);
Console.WriteLine("---");
temsilciler.TemsilciCalistir(t1);
Console.WriteLine("---");
}
}
}
Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde temsilcilerin kullanld
olaylar(events) kavramna gireceiz. Hepinize mutlu gnler dilerim.
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.
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.
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.
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.
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.
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.
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.
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.
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.]
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;
}
using System;
namespace Huffman
{
public class HuffmanNode
{
private HuffmanNode leftNode;
private HuffmanNode rightNode;
public HuffmanNode()
{
}
}
return node1.Frequency.CompareTo(node2.Frequency);
}
}
}
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.
Nodes.Add(node);
}
while(Nodes.Count > 1)
{
HuffmanNode node1 = (HuffmanNode)Nodes[0];
HuffmanNode node2 = (HuffmanNode)Nodes[1];
node1.ParentNode = newnode1;
node2.ParentNode = newnode1;
Nodes.Add(newnode1);
Nodes.Remove(node1);
Nodes.Remove(node2);
Nodes.Sort(new NodeComparer());
}
}
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.
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.]
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
* */
FileStream fs = File.Open(this.NewFile,FileMode.Create,FileAccess.ReadWrite);
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.
CharFrequencies.Add(cSymbol.ToString(),freq);
}
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.
//Hashtable'n performansndan faydalanmak iin kod szckleri ters evrilip yeni bir
hashtable oluturuluyor.
ReverseCodeWordsHashtable();
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.
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.
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.
Artk IKisi arayzn uygulayan, CKisi isimli bir snfmz var.imdi Formumuzun kodlarn
yazmaya balayabiliriz. ncelikle module dzeyinde bir CKisi snf nesnesi tanmlayalm.
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);
}
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
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();
}
}
}
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();
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();
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
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();
}
}
}
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.
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.
Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde grmek dileiyle
hepinize mutlu gnler dilerim.
Snf (Class) Kavamna Giri
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.
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.
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;
}
}
}
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();
}
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.