Adım Adım Microsoft Visual C# 2008

® ®

John Sharp
Çeviri: Ümit Tezcan

arkadaþ YAYINEVÝ Yuva Mahallesi 3702. Sokak No: 4 Yenimahalle / Ankara Tel:+90-312 394 62 70 (pbx) Faks: +90-312 394 62 85 e-posta: info@arkadas.com.tr www.arkadas.com.tr Yayıncı Sertifika No: 12382 Orijinal Ýngilizce Baský: Microsoft Visual C# 2008 Step By Step, John Sharp

© Copyright 2008, John Sharp ORÝJÝNAL YAYINCI Microsoft Press A Division of Microsoft Corporation One Microsoft Way Redmond, WA 98052-6399 ile yapýlan anlaþma sonucu tüm haklarýyla yayýmlanmýþtýr.

© Türkçe yayým haklarý arkadaþ yayýnevinindir. Yayýncýnýn yazýlý izni olmadan, hiçbir biçimde ve hiçbir yolla, bu kitabýn içeriðinin bir kýsmý ya da tümü yeniden üretilemez, çoðaltýlamaz ve daðýtýlamaz.

ISBN 978-975-509-614-8 ANKARA, 2009

Çeviri Proje Editörü Yayına Hazırlık Sayfa Düzeni Baský

: Ümit Tezcan : M. Selim Tosun : Zeynep Kopuzlu : Emine Özyurt : Ankamat Matbaacılık

Microsoft, Microsoft Press, MSDN, SQL Server, Excel, Intellisense, Internet Explorer, Jscript, Silverlight, Visual Basic, Visual C#, Visual Studio, Win32, Windows, Windows Server ve Windows Vista Amerika Birleşik Devletleri ve/veya diğer ülkelerde Microsoft Corporation’ın kayıtlı ticari markaları ya da ticari markalarıdır. Kitapta geçen diğer ürün ve şirket adları sahiplerinin ticari markaları olabilir. Kitapta geçen örnek şirketler, kuruluşlar, ürünler, etki alanı adları, e-posta adresleri, logolar, kişiler, yerler ve olaylar tümüyle gerçekdışıdır. Herhangi bir gerçek şirket, kuruluş, ürün, etki alanı adı, e-posta adresi, logo, kişi, yer ve olayla bir ilişki kurulmamıştır ya da bu biçimde anlaşılmamalıdır.

Bir Bakışta İçindekiler
Kısım I

Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş
C#’a Hoşgeldiniz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Değişkenler, İşleçler ve Deyimlerle Çalışmak . . . . . . . . . . . . . . . 29 Yöntemler Yazmak ve Kapsam Uygulamak . . . . . . . . . . . . . . . . . 49 Karar İfadeleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Bileşik Atama ve Yineleme İfadeleri Kullanmak . . . . . . . . . . . . . 85 Hatalar ve Özel Durumları Yönetmek . . . . . . . . . . . . . . . . . . . . 103

1 2 3 4 5 6
Kısım II

C# Dilini Anlamak
Sınıflar ve Nesneleri Yaratmak ve Yönetmek . . . . . . . . . . . . . . Değerleri ve Başvuruları Anlamak . . . . . . . . . . . . . . . . . . . . . . . Numaralandırma ve Yapılar ile Değer Türleri Yaratmak . . . . . Dizileri ve Koleksiyonları Kullanmak . . . . . . . . . . . . . . . . . . . . . Parametre Dizilerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . Kalıtım ile Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak . . . . . . . . Çöp Toplama ve Kaynak Yönetimini Kullanmak . . . . . . . . . . . . 123 145 167 185 207 217 239 257

7 8 9 10 11 12 13 14
Kısım III

Bileşenler Yaratmak
Alanlara Erişmek İçin Özellikler Uygulamak . . . . . . . . . . . . . . . Dizinleyicileri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Program Akışını Kesmek ve Olayları İşlemek . . . . . . . . . . . . . . Generics’e Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Koleksiyonları Numaralandırmak . . . . . . . . . . . . . . . . . . . . . . . Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . İşleç Aşırı Yüklemesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 295 311 333 355 371 395

15 16 17 18 19 20 21

iii

iv

Bir Bakışta İçindekiler

Kısım IV

Windows Uygulamaları ile Çalışmak
Windows Presentation Foundation’a Giriş . . . . . . . . . . . . . . . . 415 Menüler ve İletişim Kutularıyla Çalışmak . . . . . . . . . . . . . . . . . 451 Doğrulamayı Gerçekleştirmek . . . . . . . . . . . . . . . . . . . . . . . . . . 473

22 23 24
Kısım V

Veriyi Yönetmek
Bir Veritabanında Bilgi Sorgulamak . . . . . . . . . . . . . . . . . . . . . . 499 Veri Bağlamayı Kullanarak Veriyi Görüntülemek ve Düzenlemek . . . . . . . . . . . . . . . . . . . . 529

25 26

Kısım VI

Web Uygulamaları Oluşturmak
ASP .NET’e Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Web Formları Doğrulama Denetimlerini Anlamak . . . . . . . . . Bir Web Sitesinin Güvenliğini Sağlamak ve Web Formlarıyla Verilere Erişmek . . . . . . . . . . . . . . . . . . . . . . . Bir Web Servisi Yaratmak ve Kullanmak . . . . . . . . . . . . . . . . . . 559 587 597 623

27 28 29 30

İçindekiler
Teşekkürler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xix

Kısım I

Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş
C#’a Hoşgeldiniz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Visual Studio 2008 Ortamını Kullanarak Programlamaya Başlamak . . . . . . . . . . 3 İlk Programınızı Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Ad Alanlarını Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Grafiksel Uygulama Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Bölüm 1 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

1

2

Değişkenler, İşleçler ve Deyimlerle Çalışmak . . . . . . . . . . . . . . . . 29
İfadeleri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Tanımlayıcıları Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Anahtar Sözcükleri Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Değişkenleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Değişkenleri Adlandırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Değişkenleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Temel Veri Türleri ile Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Temel Veri Türü Değerlerini Görüntülemek . . . . . . . . . . . . . . . . . . . . . . . . 34 Aritmetik İşleçleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 İşleçler ve Türler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Aritmetik İşleçleri İncelemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Önceliği Denetlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 İşlemleri Gerçekleştirmek İçin Birleşim Özelliğini Kullanmak . . . . . . . . . . 44 Birleşim ve Atama İşleci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

v

vi

İçindekiler

Değişkenleri Artırmak ve Azaltmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Önek ve Sonek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Kapalı Türde Yerel Değişkenleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Bölüm 2 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

3

Yöntemler Yazmak ve Kapsam Uygulamak . . . . . . . . . . . . . . . . . 49
Yöntemleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Yöntem Bildirme Sözdizimini Belirlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 return İfadeleri Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Yöntemleri Çağırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Yöntemin Çağrılma Sözdizimini Belirlemek . . . . . . . . . . . . . . . . . . . . . . . . . 53 Kapsam Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Yerel Kapsamı Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Sınıf Kapsamını Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Yöntemleri Aşırı Yüklemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Yöntemler Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Bölüm 3 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

4

Karar İfadeleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Boolean Değişkenleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Boolean İşleçlerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Eşitlik ve İlişkisel İşleçleri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Koşullu Mantıksal İşleçleri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 İşleç Önceliği ve Birleşim Özelliğini Özetlemek . . . . . . . . . . . . . . . . . . . . . 70 Karar Vermek için if İfadelerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 if İfadesinin Sözdizimini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 İfadeleri Gruplamak için Bloklar Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . 73 if İfadelerini Basamaklamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 switch İfadeleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 switch İfadelerinin Sözdizimini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 switch İfadesi Kurallarını İzlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Bölüm 4 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

5

Bileşik Atama ve Yineleme İfadeleri Kullanmak . . . . . . . . . . . . . 85
Bileşik Atama İşleçleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 while İfadeleri Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 for İfadeleri Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 for İfadesinin Kapsamını Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

İçindekiler

vii

do İfadeleri Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Bölüm 5 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

6

Hatalar ve Özel Durumları Yönetmek . . . . . . . . . . . . . . . . . . . . . 103
Hatalarla Başa Çıkmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Kodu Denemek ve Özel Durumları Yakalamak . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Bir Özel Durumu İşlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Birden Çok catch İşleyici Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Birden Çok Özel Durumu Yakalamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Denetimli ve Denetimsiz Tamsayı Aritmetiği Kullanmak . . . . . . . . . . . . . . . . . . 111 Denetlenmiş İfadeler Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Denetlenmiş Deyimler Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Özel Durumlar Oluşturmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Bir finally Bloğu Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 Bölüm 6 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

Kısım II C#

Dilini Anlamak
Sınıflandırmayı Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Kapsüllemenin Amacı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Bir Sınıfı Tanımlamak ve Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Erişilebilirliği Denetlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Kurucularla Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Kurucuları Aşırı Yüklemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 static Yöntemleri ve Verileri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Paylaşılan Bir Alan Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 const Anahtar Sözcüğünü Kullanarak bir static Alan Yaratmak . . . . . . 137 Bölüm 7 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

7

Sınıflar ve Nesneleri Yaratmak ve Yönetmek . . . . . . . . . . . . . . . 123

8

Değerleri ve Başvuruları Anlamak . . . . . . . . . . . . . . . . . . . . . . . . 145
Veri Türü Değişkenleri ve Sınıfları Kopyalamak . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Null Değerleri ve Null Türlerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Boş Olabilen Türleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Boş Olabilen Türlerin Özelliklerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . 152 ref ve out Parametrelerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 ref Parametreleri Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 out Parametreleri Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

viii

İçindekiler

Bilgisayar Belleği Nasıl Düzenlenir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Yığın ve Öbek Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 System.Object Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Kutulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Kutulamayı Kaldırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Verileri Güvenli Olarak Dönüştürmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 is İşleci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 as İşleci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Bölüm 8 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

9

Numaralandırma ve Yapılar ile Değer Türleri Yaratmak . . . . . . 167
Numaralandırmalarla Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Bir Numaralandırma Türü Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Numaralandırma Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Numaralandırma Kalıp Değerlerini Seçmek . . . . . . . . . . . . . . . . . . . . . . . 169 Bir Numaralandırmanın Arka Plandaki Türünü Belirlemek . . . . . . . . . . . 170 Yapılarla Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Bir Yapı Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Yapı ve Sınıf Farklarını Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Yapı Değişkenleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Yapı Başlatmayı Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Yapı Değişkenlerini Kopyalamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Bölüm 9 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

10

Dizileri ve Koleksiyonları Kullanmak . . . . . . . . . . . . . . . . . . . . . . 185
Dizi Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Dizi Değişkenleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Bir Dizi Oluşumu Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Dizi Değişkenlerini Başlatmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Örtülü Yazılmış Dizi Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Dizi Öğelerine Tek Tek Erişmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Bir Dizi Boyunca Yineleme Yapmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Dizileri Kopyalamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Koleksiyon Sınıfları Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 ArrayList Koleksiyon Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Queue Koleksiyon Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Stack Koleksiyon Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 Hashtable Koleksiyon Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 SortedList Koleksiyon Sınıfı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

İçindekiler

ix

Koleksiyon Başlatıcılarını Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Dizileri ve Koleksiyonları Karşılaştırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Kart Oyunu Oynamak İçin Koleksiyon Sınıflarını Kullanmak . . . . . . . . . 201 Bölüm 10 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

11

Parametre Dizilerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Dizi Bağımsız Değişkenlerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 Bir params Dizisi Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 params object[ ] Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Bir params Dizisi Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Bölüm 11 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

12

Kalıtım ile Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Kalıtım Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Kalıtımı Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Temel Sınıflar ve Türetilmiş Sınıflar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Temel Sınıf Kurucularını Çağırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Sınıflar Atamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 new Yöntemleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 Virtual (Sanal) Yöntemler Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 override Yöntemler Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 protected Erişimi Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 Uzantı Yöntemlerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Bölüm 12 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

13

Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak . . . . . . . . . 239
Arabirimleri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Arabirim Sözdizimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Arabirim Kısıtlamaları . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Bir Arabirim Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 Bir Sınıfa Arabirimi Üzerinden Başvurmak . . . . . . . . . . . . . . . . . . . . . . . . . 243 Çoklu Arabirimlerle Çalışmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 Soyut Sınıflar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 Soyut Yöntemler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Mühürlenmiş Sınıflar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Mühürlenmiş Yöntemler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Genişletilebilir Çerçeve Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Anahtar Sözcük Bileşimlerini Özetlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Bölüm 13 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

x

İçindekiler

14

Çöp Toplama ve Kaynak Yönetimini Kullanmak . . . . . . . . . . . . 257
Bir Nesnenin Ömrü ve Ömür Uzunluğu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Yıkıcılar Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Neden Çöp Toplayıcı Kullanılır? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Çöp Toplayıcı Nasıl Çalışır? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Öneriler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Kaynak Yönetimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Yok Etme Yöntemleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 Özel Durum-Güvenli Yok Etme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 using İfadesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 Bir Yıkıcıdan Dispose Yöntemini Çağırmak . . . . . . . . . . . . . . . . . . . . . . . . 266 Kodu Özel Durum-Güvenli Yapmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Bölüm 14 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270

Kısım III Bileşenler

Yaratmak

15

Alanlara Erişmek İçin Özellikler Uygulamak . . . . . . . . . . . . . . . . 275
Yöntemleri Kullanarak Kapsülleme Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . 276 Özellikler Nelerdir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Özellikleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Salt Okunur Özellikler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Salt Yazılır Özellikler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Özellik Erişebilirliği . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Özellik Kısıtlamalarını Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Arabirim Özelliklerini Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Özellikleri Bir Windows Uygulamasında Kullanmak . . . . . . . . . . . . . . . . . 285 Otomatik Özellikler Üretmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Özellikleri Kullanarak Nesneleri Başlatmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 Bölüm 15 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

16

Dizinleyicileri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Dizinleyici Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Dizinleyici Kullanmayan Bir Örnek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 Aynı Örneğin Dizinleyici Kullanan Biçimi . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Dizinleyici Erişimcilerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Dizinleyicilerle Dizileri Karşılaştırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 Arabirimdeki Dizinleyiciler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Dizinleyicileri Bir Windows Uygulamasında Kullanmak . . . . . . . . . . . . . . . . . . . 303 Bölüm 16 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308

İçindekiler

xi

17

Program Akışını Kesmek ve Olayları İşlemek . . . . . . . . . . . . . . . 311
Temsilciler Bildirmek ve Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 Otomasyonlu Fabrika Senaryosu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Temsilci Kullanmadan Fabrika Senaryosunu Uygulamak . . . . . . . . . . . . 312 Temsilci Kullanarak Fabrika Senaryosunu Uygulamak . . . . . . . . . . . . . . . 313 Temsilciler Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Lambda Deyimler ve Temsilciler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Bir Yöntem Bağdaştırıcısı Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Lambda Deyimini Bağdaştırıcı Olarak Kullanmak . . . . . . . . . . . . . . . . . . . 320 Lambda Deyimlerinin Biçimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Bildirimleri Olaylarla Etkinleştirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Bir Olay Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 Bir Olaya Abone Olmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 Bir Olay Aboneliğini İptal Etmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 Bir Olayı Çağırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 WPF Kullanıcı Arabirimi Olaylarını Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 Olayları Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 Bölüm 17 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329

18

Generics’e Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Nesnelerle İlgili Sorunlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 Generics Çözümü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 Generics ve Genelleştirilmiş Sınıflar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Generics ve Sınırlamaları . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Bir Generic Sınıf Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 İkili Ağaçlar Kuramı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Generics Kullanarak İkili Ağaç Sınıfı Oluşturmak . . . . . . . . . . . . . . . . . . . 341 Bir Generic Yöntem Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 İkili Ağaç Oluşturmak İçin Bir Generic Yöntem Tanımlamak . . . . . . . . . . 351 Bölüm 18 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354

19

Koleksiyonları Numaralandırmak . . . . . . . . . . . . . . . . . . . . . . . . 355
Koleksiyondaki Öğeleri Numaralandırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Bir Numaralandırıcıyı Elle Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 IEnumerable Arabirimini Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Bir Yineleyici Kullanarak Numaralandırıcı Uygulamak . . . . . . . . . . . . . . . . . . . . 363 Basit Bir Yineleyici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Bir Yineleyici Kullanarak Tree<TItem> Sınıfı İçin Bir Numaralandırıcı Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Bölüm 19 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368

xii

İçindekiler

20

Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak . . 371
Tümleşik Sorgu Dili (LINQ) Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 Bir C# Uygulamasında LINQ Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 Veriyi Seçmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 Veriyi Filtrelemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 Veriyi Sıralamak, Gruplamak ve Toplamak . . . . . . . . . . . . . . . . . . . . . . . . . 377 Verileri Birleştirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 Sorgu İşleçlerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 Tree<TItem> Nesnelerinde Veri Sorgulamak . . . . . . . . . . . . . . . . . . . . . . 383 LINQ ve Ertelenmiş Değerlendirme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 Bölüm 20 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392

21

İşleç Aşırı Yüklemesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
İşleçleri Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 İşleç Kısıtlamaları . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 Aşırı Yüklenmiş İşleçler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 Simetrik İşleçler Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 Bileşik Atamayı Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 Artırma ve Azaltma İşleçleri Bildirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 İşleç Çiftleri Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 Bir İşleç Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Dönüştürme İşleçlerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 Yerleşik Dönüştürmeler Sağlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 Kullanıcı Tanımlı Dönüştürme İşleçleri Uygulamak . . . . . . . . . . . . . . . . . 407 Simetrik İşleçler Yaratmak (Yeniden) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Bir Kapalı Dönüştürme İşleci Eklemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 Bölüm 21 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411

Kısım IV Windows

Uygulamaları ile Çalışmak

22

Windows Presentation Foundation’a Giriş . . . . . . . . . . . . . . . . . 415
Bir WPF Uygulaması Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415 Bir Windows Presentation Foundation Uygulaması Yaratmak . . . . . . . . 416 Forma Denetimler Eklemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 WPF Denetimlerini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 Özellikleri Dinamik Olarak Değiştirmek . . . . . . . . . . . . . . . . . . . . . . . . . . 439 Bir WPF Formda Olayları İşlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Windows Forms’da Olayları İşlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Bölüm 22 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

İçindekiler

xiii

23

Menüler ve İletişim Kutularıyla Çalışmak . . . . . . . . . . . . . . . . . . 451
Menü Temel İlkeleri ve Stil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 Menüler ve Menü Olayları . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Bir Menü Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Menü Olaylarını İşlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 Kısayol Menüleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 Kısayol Menüleri Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 Windows Ortak İletişim Kutuları . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 SaveFileDialog Sınıfını Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 Bölüm 23 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

24

Doğrulamayı Gerçekleştirmek . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
Verileri Doğrulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 Kullanıcı Girişini Doğrulamak İçin Stratejiler . . . . . . . . . . . . . . . . . . . . . . . 473 Bir Örnek: Müşteri Yönetimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 Veri Bağlamayı Kullanarak Doğrulamayı Gerçekleştirmek . . . . . . . . . . . 475 Doğrulamanın Gerçekleştiği Noktayı Değiştirmek . . . . . . . . . . . . . . . . . 491 Bölüm 24 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495

Kısım V Veriyi

Yönetmek

25

Bir Veritabanında Bilgi Sorgulamak . . . . . . . . . . . . . . . . . . . . . . 499
ADO.NET Kullanarak Veritabanı Sorgulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 Northwind Veritabanı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500 Veritabanı Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500 Sipariş Bilgisini Sorgulamak İçin ADO.NET Kullanmak . . . . . . . . . . . . . . . 503 DLINQ Kullanarak Veritabanını Sorgulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 Bir Varlık Sınıfı Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 Bir DLINQ Sorgusu Yaratmak ve Çalıştırmak . . . . . . . . . . . . . . . . . . . . . . . 514 Ertelenmiş ve Anında Veri Almak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 Tabloları Birleştirmek ve İlişki Oluşturmak . . . . . . . . . . . . . . . . . . . . . . . . 517 Ertelenmiş ve Anında Veri Almak (Tekrar) . . . . . . . . . . . . . . . . . . . . . . . . . 521 Özel DataContext Sınıfı Tanımlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 Sipariş Bilgisini Sorgulamak İçin DLINQ Kullanmak . . . . . . . . . . . . . . . . 523 Bölüm 25 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527

. . . . . . . . . . . . . . . .xiv İçindekiler 26 Veri Bağlamayı Kullanarak Veriyi Görüntülemek ve Düzenlemek . . . 544 Güncelleme Çakışmalarının Üstesinden Gelmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 Bir ASP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561 ASP. . . . . . . . . . . . . . 588 İstemci Doğrulaması Uygulamak . . . . . . . .NET ile Web Uygulamaları Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . .NET’i Anlamak . 575 Bir Tema Yaratmak ve Kullanmak . . . . . . . . . . . . . . 598 Veriyi Görüntülemek ve Sorgulamak . . . . 545 Veri Eklemek ve Silmek . . . . . . . . . . . . . . . . 586 28 Web Formları Doğrulama Denetimlerini Anlamak . . . 587 Veriyi Web Sunucusunda Doğrulamak . . . . . . . . . . . . . . . . . . . . 598 Form Tabanlı Güvenliği Uygulamak . 560 Web Sunucu İsteklerini ve Yanıtlarını Anlamak . . . . . . . . . . . . . . . . . . . . . . . 589 Bölüm 28 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 Güvenliği Yönetmek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .NET Uygulaması Oluşturmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582 Bölüm 27 Hızlı Başvuru . . . . . . . . . . . . .NET’e Giriş . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564 Sunucu Denetimlerini Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 Mevcut Veriyi Güncellemek . . . 560 Durumu Yönetmek . . . . . . . . . . . . . . . . . 556 Kısım VI Web Uygulamaları Oluşturmak 27 ASP . . . 606 Veriyi Sayfalarda Görüntülemek . 611 . . . . . . . . . . . . . . . . . 559 Bir Altyapı Olarak İnternet’i Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 Sunucu ve İstemci Doğrulamalarını Karşılaştırmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 Web Formları GridView Denetimini Anlamak . . . . . . . . . . . . . . . . . . 561 ASP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 Veri Güncellemek İçin DLINQ Kullanmak . . . . . . . 548 Bölüm 26 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588 Veriyi Web Tarayıcısında Doğrulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 DLINQ ile Veri Bağlamayı Kullanmak . . . . . . . . . . . . . . . . . . . . . 605 Müşteri ve Sipariş Bilgisini Görüntülemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 Form Tabanlı Güvenliği Anlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 29 Bir Web Sitesinin Güvenliğini Sağlamak ve Web Formlarıyla Verilere Erişmek . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 Web Servisi Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627 Bir Web Servisi Oluşturmak . . . . . . . . . . . 624 Web Servisi Tanımlama Dili Nedir? . . . . . . . . . . . . . . . . 637 SOAP Konuşmak: Kolay Yol . . . . . . 637 ProductService Web Servisini Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612 Formlar Arasında Gezinmek . . . . . . . . İstemciler ve Proxy’ler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612 Bir GridView Denetimi Üzerinden Satırları Güncellemek . . . .İçindekiler xv Veriyi Düzenlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 614 Bölüm 29 Hızlı Başvuru . . . . . . . 623 SOAP Rolü . 638 Bölüm 30 Hızlı Başvuru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 Windows Communication Foundation’ın Rolü . . . . . . 645 . . . . . . . . . . . . . . . . . 627 ProductService Web Servisini Yaratmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 Web Servislerinin İşlevsel Olmayan Gereksinimleri . . . . . .644 Dizin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 SOAP Konuşmak: Zor Yol . . . . . . . . . . . . . 628 Web Servisleri. . . . . . . . . 621 30 Bir Web Servisi Yaratmak ve Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.

hayatımı çalışmak yerine bilgisayar oyunları ile harcadığım konusunda ısrar ediyor. . Ve Ginger. yani “Zaman değişiyor ve biz de zamanla birlikte değişiyoruz. Francesca. Bu kitabı yazma amacım. çalışma odamdaki sandalyemin rakibi. “Neden bahsettiğin hakkında en ufak bir fikrim yok fakat buna bir son vereceğini umuyorum” diyen bir tavır geliştirdi. Diana artık “DLINQ” ve “lambda deyimi” gibi terimleri biliyor ve kolayca cümle içinde kullanabiliyor. Çalışmamı gözden geçiren. kitap yazmak bir grup çalışmasıdır. Windows. beni tümüyle sandalyeden uzaklaştırmak için bir kedinin yapabileceğinin en iyisini yapmaya çalıştı. Şikayet etmiyorum. çünkü uygulamalar ve hizmetler oluşturmak için .” der. C# dili . nos et mutantur in illis. Gelişmelerini izlemek ve her yeni sürümü çıktığında yeni özellikler öğrenmek her zaman hoşuma gitti. Bu kitabın birkaç baskısı boyunca bana güvenini yitirmeyen Lynn Finnel’i. özellikle .NET Framework ve C#’ı duymadan önce. “DLINQ ve lambda deyimleri hakkında konuşmaktan hiç vazgeçmeyecek misin?) James hala. (Örneğin.Teşekkürler Eski bir Latin atasözü “Tempora mutantur. yoksa “Zaman değişiyor ve biz de onu yakalamak için deli gibi koşuyoruz!” derlerdi.NET Framework ve C# dilindeki gelişmeler kesinlikle çok şaşırtıcı. Son yedi-sekiz yıla dönüp baktığımda.NET Framework mükemmel bir ortam. Ayrıca. bu atasözünü söylemiş olmalılar. Benim sabırlı ailem her zaman olduğu gibi harikaydı. Microsoft’un geliştirilmesinde çok büyük çaba harcayan. bu kitap üzerinde iki yılda bir güncelleme yaparak kazançlı çıkmamı sağladıkları için de teşekkür ederim. hatalarımı düzelterek değişiklikler öneren Kurt Meyer’a verdiği çabadan dolayı özellikle teşekkür ederim ve elbette bu kitabın 2001’deki ilk basımının yazılmasına yardımcı olan Jon Jagger’a teşekkürler.” Romalılar Microsoft.NET Framework’ün tüm avantajlarından yararlanmak için en büyük araçtır. Microsoft Press’teki ekibim ile çalışmak en iyilerinden biriydi. çeşitli ürün gruplarındaki ileri görüşlü kişilere teşekkürler. Bana göre. el yazısı ile yazılmış müsveddeler üzerinde düzenlemeler yapan Christina Palaia ve Jennifer Harris’i hepimizi bir sırada ve bir programda tutan bir Truvalı gibi çalışan Stephen Sagman’i özellikle belirtmek isterim. “Panjurları Kaldırın!” —John Sharp xvii . Bu tür projelerin tümünde olduğu gibi. Her zamanki gibi. C#’ı keşfetmeye yeni başlayan diğer programcılara kendi heyecanımı yansıtmaktı.

.

Sizin İçin En İyi Başlangıç Noktasını Bulmak Bu kitap. bu güçlü özelliklerin kullanımını kolaylaştırır ve Visual Studio 2008’in içerdiği birçok yeni sihirbaz ve iyileştirmeler.NET Web uygulamaları geliştirmiş ve bir Windows Communication Foundation hizmeti oluşturup kullanmış olacaksınız. C# dilinin özelliklerini öğrenecek ve Microsoft Windows işletim sistemi üzerinde çalışan uygulamalar oluşturmak için bu özellikleri kullanacaksınız. lambda deyimleri ve hepsinden önemlisi. Programlamaya yeniyseniz ya da C. ASP. Sun Microsystems Java ya da Visual Basic gibi başka bir programlama dilinden geçiş yapıyorsanız bu kitabı kullanabilirsiniz. Sizin için en iyi başlangıç noktasını bulmak için aşağıdaki tabloyu kullanın. yineleyiciler ve adsız yöntemleri içeren birkaç yeni özellik eklenmiştir. Kitabı tamamladığınızda. Language Integrated Query özelliği ya da LINQ gibi daha fazla özellik ekler.NET Framework’ün 3. ancak tutarsızlıklar ve zaman hataları kaldırılmış. Bu Kitap Kim İçin? Bu kitabın amacı. 2005 yılında C# 2. birçok temel alanda yeteneklerinizi geliştirmenize yardımcı olmak için tasarlandı. Microsoft Visual Studio 2008’in bir parçası olan C# 3.0 ise uzantı yöntemleri. sonuçta ortaya daha temiz ve mantıklı bir dil çıkmıştır.5 sürümünü kullanarak C# ile programlama temellerini öğretmektir. C++ ve Microsoft Visual Basic’in en iyi özelliklerinin birçoğunu almıştır. Visual Studio 2008 tarafından sağlanan geliştirme ortamı.NET Framework kullanarak uygulamalar yaratan yazılım geliştiricileri hedefleyen güçlü fakat basit bir dildir. C++. C# dilini kusursuzca anlamış ve onu kullanarak Windows Presentation Foundation (WPF) uygulamaları oluşturmuş. Microsoft SQL Server veritabanlarına erişmiş.Giriş Microsoft Visual C#. Visual Studio 2008 ve . yazılım geliştirici olarak üretkenliğinizi önemli ölçüde artırır.0’ın ortaya çıkmasıyla dile. öncelikle Microsoft . xix .

Alıştırmalar üzerinde çalıştıktan sonra kitaba başvuruyorsanız 1. fakat C# konusunda yeniyseniz. uygulama dosyalarını kurun. Veritabanına erişim hakkında bilgi için. Kısım IV ve V’i okuyun. 1. Sırasıyla Kısım I. 1. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. uygulama dosyalarını kurun. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. 2. Kısım V’i okuyun. 3. Web uygulamaları ve Web hizmetleri hakkında bilgi edinmek için Kısım VI’yı okuyun. 3. 4. Belirli konular hakkında bilgiye ulaşmak için kitap dizini ya da içindekiler bölümünü kullanın. Windows-tabanlı uygulamalar oluşturmak hakkında daha fazla bilgi için. II ve III’deki bölümleri çalışın. uygulama dosyalarını kurun. V ve VI’yı tamamlayın. 2. Kısım IV. Kısım IV’ü okuyun. 2. Windows uygulamaları oluşturmak ve veritabanı kullanmak hakkında bilgi edinmek için.xx Eğer Giriş Şu adımları izleyin . Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde tanımlandığı gibi. C# ve Visual Studio 2008 hakkında genel bir bilgi elde etmek için ilk beş bölümü gözden geçirin ve sonra Bölüm 6-21 arasına yoğunlaşın. Visual Basic 6’dan geçiş yapıyorsanız 1. 2. Bölümde sunulan söz dizimi ve tekniklerin özetine ulaşmak için her bir bölümün sonundaki Hızlı Başvuru kısmını okuyun. Deneyiminiz ve ilginizin belirlediği kadar. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. 3. Sırasıyla Kısım I. 2. V ve VI’yı deneyiminiz ve ilginizin belirlediği ölçüde tamamlayın. C++ ya da Java gibi nesneyönelimli bir programlama dilinden geçiş yapıyorsanız 1. Kısım IV. II ve III’deki bölümleri çalışın. Web uygulamaları ve Web hizmetleri hakkında bilgi edinmek için Kısım VI’yı okuyun. Özel C# ve Visual Studio 2008 yapıları hakkında bilgi için bölümlerin sonundaki Hızlı Başvuru kısımlarını okuyun. Nesne-yönelimli programlama konusunda yeniyseniz C gibi yordamsal programlama dillerine aşina iseniz. 5. . uygulama dosyalarını kurun. C# ve Visual Studio 2008 hakkında genel bir bilgi elde etmek için ilk yedi bölümü gözden geçirin ve Bölüm 8-21 arasına yoğunlaşın. 6. 4.

Her bölüm Hızlı Başvuru kısmı ile sonlanır. Örneğin. Alt tuşunu basılı tutarken Tab tuşuna da basmanızı bildirir. Her görev. bu tuşlara aynı anda basmanız gerektiği anlamına gelir. İki tuş adı arasındaki artı işareti (+). “önemli” başlıklı notlar. alıştırmanın tek adımdan oluştuğunu belirtir. 2. Kenar çubukları arka plan bilgisi. vb. Windows Vista Business Edition ya da Windows Vista Ultimate Edition. Başlamadan önce. “ipucu” başlıklı notlar.) olarak gösterilmiştir. devam etmeden önce kontrol etmeniz gereken bilgi hakkında sizi uyarır. Yuvarlak madde imi (•). kolay okunur ve izlenebilir olması için bilgileri bazı standartlar kullanarak sunar. bir basamağı başarılı bir şekilde tamamlamak için ek bilgi ya da alternatif yöntemler sağlar.Giriş xxi Kitaptaki Standartlar ve Özellikler Bu kitap. . Sizin yazacağınız metin kalın olarak yazılmıştır. bir dizi görevdir. Standartlar n Her alıştırma. Hızlı Başvuru kısmı. tasarım ipuçları ya da tartışılan konu ile ilgili özellikler içerebilir. kitap boyunca göreceğiniz standartları açıklayan ve kullanmak isteyebileceğiniz yardımcı özellikleri vurgulayan aşağıdaki listeyi okuyun. bölümde öğrendiğiniz görevleri nasıl gerçekleştireceğinize dair kısa hatırlatmalar içerir. numaralandırılmış basamaklar dizisi (1. n Sistem Gereksinimleri Bu kitaptaki uygulama alıştırmalarını tamamlamak için aşağıdaki donanım ve yazılıma gereksiniminiz olacaktır: n Windows Vista Home Premium Edition. n n n n Diğer Özellikler n Kenar çubukları kitap boyunca alıştırmalar hakkında daha ayrıntılı bilgi sağlar. “Alt+Tab tuşuna basın” ifadesi. Alıştırmalar ayrıca Service Pack 2 yüklü Microsoft Windows XP Professional Edition ile de çalışır.

Kod Örneklerini Kurmak Kod örneklerini ve gerekli yazılımı bilgisayarınıza kurmak için aşağıdaki işlem basamaklarını izleyin. Böylece alıştırmalarda kod örneklerini kullanabilirsiniz. Eğer açılmazsa. Not Son kullanıcı lisans anlaşması.xxii Giriş Önemli Windows XP kullanıyorsanız. alıştırma ile ilgili olmayan dosyaları yaratmak için zaman harcamayacaksınız. CD-ROM sürücünüze takın. Bunun nedeni. Kod Örnekleri Bu kitap ile birlikte verilen CD.6-GHz Pentium III+ işlemci ya da üzeri 1 GB kullanılabilir fiziksel RAM Video monitör (800 × 600 ya da daha yüksek çözünürlük) en az 256 renk CD-ROM ya da DVD-ROM sürücü Microsoft fare ya da uygun işaretleme aracı n n n n n n Ayrıca. 1. n Microsoft Visual Studio 2008 Standard Edition. yeni bilgileri kavramak ve hatırlamanın kolay ve etkili bir yoludur. önce CD-ROM sürücünüzün simgesini ve daha sonra StartCD. Kitabın arka kapağının iç yüzünde bulunan CD’yi paketinden çıkararak. alıştırmaları yaparken kullanacağınız kod örneklerini içerir. bu kitapta tanımlanan bazı iletişim kutuları ve ekran görüntüleri.exe’yi çift tıklayın. . Windows Vista işletim sisteminin kullanıcı arayüzündeki ve Windows Vista’nın güvenlik yönetimindeki farklılıklardır. Kod örneklerini kullanarak. Bu. biraz farklı görünebilir. masaüstündeki Bilgisayarım klasörünü ya da Başlat menüsünü açın. otomatik olarak açılmalıdır. SQL Server 2005 Express Edition’ı yapılandırmak ve alıştırmaları gerçekleştirmek için bilgisayarınıza Administrator (Yönetici) erişimine sahip olmanız gerekmektedir. Dosyalar ve derslerdeki adım-adım komutlar. Visual Studio 2008 Enterprise Edition ya da Microsoft Visual C# 2008 Express Edition ve Microsoft Visual Web Developer 2008 Express Edition Service Pack 2 yüklü Microsoft SQL Server 2005 Express Edition 1. ayrıca uygulayarak öğrenmenizi sağlayacak.

Kod örneği kullanılacağı zaman. Metne dayalı selamlama görüntüleyen basit bir program yaratma basamakları gösterilmiştir. Bu proje başlangıç yapmanızı sağlar.Giriş xxiii 2. Tanım MathsOperators . Önemli Kod örnekleri. Windows Presentation Foundation kullanarak. 4. Yönetici haklarına sahip bir hesap kullanarak yapmanız önerilir. Koşulları kabul ediyorsanız. Tüm ayrıntıları bilmek isteyenler için. Bu program. bu değişkenlere nasıl değer atanacağını ve değişken değerlerinin bir pencerede nasıl görüntüleneceğini gösterir. kitap. Alıştırmaları. Uygulama Dosyalarını Yükleyin’i tıklayın. selamlamayı bir pencerede görüntüler. Ekranda görünen yönergeleri izleyin. kabul ediyorum seçeneğini seçin ve daha sonra İleri’yi tıklayın. Son kullanıcı lisans anlaşmasını okuyun. her bir temel tipi kullanarak nasıl değişken tanımlanacağını. Bu proje. Kod örnekleri bilgisayarınızda aşağıdaki konuma kurulur: Belgeler\Microsoft Press\Visual CSharp Step By Step Kod Örneklerini Kullanmak Kitaptaki her bölüm. Visual Studio 2008 projeleri ve çözümleri kod örneklerinin. o bölüm için kod örneklerini ne zaman ve nasıl kullanacağınızı açıklar. yerel Yöneticiler grubunun üyesi bir hesap kullanılarak test edilmiştir. bulundukları klasörlere göre gruplandırılmış listesi aşağıdadır. Proje Bölüm 1 TextHello WPFHello Bölüm 2 PrimitiveDataTypes Bu proje. aritmetik operatörleri (+ – * / %) tanıtır. dosyaları nasıl açacağınıza dair yönergeleri listeler. 3. Kitap ile ilgili özelliklerle birlikte bir menü görünür.

Ayrıca. değer parametreleri ve başvuru parametreleri arasındaki farklılığı araştırır. takvim tarihini göstermek için struct tipi tanımlar. karakterleri XML gösterimlerine çevirmek için switch deyimini kullanır. kendi sınıflarınızı tanımlamak. ondalık sayıyı. yöntemleri çalıştırmak ve Visual Studio 2008 hata ayıklayıcı kullanarak yöntem çağırmayı basamaklandırmak konularını ele alır. Bölüm 7 Classes Bu proje. Bölüm 4 Selection Bu proje. ortak kurucular. Bu proje. try ve catch anahtar sözcükleri uygulamayı daha güçlü yapar. yöntemler ve özel alanlar ile sınıflarınızı tamamlamanın temellerini ele alır. Bölüm 2. . Daha sonra. ref ve out anahtar sözcüklerinin nasıl kullanılacağını gösterir. Bu basit program. Bölüm 9 StructsAndEnums Bu proje. Bu proje. new anahtar sözcüğünü kullanarak class örneklerini nasıl yaratacağınızı ve statik yöntemleri ve alanları nasıl tanımlayacağınızı gösterir. önceki projedeki kodu yeniden inceleyecek ve kodun yöntemlerle nasıl yapılandırıldığını araştıracaksınız. Operatörler ve İfadelerle Çalışmak” bölümündeki MathsOperators projesini yeniden inceler ve programın başarısız olması için çeşitli işlenmemiş özel durumlar oluşturur.xxiv Giriş Proje Bölüm 3 Methods DailyRate Tanım Bu projede. DoStatement Bölüm 6 MathsOperators Bu proje. böylece program artık başarız olmaz. iki tarihin karşılaştırılması gibi karmaşık bir mantığı uygulamak için iç içe geçmiş bir if deyimini nasıl kullanacağınızı gösterir. “Değişkenler. her satırı form üzerindeki metin kutusunda görüntülemek için while deyimini kullanır. kendi yöntemlerinizi yazmak. SwitchStatement Bölüm 5 WhileStatement Bu proje. Bölüm 8 Parameters Bu program. bir kaynak dosya içeriğini her defasında bir satır okuyarak. sekizlik gösterimine dönüştürmek için do deyimini kullanır.

Bölüm 13 Tokenizer Bu proje. olaylar kullanarak kod basitleştirilmiştir. sembolleri zengin metin kutusunda renkli sözdiziminde göstermek için anahtar arabirimlerden sınıfları türetir.Giriş xxv Proje Bölüm 10 Cards Bölüm 11 ParamsArrays Tanım Bu proje. Bölüm 12 Vehicles ExtensionMethod Bu proje. ana penceresinin boyutunu görüntülemek için birkaç özellik kullanan basit Windows uygulaması sunar. C# kaynak dosyasını okumak ve dosya içeriğini çeşitli türde jetonlara (tanımlayıcılar. Bölüm 17 Delegates Bu proje. Bu proje. Kullanıcı. Bu proje. Bölüm 15 WindowProperties Bu proje. operatörler vb. devralmayı kullanarak basit bir taşıt hiyerarşisi yaratır. Daha sonra. eldeki oyun kartlarını gruplandırmak için ArrayList koleksiyon sınıfını kullanır. bir tamsayı değerini 10’luk tabandan farklı bir tabana çeviren yöntem sağlayan. ayrıca. int tipi için bir dahili yöntemin nasıl yaratılacağını gösterir. Bölüm 14 UsingStatement Bu proje. temsilci geri çağrılarını kullanarak dijital biçimde zamanı görüntüler. herhangi bir sayıda int bağımsız değişkenini kabul edebilen tek bir yöntem yaratmak için params anahtar sözcüğünün nasıl kullanılacağını gösterir. Bu proje. sanal yöntemin nasıl tanımlanacağını gösterir. sınıf için otomatik özelliklerin nasıl oluşturulduğunu ve sınıf örneğini başlatmak için bunların nasıl kullanıldığını gösterir. using deyimi ile kodun nasıl özel duruma karşı güvenli yapılacağını gösterir. Kullanım örneği olarak. AutomaticProperties Bölüm 16 Indexers Bu proje iki dizin oluşturucu kullanır: biri adı verilmiş olan kişinin telefon numarasını arar ve diğeri de telefon numarası verilmiş olan kişinin adını arar. anahtar sözcükleri.) sınıflandırmanın benzetimini yapmak için sınıflar ve arabirimlerin hiyerarşisini kullanır. . Bölüm 5. “Bileşik Atama ve Yineleme Deyimlerini Kullanmak“ bölümündeki küçük kod parçasını yeniden gözden geçirir ve özel durum korumalı olmadığını açığa çıkarır. görüntü otomatik olarak güncellenir. Ayrıca. pencereyi yeniden boyutlandırdıkça.

NET kod kullanarak veritabanına nasıl erişileceğini gösterir. Bu proje. herhangi bir tipte parametre alabilen bir tipgüvenli yapı oluşturmak için genelleri nasıl kullanacağınızı gösterir.xxvi Giriş Proje Bölüm 18 BinaryTree BuildTree Bölüm 19 BinaryTree IteratorBinaryTree Bölüm 20 QueryBinaryTree Bölüm 21 Operators Tanım Bu çözüm. Bu proje. Northwind veritabanındaki Orders tablosundan bilgi alır. kullanıcı girişini onaylamak için iş kurallarının nasıl uygulanacağını gösterir. Bu proje. Minute ve Second adı verilen ağaç yapılarını oluşturur. Uygulama. Bölüm 25 ReportOrders Bu proje. Hour. DLINQOrders . Bu çözüm. genel BinaryTree sınıfında enumerator yaratmak için genel IEnumerator<T> arayüzünü nasıl uygulayacağınızı gösterir. Bu proje. “Windows Presentation Foundation’a Giriş” bölümünde yaratılmış olan uygulamanın uzantısıdır. ikili ağaç nesnesinden veri almak için LINQ sorgularının nasıl kullanılacağını gösterir. örnek olarak müşteri bilgisini kullanan bir WPF uygulamasında. genel BinaryTree sınıfında enumerator oluşturmak için bir yineleme kullanır. stillerin nasıl tanımlanacağını ve basit WPF denetimlerinin nasıl kullanılacağını gösteren bir Windows Presentation Foundation uygulamasıdır. ADO. herhangi bir tipte eleman içerebilen bir tipgüvenli yapı oluşturmak için genelleri (generics) nasıl kullanacağınızı gösterir. Bölüm 24 CustomerDetails Bu proje. Kod daha sonra dönüşüm operatörü kullanılarak basitleştirilmiştir. Bölüm 22 BellRingers Bu proje. Bölüm 23 BellRingers Bu proje. Bu çözüm. veritabanına erişmek ve Northwind veritabanındaki Orders tablosundan bilgi almak için DLINQ’nun nasıl kullanılacağını gösterir. kullanıcı-tanımlı operatörler içeren. Kullanıcı arabirimine açılan menüler eklenmiştir. Bölüm 22.

Giriş xxvii Proje Bölüm 26 Suppliers Tanım Bu proje. Şu Anda Yüklü Programlar (Currently Installed Programs) listesinden.NET Web sitesi oluşturur. 1.NET formunun nasıl kullanılacağını gösterir. Bölüm 27 Litware Bu proje. 2. WPF formu üzerindeki kontrollerde. kullanıcının hayali yazılım geliştirme şirketi için çalışan elemanlar hakkında bilgi girmesini sağlayan basit bir Microsoft ASP. Windows Communication Foundation Web servis uygulamasıdır. ASP. Bölüm 30 NorthwindServices Bu proje. Products tablosundaki veriye Internet üzerinden uzaktan erişimi sağlayan.NET Web uygulamasında kullanıcı girişinin nasıl onaylandığını gösterir. Northwind veritabanında. kullanıcının doğrulanması için Form tabanlı güvenliğin nasıl kullanılacağını gösterir. Kaldır’ı (Remove) tıklayın. bir önceki bölümdeki Litware projesinin genişletilmiş sürümüdür ve ASP. Bölüm 28 Litware Bu proje. veritabanından çekilen veriyi görüntülemek ve biçimlendirmek için WPF uygulaması ile veri bağlamasının nasıl kullanılacağını gösterir. Microsoft Visual C# Step by Step’i seçin. 4. Program Ekle/Kaldır’ı (Add or Remove Programs) açın. Bölüm 29 Northwind Bu proje. . ölçeklenebilir anlamda veritabanının nasıl sorgulanacağını ve güncelleneceğini ve birden fazla Web formlarına yayılan uygulamaların nasıl yaratılacağını gösteren. Kod örneklerini kaldırmak için yönergeleri izleyin. 3. Uygulama ayrıca. Denetim Masası (Control Panel) .NET Web formundan ADO. Kod Örneklerini Kaldırmak Bilgisayarınızdan kod örneklerini kaldırmak için aşağıdaki adımları izleyin.

kitaplar ve kitap ekinde verilen CD’ler için aşağıdaki Web sitesinde kullanıcı desteği sağlar: http://www. Sokak No: 4 Yenimahalle/Ankara www. Microsoft Press.arkadas. Düzeltmeler ya da değişiklikler toplandıkça.com/learning/support/books/ Sorular ve Yorumlar Kitapla ya da yanında verilen CD ile ilgili soru. Microsoft Knowledge Base makalesine eklenecektir.com. lütfen. yorum ya da fikirleriniz varsa ya da yukarıdaki sitede cevabını bulamadığınız sorularınız varsa. .microsoft. yukarıdaki adreslerden Microsoft yazılım desteği verilmediğini unutmayın.tr Posta adresi: Arkadaş Yayınevi Yuva Mahallesi 3702. E-posta adresi: info@arkadas. e-posta yoluyla ya da posta yoluyla bize iletin.tr Lütfen.com.xxviii Giriş Kitap İçin Destek Bu kitabın ve ekinde verilen CD’nin içeriğinin doğruluğundan emin olmak için her türlü çaba gösterilmiştir.

. . . . . . . . . . . . 3 Bölüm 2 . . . . . . . . . . . . . . . . . . . . Hatalar ve Özel Durumları Yönetmek . . . . . . 29 Bölüm 3 . . . . . . . . . . . . . . . . . . . . . . . 49 Bölüm 4 . . . . . Yöntemler Yazmak ve Kapsam Uygulamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bileşik Atama ve Yineleme İfadeleri Kullanmak . . . . . . . . . . . . . . . . . . . 103 Kısım I 1 . . İşleçler ve Deyimlerle Çalışmak . . . .Adım Adım Microsoft Visual C# 2008 Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bu kısımdaki konular: Bölüm 1 . . . . . . . . . . C#’a Hoşgeldiniz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Değişkenler. . . . . . 85 Bölüm 6 . . . . 67 Bölüm 5 . . . . . . . . . . Karar İfadeleri Kullanmak . . . .

.

C++ ya da Java gibi dilleri biliyorsanız. 3 . Farklı programlama dilleri kullanılarak derlenmiş modülleri tek bir modül gibi birleştiren projeler bile oluşturabilirsiniz. Microsoft. Microsoft’un güçlü bileşen-yönelimli dilidir. grafiksel kullanıcı arayüzünden çok. nasıl kullandığını anlayacaksınız. C#. Yöntemleri nasıl yazacağınızı ve yöntemlere bağımsız değişken göndermeyi göreceksiniz. Nasıl değişken bildirimi yapacağınızı ve değişkenlerdeki değerleri işlemek için toplama işareti (+) ve çıkarma işareti (-) gibi aritmetik operatörleri nasıl kullanacağınızı öğreneceksiniz. özel durumları incelikle ve kolay kullanılır biçimde. Visual Studio 2008 programlama ortamını başlatacak ve konsol uygulamasını nasıl yaratacağınızı öğreneceksiniz.Bölüm 1 C#’a Hoşgeldiniz Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n Microsoft Visual Studio 2008 programlama ortamını kullanmak Bir C# konsol uygulaması yaratmak Ad alanı amacını açıklamak Basit grafiksel C# uygulaması yaratmak Microsoft Visual C#. sadece ayraç ve noktalı virgülleri doğru yere koymanız gerekir. C#’ın hataların üstesinden gelmek için.NET Framework mimarisinde önemli rol oynar ve kimileri C dilinin UNIX ortamında oynadığı rolle karşılaştırma yapar. İlk alıştırmada. Bu konular C#’ın özünü şekillendirir ve bu kuvvetli temelden sonra Kısım II’den KısımVI’ya doğru daha ileri seviye özelliklere doğru ilerleyeceksiniz. C# sözdizimini oldukça aşina bulacaksınız. bu size tam olarak yardımcı olacak kitaptır! Kısım I’de. Ayrıca if gibi seçim deyimlerini ve while gibi yineleme deyimlerini nasıl kullanacağınızı öğreneceksiniz. C# sözdizimini kısa sürede kavrayabilirsiniz. C. C# temellerini öğreneceksiniz. Son olarak. Not Konsol uygulaması. Visual Studio 2008 Ortamını Kullanarak Programlamaya Başlamak Visual Studio 2008. büyük ya da küçük C# projeleri oluşturmanız için gereken tüm işlevselliği içeren zengin araçlara sahip programlama ortamıdır. komut satırı penceresinde çalışan uygulamadır. Diğer dillerde programlamaya alışkınsanız. Umarız.

Kısa bir beklemeden sonra. n Visual C# 2008 Express Edition kullanıyorsanız. Aşağıdaki gibi. IDE ) çeşitli iletişim kutuları ve araçları. Visual Studio 2008 başlar: Not Visual Studio 2008’i ilk defa çalıştırıyorsanız. All Programs menüsünü ve daha sonra da Microsoft Visual Studio 2008 program grubunu seçin. Microsoft Windows görev çubuğu üzerinde. sizin tercih ettiğiniz programlama diline uygun olarak kendini uyarlayabilir. 2. Visual Studio 2008 IDE görünecektir. Start düğmesini tıklayın. Microsoft Visual Studio 2008 program grubunda. seçtiğiniz programlama dili için varsayılan seçimler kümesine sahip olacaktır. . Listeden Visual C# Development Settings’i seçin ve sonra Start Visual Studio düğmesini tıklayın. varsayılan ortam ayarlarınızı seçmeniz için uyarıda bulunan bir iletişim kutusu çıkabilir. Microsoft Windows görev çubuğu üzerinde Start düğmesini tıklayın. Visual Studio 2008’i başlatmak için aşağıdaki işlemleri gerçekleştirin: 1. Microsoft Visual Studio 2008 seçeneğini tıklayın. All Programs’ı işaret edin ve daha sonra Microsoft Visual C# 2008 Express Edition’ı tıklayın. Tümleşik geliştirme ortamındaki (Integrated Development Environment.4 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Visual Studio 2008’de konsol uygulaması yaratmak n Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Visual Studio 2008.

Project types bölmesinde. n Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Visual Studio 2008 Professional Edition ya da Visual C# 2008 Express Edition’ı açmanız gerektiğinde. yeni bir konsol uygulaması yaratmak için aşağıdaki işlemleri gerçekleştirin. Bu iletişim kutusu. 1. File menüsü üzerinde New’i işaret edin ve daha sonra Project seçeneğini tıklayın. Templates bölmesindeki Console Application simgesini tıklayın. basitçe “Visual Studio’yu Başlat” diyeceğiz. 2. Visual C#’ı tıklayın. Visual Studio 2008 Standard Edition. New Project iletişim kutusu açılır. uygulama oluşturmak için başlangıç olarak kullanabileceğiniz şablonları listeler.Bölüm 1 C#’a Hoşgeldiniz 5 Visual C# 2008 Express Edition aşağıdaki gibi açılır: Not Kitap boyunca tekrarlamadan kaçınmak için. İletişim kutusu kullandığınız programlama diline ve uygulama tipine uygun olarak şablonları kategorilere ayırır. .

“C:\Users\Adınız\Belgeler” ya da “C:\Documents and Settings\Adınız\Belgelerim” yolunu. Not Kitabın geri kalan bölümünde yer kazanmak açısından. Create directory for solution onay kutusunun seçili olduğundan emin olun ve daha sonra OK’i tıklayın. Visual Studio 2008 sizin için oluşturacaktır. 3. 2. Name alanına. Console Application simgesini tıklayın. 4. TextHello yazın. Windows Vista işletim sistemi kullanıyorsanız. OK‘i tıklayın. yeni bir konsol uygulaması oluşturmak için aşağıdaki işlemleri yapın. C:\Users\ Adınız\Belgeler\Microsoft Press\Visual CSharp Step By Step\Chapter1 yazın. İpucu Belirttiğiniz klasör bulunmuyorsa. Visual C# 2008 Express Edition kullanıyorsanız. Options seçeneğini tıklayın. Tools menüsünde. Show All Settings kutucuğunu işaretleyin ve daha sonra sol bölmedeki ağaç görünümünde Projects and Solutions’ı tıklayın. n Visual C# 2008 Express Edition kullanıyorsanız. Aşağıdaki işlemleri yaparak bu klasörü değiştirin: 1. 2. New Project iletişim kutusundaki. Options iletişim kutusunda. Name alanına TextHello yazın. Location alanında.6 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 3. C:\Documents and Settings\Adınız\Belgelerim\Microsoft Press\Visual CSharp Step By Step\ Chapter 1 yazın. OK’i tıklayın. sizin Belgeler klasörünüz olarak adlandıracağım. 4. varsayılan olarak C:\Users\Adınız\AppData\Local\Temporary Projects klasörünü kullanır. Windows XP ya da Windows Server 2003 kullanıyorsanız. Belgeler klasörünüzün altındaki Microsoft Press\Visual CSharp Step By Step\Chapter 1 klasörünü belirleyin. 4. File menüsü üzerinde New Project seçeneğini tıklayın. 5. Sağ bölmede. New Project iletişim kutusu proje dosyalarınızın konumunu belirtmenize imkan vermeyecektir. Buradaki Adınız kısmını Windows kullanıcı adınız ile değiştirin. 1. n . 3. Visual Studio projects location metin kutusunda.

Kaynak dosyayı Code and Text Editor penceresinde ön plana getirmek için aynı zamanda.Bölüm 1 C#’a Hoşgeldiniz 7 Visual Studio Console Application şablonunu kullanarak proje oluşturur ve aşağıdaki gibi bir başlangıç kodu görüntüler: Ekranın üst kısmındaki menü çubuğu. Araç çubuğu. Adlandırılmış kaynak dosyasını Code and Text Editor penceresinde ön plana getirmek için sekmeyi tıklayabilirsiniz. bir ya da daha fazla proje dosyasına başvurular içerir.sln olduğunu görürsünüz. . menü çubuğunun altında yer alır ve en sık kullanılan komutları çalıştırmak için düğme kısayolları sağlar. programlama ortamında kullanacağınız özelliklere erişim sağlar. Solution Explorer’ da dosya adını çifttıklayabilirsiniz. Her çözüm dosyası. kaynak dosyaların içeriklerini görüntüler. Solution Explorer proje ile ilgili dosyaların adlarını diğer parçalar arasında görüntüler. her kaynak dosya. Kod yazmadan önce. birden fazla dosya düzenlediğinizde. bu dosyanın gerçek adının TextHello. kaynak dosyanın adıyla kendi sekme etiketine sahiptir. IDE’nin ana kısmını dolduran Code and Text Editor penceresi. Belgeler\Microsoft Press\Visual CSharp Step by Step\Chapter 1\TextHello klasörünüze bakmak için Windows Gezgini’ni kullanırsanız. Tüm Windows-tabanlı programlarda yaptığınız gibi. Çokdosyalı bir projede. uygulama başına bir tane olan üst-seviye çözüm dosyasıdır. menüler ve komutlara erişmek için klavye ya da fareyi kullanabilirsiniz. Visual Studio 2008’in projenizin parçası olarak oluşturduğu Solution Explorer’da listelenen dosyaları inceleyin: n ‘TextHello’ çözümü Bu.

cs dosyası. “Yöntemler Yazmak ve Kapsam Uygulamak” bölümünde yöntemleri daha ayrıntılı gözden geçireceksiniz. bölümde de statik yöntemleri ele aldık. Main yöntemi özeldir (programın giriş noktasını belirtir). bu kitabın kapsamı dışındadır.cs adında bir dosya içerdiğini görürsünüz. Hello World konsol uygulamasını oluşturacak ve çalıştıracaksınız ve kod elemanlarını bölümlemek için ad alanlarının nasıl kullanıldığını öğreneceksiniz. n n n İlk Programınızı Yazmak Program. Ayrıca. Tüm yöntemler. AssemblyInfo. Visual Studio 2008’in otomatik olarak sağladığı. programın yazıldığı tarih ve bu gibi öznitelikler eklemek için kullanabileceğiniz özel bir dosyadır. bu dosya gerçekte TextHello. yazar adı.cs Bu C# kaynak dosyasıdır ve proje ilk oluşturulurken Code and Text Editor penceresinde görüntülenen dosyadır. kısaca inceleyeceğiniz bazı kodlar içerir. böylece kendi uygulamalarında kodu kullanmak isteyebilecek diğer yazılım geliştiricilere kodu dağıtabilirler. Özellikler TextHello projesindeki klasördür. 7. Main yöntemini büyük M harfi ile yazmanız gerekir. Konsol uygulaması için kodunuzu bu dosyada yazacaksınız. küçük-büyük harfa duyarlı bir dil olmasıdır. Bu kitabı kullanarak uygulamalar yazarken kullanacağınız özelliklerin bir çoğu. Statik yöntem olmak zorundadır (Bölüm 3. Başvurular Uygulamanızın kullanabileceği derlenmiş koda başvurular içeren klasördür.cs dosyası programa. yazdıkları kullanışlı kod bitlerini paketlemek için derlemeleri kullanır. Tek bir projedeki tüm kaynak kodlar aynı programlama dilinde yazılmak zorundadır. konsolda Hello Word iletisini görüntülemek için kod yazacaksınız. bölümde sınıfları daha ayrıntılı olarak göreceksiniz.csproj olarak adlandırılır ve \Belgelerim\ Microsoft Press\Visual CSharp Step by Step\Chapter 1\TextHello\TextHello klasörünüzde saklanır. Microsoft tarafından Visual Studio 2008 ile sağlanan derlemelerden yararlanır. AssemblyInfo. Yazılım geliştiriciler. Main adı verilen bir yöntem içeren Program adında bir sınıf tanımlar. derlemeye dönüştürülür ve benzersiz ad verilir. Kod derlendiğinde. “Sınıflar ve Nesneler Oluşturmak ve Yönetmek” başlıklı 7. Bu klasörü genişletirseniz. . Aşağıdaki alıştırmalarda. Programın çalışma yöntemini değiştirmek için ek öznitelikler belirleyebilirsiniz. Bu özniteliklerin nasıl kullanılacağını öğrenmek. Windows Gezgini’nde. sınıf içinde tanımlanmalıdır.) Önemli C#’nin önemi. kaynak kod ve proje için diğer parçaları içeren bir ya da daha fazla dosyaya başvurur. Her proje dosyası.8 Kısım I n Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş TextHello C# proje dosyasıdır. Program .

2. i. Bu ipucu WriteLine yönteminin alabileceği parametreleri görüntüler. r. Console sınıfının WriteLine olarak adlandırılmış birden fazla yöntem içermesi anlamına gelir. WriteLine yönteminin her bir sürümü. (Bölüm 3. Main yöntemi şu şekilde görünmelidir: static void Main(string[] args) { Console } Not Console. WriteLine aşırı yüklenmiş (overloaded) yöntemdir. gerçekten de bu yöntemin 19 farklı sürümünü sağlar. L harflerini yazmaya devam edebilir ve daha sonra da Enter tuşuna basabilirsiniz.(. 3. Siz C harfini yazar yazmaz. Yeni satır üzerinde. küme parantezi {. Aslında.cs dosyasını görüntüleyen Code and Text Editor penceresinde. Program. Main şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console. Con yazdıktan sonra. Listeyi aşağıya doğru kaydırın. WriteLine seçilene kadar W. açtıktan hemen sonra imleci Main yöntemi üzerine getirin ve yeni bir satır oluşturmak için Enter tuşuna basın. IntelliSense listesi görünecektir. t. özellikleri ve Console sınıfının alanlarını gösteren bir diğer IntelliSense listesi görünecektir. Console kelimesinden hemen sonra nokta (. WriteLine’ı seçin ve Enter tuşuna basın. Başka bir IntelliSense ipucu görünür. IntelliSense otomatik olarak listeyi Console öğesi üzerinde yuvalandırır.WriteLine } 4. yazın. yerleşik sınıf adı olan Console kelimesini yazın. Açık parantez . ekranda iletileri görüntülemek ve klavyeden girilen değerleri elde etmek için yöntemler içeren yerleşik sınıftır.WriteLine( } . farklı veri türlerinin çıktısı için kullanılabilir.Bölüm 1 C#’a Hoşgeldiniz 9 IntelliSense kullanarak kod yazın 1.) yazın. Main yöntemi şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console. Alternatif olarak. öğeyi seçmek için Tab ya da Enter tuşuna basabilirsiniz. Alternatif olarak. IntelliSense listesi kapanır ve WriteLine kelimesi kaynak dosyaya eklenir. aşırı yüklenmiş yöntemleri ayrıntıları ile ele alır). Kelimenin tamanını yazabilir ya da listeyi aşağıya doğru çekerek fare ile Console öğesini çift tıklayabilirsiniz. Yöntemleri. Bu liste bu bağlamda geçerli olan C# anahtar sözcükleri ve veri türlerinin tümünü içerir. e.

Kapalı parantez ve noktalı virgül (. parantezi kapatmak kolay unutulabilir. 5.WriteLine(). Parantez içindekini yazdıktan sonra. Yaygın simgeler ve türleri aşağıdaki gibidir: Simge Anlamı method (Bölüm 3’de incelenmiştir) property (Bölüm 15’de incelenmiştir) class (Bölüm 7’de incelenmiştir) struct (Bölüm 9’da incelenmiştir) enum (Bölüm 9’da incelenmiştir) .WriteLine(“Hello World”). o sınıfın her bir üyesinin adını görüntüler. } İpucu İçindekileri yazmadan önce parantez ve süslü parantezleri içi boş olarak ( ) ve { } şeklinde yazın.) koyduğunuzda. Main yöntemi şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console. üyenin türünü gösteren bir simge bulunur. } 6.) yazın. Main yöntemi şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console.10 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu: WriteLine yönteminin farklı aşırı yüklenmeleri üzerinde gezinmek için ipucundaki yukarı ve aşağı oklarını tıklayabilirsiniz. İmleci hareket ettirin ve WriteLine yönteminden sonra parantez arasında tırnak işaretleri ile birlikte “Hello World” dizesini yazın. Her üye adının solunda. IntelliSense Simgeleri Sınıf adından sonra nokta işareti (. IntelliSense.

0 warnings TextHello -> C:\Documents and Settings\John\My Documents\Microsoft Press\… ========== Build: 1 succeeded or up-to-date. Aynı zamanda.5\Csc. WriteLine ifadesinde Hello World metninden sonra parantezi kapatmayı . Output penceresinde. Bu hareket C# kodunu derler. 0 failed.exe /config /nowarn:1701. Kodunuzu. // Enter tuşuna basmak için kullanıcıyı bekleyin Derleyici. sonrasında normal metin içeren kod satırları göreceksiniz. görüntülemek için View menüsü üzerinde Output seçeneğini tıklayın.0 errors. yazılım geliştiriciler için oldukça kullanışlıdır. 0 skipped ======== Hatalar yapmışsanız. gerektiği kadar anlamlı yorumlarla belgelemeye teşvik edilirsiniz.Bölüm 1 C#’a Hoşgeldiniz 11 Simge Anlamı interface (Bölüm 13’de incelenmiştir) delegate (Bölüm 17’de incelenmiştir) extension method (Bölüm 12’de incelenmiştir) Farklı içeriklerle kod yazdıkça diğer IntelliSense simgelerini de göreceksiniz Not Sık sık iki eğik çizgi. Configuration: Debug Any CPU ---C:\Windows\Microsoft.1702 … Compile complete -. Derleyici tarafından yok sayılır fakat programın tam olarak ne yaptığını açıkladığından. programın nasıl derlendiğini gösteren aşağıdakine benzer iletiler görmelisiniz. bu hatalar Error List penceresinde görünecektir. iki eğik çizgiden satır sonuna kadar olan kısımdaki metni atlayacaktır. Konsol uygulamasını oluşturun ve çalıştırın 1. aşağıya doğru inen çok sayıda satır olabilir.Build started: Project: TextHello. Derleyici. eğik çizgi sonrasında yıldız işareti (/*) ile başlayan birden fazla satırda yer alan yorumlar da ekleyebilirsiniz. -----. Aşağıdaki ekran görüntüsü. Örneğin: Console.NET\Framework\v3. çalıştırabileceğiniz programla sonuçlanır. Bunlar yorumlardır. Code and Text Editor penceresi altında Output penceresi görünür. Build Solution seçeneğini tıklayın.ReadLine(). //. Build menüsü üzerinde. yıldız işareti sonrasında eğik çizgi (*/) bulana kadar herşeyi atlar. İpucu Output penceresi ortaya çıkmazsa.

altında dalgalı kırmızı çizgi ile gösterir. Code and Text Editor penceresinin üzerindeki sekmedeki dosya adından sonra yer alan yıldız işareti. Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. İpucu Build Solution komutu dosyayı otomatik olarak kaydettiği için oluşturmadan önce dosyayı kaydetmeniz gerekmez. Visual Studio. proje oluşturduğunuz zaman belirtilen konumda kaydedilir. İmleç hataya neden olan satır üzerine yerleşir. . Önceki yönergeleri dikkatlice izlediyseniz. İpucu Error List penceresindeki öğeyi çift tıklayabilirsiniz. Tek bir hatanın bazen çok sayıda derleme hatasına neden olabileceğine dikkat edin. derlenmeyecek kod satırlarını. Visual C# 2008 Express Edition kullanıyorsanız. proje geçici bir konumda kaydedilir ve sadece File menüsü üzerindeki Save All komutunu kullanarak projeyi kaydettiğinizde ya da Visual C# 2008 Express Edition’ı kapattığınızda görünen Options iletişim kutusunda belirtilen klasöre kopyalanır. hiçbir hata ya da uyarı olmamalı ve program başarılı olarak çalışmalıdır. dosyanın son kaydedildiğinden beri değiştirildiğini gösterir.12 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş unutursanız neler olacağını gösterir.

HelloWord iletisi görünür ve daha sonra aşağıdaki ekran görüntüsünde gösterildiği gibi program herhangi bir tuşa basmanızı bekler. Komut penceresi kapanır ve Visual Studio 2008 programlama ortamına dönersiniz. Program. Start Without Debugging’ı tıklayın. 3. uygulamayı oluşturmak ve hata ayıklamak için kullanılan bazı diğer dosyalar ile birlikte. Not Ayrıca. Debug olarak adlandırılmış bir diğer klasör ortaya çıkar. Not “Press any key to continue…” uyarısı Visual Studio tarafından oluşturulmuştur. Uygulamanızı oluşturduğunuzda. Komut penceresi açılır ve program çalışır. Debug menüsünde. . Solution Explorer’da. bunun için herhangi bir kod yazmazsınız. bin and obj dosyalarına karşılık gelir. TextHello projesini (çözümü değil) tıklayın ve daha sonra Solution Explorer araç çubuğu üzerindeki Show All Files araç çubuğu düğmesini tıklayın (Solution Explorer penceresindeki araç çubuğu üzerinde soldan ikinci düğmedir). uygulama çalışır fakat komut penceresi sizin bir tuşa basmanızı beklemeden aniden kapanır. Solution Explorer’da. 5. bin girişinin solundaki artı işaretini (+) tıklayın. doğrudan proje klasöründeki (Microsoft Press\Visual CSharp Step by Step\ Chapter 1\TextHello\TextHello). Bu girişler. 4. Program sonucunu gösteren komut penceresinin etkin olduğundan emin olun ve Enter tuşuna basın. Release olarak adlandırılmış bir klasör de görebilirsiniz.Bölüm 1 C#’a Hoşgeldiniz 13 2. Programı Debug menüsü üzerindeki Start Debugging komutunu kullanarak başlattıysanız. programın uygulanabilir sürümünü içerirler. Visual Studio bu klasörleri yaratır ve bu klasörler.cs dosyasının üstünde bin ve obj olarak adlandırılmış girişler görünür.

exe. TextHello. İlki. TextHello. TextHello. bu dosyaların tümünü göremeyebilirsiniz. Ad Alanlarını Kullanmak Şimdiye kadar gördüğünüz örnek.pdb. büyük programları anlamak ve bakımını yapmak.vshost. Debug klasörünün solundaki artı işaretini (+) tıklayın.exe ve TextHello. adları yazmak. Aşağıdaki gibi. programcılar ad-çakışması problemini. TextHello. küçük programları anlamak ve bakımını yapmaktan zordur. iki ya da daha fazla ad çakışacağından projenin hata oluşturma olasılığı da artar (özellikle program.vshost. daha fazla yöntem ve daha fazla sınıf demektir. okumak ve anlaşılmayan uzun adları tekrar okumak için daha fazla zaman harcayabilirsiniz. Visual Studio 2008 tarafından kullanılan bilgiyi içerir. ayrıca aynı adları kullanmış olan yazılım geliştiriciler tarafından yazılmış üçüncü parti kütüphaneleri kullandığında).14 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 6. Program büyüdükçe. adların önüne bir tür niteleyici (ya da niteleyici kümesi) ön eki koyarak çözmeye çalıştılar. Bununla birlikte. İkincisi. çok küçük bir programdır. programınızı Debug modda çalıştırdığınızda (Debug menüsünde Start Debugging’ı tıkladığınızda). adlar uzun olmaya başlayabilir ve yazılımı yazmak için daha az. Solution Explorer’da. Ölçeklenebilir olmadığından bu iyi bir çözüm değildir. exe.exe dosyası derlenmiş programdır ve Debug menüsünde Start Without Debugging’ı tıkladığınızda çalışan dosyadır. daha fazla kod genellikle daha fazla ad. küçük programlar büyüyerek çok büyük programlara dönüşebilir. Diğer dosyalar. Ad sayısı arttıkça. Geçmişte. . iki sorun ortaya çıkar.manifest olarak adlandırılmış dört öğe daha görünür: Show All Files Not Visual C# 2008 Express Edition kullanıyorsanız.

Aşağıdaki alıştırma ad alanı kavramını daha ayrıntılı olarak gösterir. System. Tüm sınıflarınızı ad alanlarında tanımlamak iyi bir uygulamadır ve Visual Studio 2008 ortamı üst seviye ad alanı olarak projenizin adını kullanarak bu tavsiyeye uyar. birbirine karıştırılmazlar.Greeting olarak belirtmeniz gerekir. ad alanı zahmetine girmeden. System.Collections. Diğer yazılım geliştiricinin Greeting sınıfına başvurmak isterseniz.Bölüm 1 C#’a Hoşgeldiniz 15 Ad alanları.cs dosyasına bakarsanız. dosyanın üstünde aşağıdaki ifadeleri görürsünüz: using using using using System. using ifadesi. TextHello olarak adlandırılmış alan adı içinde Greeting adında bir sınıf yaratabilirsiniz: namespace TextHello { class Greeting { . Aynı adla iki sınıf. Aşağıdaki gibi. SystemConsole gibi bazı genel benzersiz bir adla adlandırmaktan daha iyi olmayacaktı.Generic.. her kullandığınızda sınıfın tam adını yazmak zorunda olsaydınız. sınıflar gibi. Code and Text Editor penceresinde Program. siz her yeni proje yarattığınızda Visual Studio 2008’in bu using ifadelerini otomatik olarak eklediği. bu durum. kapsama ad alanı getirir. yine istenildiği gibi çalışır. Gösterilen dört ad alanı. artık nesneleri açık bir şekilde ait oldukları ad alanı ile nitelendirmeniz gerekmez.Console olması demektir. Bu. Aynı dosyada. farklı ad alanlarında yer alıyorlarsa. Başka bir yazılım geliştirici de NewNamespace gibi farklı bir ad alanında Greeting sınıfı yaratırsa ve sizin bilgisayarınıza yüklerse. niteleyicileri ön ek olarak eklemekten ya da sınıfı.NET Framework yazılım geliştirme paketi de (SDK) bu öneriye bağlı kalır. Elbette.. oldukça sık kullanılan sınıfları kapsar. bu problemi programlarınızda using yönergesi kullanarak çözebilirsiniz. . NewNamespace.Greeting olarak Greeting sınıfına başvurabilirsiniz. . programlarınız TextHello.NET Framework’deki her sınıf. Visual Studio 2008’de TextHello programına dönerek. bir ad alanı içinde yer alır.Greeting sınıfını kullandığından. Örneğin. bir sonraki kodda. tam adının aslında System.Linq.Text. } } Daha sonra programlarınızda TextHello. Neyse ki. Console sınıfı System ad alanı içinde yer alır. diğer tanımlayıcılar için adlandırılmış toplayıcı kap yaratarak bu problemi çözmenize yardımcı olur. . System. Kaynak dosyasının üstüne daha fazla using yönergeleri ekleyebilirsiniz.

tam olarak tanımlanmış System. dosyanın üzerindeki ilk using yöndergesini aşağıdaki şekilde yorum satırı haline getirin: //using System.cs dosyasını görüntüleyen Code and Text Editor penceresinde.dll dosya uzantısına sahip dosyadır. Sınıflar. Başarılı olmazsa. Debug menüsünde Start Without Debugging’ı tıklayarak uygulamayı çalıştırın.Console. 4. Program. Main yönteminin tam olarak bir önceki kodda göründüğü gibi olduğundan emin olun ve daha sonra tekrar oluşturmayı deneyin. } Not System yazdığınızda. 3. IntelliSense tarafından System ad alanındaki tüm öğelerin adı görüntülenir. Oluşturma işlemi hata verir ve Error List penceresi aşağıdaki hata iletisini gösterir: The name ’Console’ does not exist in the current context. derlemelere (assemblies) derlenir. Bu defa oluşumun başarılı olması gerekir.16 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Uzun adları kullanmayı deneyin 1. Açık konuşmak gerekirse. hata iletisini çift tıklayın. Build Solution’ı tıklayın. Code and Text Editor penceresinde. Build Solution’ı tıklayın. Build menüsünde. Main şu şekilde görünmelidir: static void Main(string[] args) { System.WriteLine(“Hello World”). 6. 5. 2. ad alanındaki öğeleri basitçe kapsam içine getirir ve kodunuzda sınıf adlarını tam olarak nitelendirmek zorunda kalmazsınız.Console adını kullanmak için Main yöntemini düzenleyin. .exe dosya adı uzantısı ile uygulanabilir programlar da derlemelerdir. Program. . Ad Alanları ve Derlemeleri Kullanmak using ifadesi. Error List penceresinde. Uygulamanın çalıştığından emin olmak için. Derleme. Build menüsünde.cs kaynak dosyasında hataya neden olan tanımlayıcı seçilir. genellikle .

projenize o derleme için başvuru eklemeniz gerekir.Console gibi tüm ortak sınıfları içeren bir “çekirdek” derleme ve veritabanlarını. Tümü aynı derlemede tutulmuş olsaydı. fakat yakında alışacaksınız. çok sayıda sınıf içerebilir. Bir uygulama yaratmak için Visual Studio kullandığınızda. TextHello projesi için Solution Explorer’da References klasörünün sol tarafındaki artı işaretini (+) tıklayın. tek bir derleme birden fazla ad alanı için sınıf içerebilir ve tek bir ad alanı birden fazla derlemeye yayılabilir.Core. System. tek bir sınıftaki tek bir yöntemi güncellediğinde. Visual Studio 2008. bu işlemi sonraki alıştırmalarda uygulayacaksınız. Windows tabanlı uygulamanın forma dayalı kullanıcı arayüzünü etkileşimli olarak tasarlayabilirsiniz. Visual Studio 2008 grafiksel uygulamanın iki görünümünü sağlar: tasarım görünümü ve kod görünümü. tüm sınıf kütüphanesini tüm yazılım geliştiricilere dağıtmak zorunda kalırdı!) Bu nedenle. basit Konsol uygulaması yaratmak ve çalıştırmak için Visual Studio 2008’i kullandınız. Grafiksel Uygulama Yaratmak Şimdiye kadar. kapsam içine getiren using ifadelerini ekleyebilirsiniz. System. System. System. . (Microsoft.NET Framework sınıf kütüphanesinin içerdiği sınıflar.Console gibi. sınıfların ilişkili olduğu işlevsel alan tarafından ayrılmış çok sayıda derlemeye bölünmüştür. Visual Studio 2008 programlama ortamı aynı zamanda grafiksel Windows-tabanlı uygulamalar oluşturmak için ihtiyacınız olan herşeyi kapsar. daha sonra tasarladığınız kullanıcı arayüzünü uygulamak için program ifadelerini oluşturur.Data ve System. seçtiğiniz şablon otomatik olarak uygun derlemeye başvuru içerir. Visual Studio ile birlikte bilgisayarınıza yüklenmiş olan derlemelerde sağlanmıştır. o derlemedeki ad alanlarındaki öğeleri. Bir sınıfı derlemede kullanılır yapmak istiyorsanız.NET Framework sınıf kütüphanesi.Bölüm 1 C#’a Hoşgeldiniz 17 Derleme. Örneğin. Konsol uygulamasının. References klasörünü farenin sağ düğmesiyle tıklayıp Add Reference’a tıklayarak projenize ilave derlemeler için referanslar ekleyebilirsiniz. Web hizmetlerine erişimi. . Örneğin. derleme çok büyük olur ve bakımı zor olurdu.Xml olarak adlandırılmış derlemelere otomatik olarak başvurular içerdiğini göreceksiniz. grafiksel kullanıcı arayüzü oluşturmayı ve bunun gibi şeyleri işlemek için sınıflar içeren daha fazla derleme vardır.NET Framework sınıf kütüphanesinin binlerce sınıf içerdiğini göreceksiniz. . System. Bu ilk önce oldukça karmaşık gibi gelebilir. Daha sonra kodunuza. Derleme ve ad alanı arasında 1:1 eşitliğe gerek olmadığını not etmelisiniz. Grafiksel uygulama için kod ve mantığı değiştirmek ve bakımını yapmak için Code and Text Editor penceresini ve kullanıcı arayüzünü yerleştirmek için de Design .

1.0 ile ortaya çıkmış olan geliştirilmiş teknolojidir. adınızı girebileceğiniz bir metin kutusu ve bastığınızda ileti kutusunda bir selamlama iletisi gösterecek olan bir düğme içeren. yeni bir grafiksel uygulama yaratmak için aşağıdaki işlemleri gerçekleştirin. WPF Application simgesini tıklayın. Aşağıdaki alıştırmalarda Visual Studio 2008 kullanarak grafiksel uygulamayı nasıl yaratacağınızı öğreneceksiniz. ilk olarak . Add to Solution. Bu eylem projeyi tutmak için yeni bir çözüm yaratır. Not Visual Studio 2008 grafiksel uygulamalar oluşturmak için iki şablon sağlar: Windows Forms Application şablonu ve WPF Application şablonu. 4. File menüsünde. Visual Studio 2008’de grafiksel uygulama yaratın n Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Name alanına WPFHello yazın. 2.0 ile ortaya çıkmış olan bir teknolojidir. Project Types bölmesinde Visual C#’ı tıklayın. Location alanının Belgeler klasörü altındaki Microsoft Press\Visual CSharp Step by Step\Chapter 1 dosyasına ayarlanmış olduğunu doğrulayın ve daha sonra Save’i tıklayın. New Project iletişim kutusu açılır.18 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş View penceresini kullanırsınız. 2. Windows Formlarına birçok ek özellik ve kapasite sağlar. Save Project iletişim kutusunda. basit bir form görüntüler.NET Framework sürüm 3. New’i işaret edin ve daha sonra Project’i tıklayın. WPF ya da Windows Presentation Foundation. New Project ileti kutusu görünürse. Location alanının Belgeler\Microsoft Press\Visual CSharp Step by Step\Chapter 1 klasörünü gösterdiğinden emin olun. projeyi TextHello çözümüne ekler. File menüsünde New Project’i tıklayın. Bu program. Windows Formları ilk olarak . Tüm yeni yazılım geliştirmeleri için WPF’ı. OK’i tıklayın. İstediğiniz zaman bu iki görünümün birinden ötekine geçiş yapabilirsiniz. Create new solution ‘ın seçili olduğundan emin olun. 3. 6.NET Framework sürüm 1. 7. TextHello projenizde yaptığınız değişiklikleri kaydetmek için Save’i tıklayın. yeni bir grafiksel uygulama yaratmak için aşağıdaki işlemleri gerçekleştirin: 1. Solution alanında. Alternatif olarak. Windows Formlarına tercih etmelisiniz. n . Visual C# 2008 Express Edition kullanıyorsanız. 5. Templates bölmesinde.

bir XAML tanımı yazarak bir WPF formunu tam olarak tanımlayabilirsiniz. XML dilini biliyorsanız. XAML dili de size aşina gelmelidir. XAML. Windows SDK ile birlikte yüklenmiş olan XAMLPad adı verilen bir XAML düzenleyicisi sağlar. . New Project iletişim kutusunda. Name alanına WPFHello yazın. Extensible Application Markup Language anlamına gelir ve formun yapısını ve içeriğini tanımlamak için WPF uygulamaları tarafından kullanılan XML benzeri bir dildir.Bölüm 1 C#’a Hoşgeldiniz 19 3. 4. Visual Studio 2008 geçerli uygulamanızı kapatır ve yeni bir WPF uygulaması yaratır. Design View penceresinde boş bir WPF formu görüntüler: İpucu Design View penceresini görüntülemek üzere ekranda daha fazla alan sağlamak için Output ve Error List pencerelerini kapatın. Microsoft. Visual Studio’nun Design View penceresini kullanmayı istemiyorsanız ya da Visual Studio’ya erişime sahip değilseniz. OK’i tıklayın. 5. Aşağıdaki alıştırmalarda. Windows formuna üç denetim eklemek için Design View penceresini kullanacak ve bu denetimleri uygulamak için Visual Studio 2008 tarafından otomatik olarak oluşturulmuş C# kodunun bazılarını inceleyeceksiniz. WPF Application simgesini tıklayın. Aşağıdaki resimde gösterildiği gibi. formun XAML tanımını içeren başka bir pencere ile birlikte.

“Windows Presentation Foundation’a Giriş” bölümünde WPF denetimlerinin Height ve Width özelliklerini ve Margin özelliğini daha ayrıntılı olarak öğreneceksiniz. çok fazla alanı kaybedebilirsiniz. View menüsünde Properties Window’u tıklayın. Margin özelliği tarafından yönetilen form üzerindeki konum gibi özelliklerle birlikte. Bu tekniği kullanarak. Margin özelliğinin değeri değişir. Visual Studio 2008 penceresinin sol tarafında Toolbox kalıcı olarak görünür ve Toolbox’ı yerleştirmek için Design View penceresi küçülür. Ekranın sağ alt köşesinde. pencere etiket için özellikleri görüntüler. Form yeniden boyutlandırılırsa. Design View penceresinde görüntülenen formun başlık çubuğunu tıklarsanız. Margin değerlerini sıfır olarak ayarlayarak bunu engelleyebilirsiniz. Forma etiket denetimi eklenir (kısa sürede doğru konuma getireceksiniz) ve Toolbox gözden kaybolur. Form üzerinde herhangi bir yeri tıklarsanız. Properties penceresinin formun kendi özelliklerini görüntülediğini görebilirsiniz. Etiket denetimini tıklarsanız. 3. formun sol üst köşesine doğru konumlanacak şekilde etiket denetimini taşıyın. Common bölümünde. Controls bölümü. Solution Explorer altında. Label’ı tıklayın ve daha sonra formun görülebilir kısmını tıklayın. etiket denetimini de içerir.) Not Küçük bölmedeki formun XAML tanımı şimdi. projedeki diğer özellikler kadar. Margin özelliği. 2. 4. etiketin her köşesinin formun köşelerine uzaklığını gösteren dört sayıdan ibarettir. Kısmen formu engelleyerek araç kutusu görünür ve Windows formuna yerleştirebileceğiniz çeşitli bileşenleri ve denetimleri görüntüler. (Düşük çözünürlükte ekrana sahipseniz. yani seçilmiş olan geçerli öğe için özellikleri görüntüler.20 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Kullanıcı arayüzü yaratın 1. Properties penceresi. denetimlerin daha geniş listesini gösterir. Properties penceresi grid (kılavuz) adı verilen bilinmeyen bir öğenin özelliklerini görüntüler. İçerik duyarlıdır. formun kenarlarına tutturulmuş taşınan denetimler kenar değerlerini korumak için yeniden boyutlandırılır. Form üzerindeki etiket denetimi muhtemelen sizin olmasını istediğiniz yerde değildir. Common bölümü birçok WPF uygulaması tarafından kullanılan denetimlerin listesini gösterir. . form üzerindeki öğelerin özelliklerini değiştirmek için başka bir yol sağlar. Properties penceresi görünür (Zaten ekranda değilse). Forma eklediğiniz denetimleri tıklayarak istediğiniz yere sürükleyebilirsiniz. (Bu uygulama için gerçek konum önemli değildir.) Auto Hide düğmesini birden fazla tıklamak Toolbox’ın yeniden gözden kaybolmasına neden olur. Bölüm 22. İpucu Toolbox’ın açık kalmasını fakat formun herhangi bir kısmını gizlememesini isterseniz. Design View penceresinde formun sol tarafında görünen Toolbox sekmesini tıklayın. Denetimi form etrafında taşırsanız. Toolbox başlıklı çubuğun sağındaki Auto Hide düğmesini tıklayın (raptiye gibi görünür).

özellik değerlerini içeren bir <Label> etiketi.Bölüm 1 C#’a Hoşgeldiniz 21 Kılavuz. . Design View penceresinde hemen kendiliğinden yeniden boyutlanmayabilir. Properties penceresinde. etiketdeki metnin boyutu değişir. Bu arada. Etiket metni göstermek için yeterince büyük olmamasına rağmen. 5. 6. FontSize özelliğini 20 olarak değiştirin ve daha sonra formun başlık çubuğunu tıklayın. form üzerindeki öğelerin nasıl hizalandığını ve birarada gruplandırıldığını göstermek için kılavuz kullanabilirsiniz. WPF formu üzerindeki öğeler için bir kap gibi davranır. Bu bölümdeki özellikleri kullanarak. 8. Aşağıdaki bölmedeki formun XAML tanımını sağa doğru kaydırın ve etiket denetiminin özelliklerini inceleyin. Etiket denetimi. Uygulamayı oluşturup çalıştırdığınızda ya da Design View penceresini kapatıp açtığınızda doğru değeri alır. 7. Text bölümünün yerini belirleyin. Form üzerindeki etiket denetimini tıklayın. etiketin gösterdiği gerçek metnin değil. etiketin kendisinin yazı tipi ve yazı tipi büyüklüğünü belirleyebilirsiniz. ”Please enter your name” olarak değiştirin. Etiket metnini (kapatma etiketinden hemen önce). Not Etikette gösterilen metin. Aşağıdaki resimde gösterildiği gibi. ardından etiketin kendisi için metin (“Label”) ve daha sonra da kapanma </Label> etiketinden oluşur. FontSize’ı tekrar 12 olarak değiştirin.

Toolbox’ı tekrar görüntüleyin. formun başlık çubuğunu tıklayın. diğer denetimlerle yatay ya da dikey olarak hizalandığında.xaml formunun başlık çubuğunu tıklayın. Fare işaretçisi. form üzerini tıklayarak formu yeniden boyutlandırmak için işaretciyi sürükleyin. pencerenin üzerinde gösterilen Name özelliğinin değerini userName olarak değiştirin. 12. denetim. form üzerindeki etikette görüntülenen metnin değiştiğine dikkat edin. 11. formun kendisinin boyutunu değil. . “Değişkenler. Toolbox’da TextBox’ı tıklayın ve daha sonra da formu tıklayın. Doğrudan etiket denetiminin altında olacak şekilde metin kutusu denetimini taşıyın. Title özelliğini Hello olarak değiştirin.22 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Metni göstermek için etiket hala çok küçük olmakla birlikte. 16. Bu. OK olarak değiştirin. Design View penceresinde formu tıklayın ve Toolbox’ı tekrar görüntüleyin. Operatörler ve İfadelerle Çalışmak” bölümünde denetimler ve değişkenler için adlandırma kuralları hakkında daha fazlasını öğreneceksiniz. 15. köşegen çift başlı oka dönüştüğünde. otomatik olarak hizalama göstergesi görünür. 10. Design View penceresinde. Properties penceresinde. Form üzerindeki düğme denetiminin başlığının da değiştiğinden emin olun. form seçildiğinde formun sağ alt köşesinde yeniden boyutlandırma tutamacının (küçük bir kare) ortaya çıktığına dikkat edin. form üzerinde metin kutusu denetiminin sağına sürükleyin. düğme tarafından gösterilen başlığı görüntülemek için metni sağa kaydırın ve Button olan başlığı. Fare işaretçisini. “There are no usable controls in this group” (bu grupta kullanılabilir denetim yok) hata iletisini gösterir. form üzerindeki denetimlerin yerleşimini değiştirirsiniz. Metin kutusu denetimi seçildiğinde. Properties penceresini kullanarak. 13. form içindeki kılavuzun dış çizgisini değil. Önemli Formu yeniden boyutlandırmadan önce. böylece düğmenin altı yatay olarak metin kutusunun altı ile hizalanır. Kılavuzu seçerseniz. Formun XAML tanımında. Metin kutusu denetimi forma eklenir. Window1. 9. yeniden boyutlandırma tutamacı üzerinde hareket ettirin. Button’ı ve daha sonra da formu tıklayın. Properties penceresinde. Sürüklemeyi durdurun ve denetimler etrafındaki aralık kabaca eşit olduğunda farenin düğmesini serbest bırakın. Toolbox. düğme denetiminin Name özelliğini ok olarak değiştirin. İpucu Form üzerinde denetimi sürüklediğinizde. 14. Not Design View penceresinde formu tıklamazsanız. Düğme denetimini. denetimlerin düzgün hizalandığından emin olmak için hızlı bir görsel işaret verir. Design View penceresinde. Not Bölüm 2.

OK düğmesi için Click olayını işlemek için bazı kodlar eklemeniz gerekir. Start Without Debugging’i tıklayın. . Debug menüsünde. formu başlatmak ve görüntülemek gibi tüm grafiksel uygulamaların gerçekleştirmek zorunda olduğu rutin görevleri işleyen çok sayıda kod oluşturur. Etiketin sol kenar boşluğu da sabitlenmiştir ve form daralmaya başladıkça etiket küçüldüğünde. fakat henüz hiçbirşey olmaz. OK düğmesi metin kutusu denetiminin üzerine biner. Bundan sonraki alıştırmada bunu yapacaksınız. Tek bir C# kod satırı yazmadan grafiksel uygulama yaratmayı başardınız. Uygulama. Build menüsünde Build Solution’u tıklayın ve projenin başarılı bir şekilde oluşturulduğunu doğrulayın. fakat Visual Studio sizin için.Bölüm 1 C#’a Hoşgeldiniz 23 Not Formu daha dar yaparsanız. Metin kutusuna adınızı yazın ve OK’i tıklayın. Formu çok dar yaparsanız. Visual Studio’nun sizin için ne oluşturduğunu anlamak iyi olacaktır. 18. etiketin metni görünmez olmaya başlar. formunuzu çalıştırmalı ve görüntülemelidir. Form şimdi şu şekilde görünmelidir: 17. Uygulamaya kendi kodunuzu eklemeden önce. Formu kapatmak ve Visual Studio 2008’e dönmek için Close düğmesini (formun sağ üst köşesindeki X simgesi) tıklayın. Henüz çoğu yapılmadı (biraz sonra biraz kod yazmanız gerekecek). OK düğmesi formun sağdaki köşesinden Margin özelliği ile hesaplanan sabitlenmiş uzaklıkta sabit kalır. 19.

System. System.Windows. Şu şekilde görünür: using using using using using using using using using using using using using System.Windows.xaml. System. Window1.Generic. System. xaml.Collections. Window1. System.Windows. namespace WPFHello { /// <summary> /// Interaction logic for Window1. biraz kod vardır. form üzerindeki çeşitli denetimleri yaratma ve konumlandırma gibi işlemleri gerçekleştirir.cs dosyasını çift tıklayın. System.Text.24 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Solution Explorer’da Window1. Bölüm 7’de kurucuları öğreneceksiniz. uygulamanızın mantığını işlemek için. InitializeComponent adı verilen yöntemi çağıran.Media. kullanıcı OK düğmesini tıkladığında nelerin meydana geleceği gibi. .) Aslında. Bu sınıfta görebileceğiniz kodun amacı. System.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent().Documents.Navigation.Windows. Sınıf örneği yaratıldığında uygulanır ve örneği başlatmak için kod içerebilir.Controls. System.Windows. System. uygulama çok sayıda kod içerir. daha fazlasını değil.Windows.Input.cs dosyası görünür.Windows.Linq.Data. formun XAML tanımına dayanarak otomatik olarak oluşturulmuş ve sizden gizlenmiştir.Shapes. birçok WPF uygulamasının kullandığı bazı ad alanlarını kapsama getiren çok sayıda using deyiminden başka. Code and Text Editor penceresinde görüntülenir. sınıf ile aynı adda olan özel bir yöntemdir. (Kurucu. fakat çoğu. } } } Dosya. System. Window1 sınıfı için kurucu olarak bilinen. System. Bu saklı kod. Formun kodu. fakat hepsi budur.Windows.Media. Window1 adı verilen sınıfın tanımını içerir.Imaging. System.xaml dosyasının yanındaki artı işaretini (+) tıklayın. formu yaratma ve görüntüleme. kendi yöntemlerinizi ekleyebilmenizdir.Windows.

Bu noktada.Generic. Main yönteminin programın başlayacağı noktayı tanımladığını hatırlayın. aşağıdaki kodu içerdiğini görürsünüz: using using using using using using System.cs dosyası olduğunu göreceksiniz.Data.Windows.Configuration. Main yönteminin nerede olduğunu ve uygulama çalıştığında görüntülenen formun nasıl elde edildiğini merak edebilirsiniz.xaml adında bir diğer kaynak dosyaya dikkat etmiş olmalısınız.Collections. Bu dosyayı çift tıklarsanız. fakat dosya XAML tanımına sahiptir.xaml.Bölüm 1 C#’a Hoşgeldiniz 25 İpucu Design View penceresinde herhangi bir yeri farenin sağ düğmesiyle tıklayarak ve daha sonra View Code’u tıklayarak WPF formunun C# kodu dosyasını görüntüleyebilirsiniz. App. System.xaml dosyasına başvurur: Solution Explorer’da. System. ayrıca Application.Linq. Solution Explorer’da. . Window1. System. System. Bu dosyayı çift tıklarsanız. System.xaml dosyasına bitişik olan artı işaretini (+) tıklarsanız. Design View penceresi “Intentionally Left Blank”(“Özellikle Boş Bırakılmış”) iletisini görüntüler. XAML kodunda bir özellik StartupUri olarak adlandırılır ve aşağıda gösterildiği gibi. App.

Henüz bu kodun sözdizimi hakkında fazla düşünmenize gerek yok (sadece tam olarak yukarda gösterildiği gibi kopyaladığınızdan emin olun).26 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş namespace WPFHello { /// <summary> /// Interaction logic for App. “Hello” metni ile birlikte kullanıcının forma eklenmiş username metin kutusuna girdiği adı içeren ileti kutusunu görüntüler. İlginç kısım MessageBox. 4. fakat gizlenmiş. ok_Click yöntemine. Code and Text Editor penceresinde Window1. olayların nasıl çalıştığı hakkında daha fazla ayrıntı öğreneceksiniz. StartupUri özelliği tarafından belirlenmiş formu oluşturacak ve görüntüleyecektir. Main yöntemi orada. fakat yeterince değil. Bu bir olay örneğidir. 3. Design View penceresinde Window1’i görüntülemek için. RoutedEventArgs e) { MessageBox. özellikle. Form üzerindeki OK düğmesini çift tıklayın.Text). Design View penceresinde Window1’i tekrar görüntülemek için Code and Text Editor penceresi üstündeki Window1. App. kullanıcı OK düğmesini tıkladığında bu yöntemi çağırmak için otomatik olarak kod oluşturur.Show(“Hello ” + userName.xaml. çok sayıda using ifadesi var. xaml dosyasındaki ayarlara dayanarak oluşturulmuştur. } Bu. hatta Main yöntemi de yok.Show ifadesidir. Visual Studio.cs dosyası görünür. koyu renkli yazılmış olan kodu ekleyin: void ok_Click(object sender. Bu ifade.xaml sekmesine tıklayın. Kitap boyunca ilerledikçe. fakat ok_Click olarak adlandırılmış yeni bir yöntem eklenmiştir. Code and Text Editor penceresinin üstündeki Window1. Kendi kendinize biraz kod yazmanızın zamanı geldi! OK düğmesi için kod yazın 1. Main yöntemi için kod.xaml sekmesini tıklayın. kullanıcı OK düğmesini tıkladığında çalışacak olan koddur. Bölüm 3’te yöntemler hakkında herşeyi öğreneceksiniz. Aslında. . 2. Main yöntemi.xaml /// </summary> public partial class App : Application { } } Bir kez daha söylemek gerekirse.

ok_Click yöntemine başvuran Click adında bir öğe içerdiğine dikkat edin: <Button Height=”23” … Click=”ok_Click”>OK</Button> 6. Form göründüğünde. n Bir sonraki bölüme devam etmek istiyorsanız Visual Studio 2008’i çalışır durumda tutun ve Bölüm 2’ye geçin. Adınızla sizi selamlayan ileti kutusu görünür. 7. fakat hiçbirşeyi değiştirmemeye dikkat edin. İleti kutusu kapanır. n . İleti kutusunda OK’i tıklayın. 9. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde. Formu kapatın. Save iletişim kutusu görürseniz. Exit’i tıklayın. adınızı metin kutusuna yazın ve daha sonra OK’i tıklayın. Debug menüsünde. Yes’i (Visual Studio 2008 kullanıyorsanız) ya da Save’i (Visual C# 2008 Express Edition kullanıyorsanız) tıklayın ve projeyi kaydedin. Button öğesini inceleyin. Formun XAML tanımını gösteren aşağıdaki sekmede. Start Without Debugging’i tıklayın.Bölüm 1 C#’a Hoşgeldiniz 27 5. 8.

OK’i tıklayın. Proje türü olarak Visual C# seçin. proje dosyaları için bir dizin belirleyin. Build Solution’ı tıklayın. Projects and Solutions seçeneğini tıklayın. Projects and Solutions seçeneğini tıklayın. Options iletişim kutusunda.28 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bölüm 1 Hızlı Başvuru Bunun İçin Visual Studio 2008 Standard ya da Professional Edition kullanarak yeni bir konsol uygulaması yaratmak Şunu Yapın File menüsünde New’i işaret edin ve sonra New Project iletişim kutusunu açmak için Project’i tıklayın. Tuş Bileşimi Visual C# 2008 Express Edition kullanarak yeni konsol uygulaması yaratmak Visual Studio 2008 Standard ya da Professional Edition kullanarak yeni grafiksel uygulama yaratmak File menüsünde New’i işaret edin ve sonra New Project iletişim kutusunu açmak için Project’i tıklayın. proje dosyaları için bir dizin belirleyin. Tools menüsünde Options’ı tıklayın. Proje için bir ad seçin. OK’i tıklayın . Proje için bir ad seçin. Location kutusunda proje dosyaları için bir dizin seçin. Şablon olarak. File menüsünde New Project iletişim kutusunu açmak için New’i tıklayın. Console Application seçin. Proje için bir ad seçin. Şablon olarak. Options iletişim kutusunda. WPF Application seçin. Şablon olarak. Visual Studio projects location kutusunda. Start Without Debugging’i tıklayın. OK’i tıklayın. Visual C# 2008 Express Edition kullanarak yeni grafiksel uygulama yaratmak Uygulama oluşturmak Uygulamayı çalıştırmak Build menüsünde. F6 Ctrl+F5 . Debug menüsünde. Proje türü olarak Visual C# seçin. Şablon olarak. File menüsünde New Project iletişim kutusunu açmak için New’i tıklayın. Console Application seçin. OK’i tıklayın. Tools menüsünde Options’ı tıklayın. Visual Studio projects location kutusunda. Proje için bir ad seçin. WPF Application seçin. Location kutusunda proje dosyaları için bir dizin seçin.

yöntemler hakkında daha fazlasını öğreneceksiniz. “Yöntemler Yazmak ve Kapsam Uygulamak” bölümünde. Bölüm 3. Bir önceki bölümde gördüğümüz Main. (Karşıt olarak. bir eylem gerçekleştiren komuttur. “C#’a Hoşgeldiniz” başlıklı Bölüm 1’de Console programı ve Windows Presentation Foundation (WPF) uygulaması oluşturmak ve çalıştırmak için Microsoft Visual Studio 2008 programlama ortamını nasıl kullanacağınızı öğrendiniz. anahtar sözcükler ve tanımlayıcılar gibi. ifadelerin ne yaptığının belirtimi topluca anlambilim olarak bilinir). Temel C# türleriyle (C# dili içinde yerleşik olan türler) ve her türün taşıdığı değerlerin özellikleriyle çalışacaksınız. her ifadenin bir noktalı virgül ile bitmesi gerektiğidir. sonundaki noktalı virgül olmadan. İşleçler ve Deyimlerle Çalışmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n İfadeler.Bölüm 2 Değişkenler. Örneğin. Bu bölümde ise ifadeler. İfadeleri Anlamak Bir ifade (statement). Artı işareti (+) ve eksi işareti (-) gibi aritmetik işleçleri kullanmak. tanımlayıcılar ve anahtar sözcükleri anlamak. Değişkenleri artırmak ve azaltmak.WriteLine(“Hello World”). C#’daki ifadeler. iyi tanımlanmış bir kurallar kümesine uymalıdır. C#’ın sunduğu aritmetik işleçleri. Microsoft Visual C# sözdiziminin ve dil yapısının öğeleriyle tanışacaksınız. aşağıdaki ifade derlenmeyecektir: Console. 29 . yöntem için bir örnektir. yöntemi adlandırılmış ve sıralanmış ifadeler olarak düşünün. C# sözdizimi kurallarından biri ve en önemlisi. değerleri değiştirmek için işleçleri kullanmayı ve iki ya da daha fazla işleç içeren deyimleri denetlemeyi öğreneceksiniz. yerel değişkenleri (sadece bir yöntem ya da başka küçük kod parçasındaki değişkenler) bildirmeyi ve kullanmayı görecek. Ayrıca. Bilgi depolamak için değişkenler kullanmak. Temel veri türleri ile çalışmak. İfadeler yöntemlerin içinde bulunurlar. Bu kurallar topluca sözdizimi olarak bilinir. Fakat şimdilik.

Örneğin. namespace ve using verilebilir. Anahtar sözcüklere örnek olarak class. 77 adet tanımlayıcıyı kendisi kullanmak için ayırmıştır ve bu tanımlayıcıları kendi amaçlarınız için yeniden kullanamazsınız. en önemli C# ifadelerinin örneklerini göreceksiniz.30 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu C#. tanımlayıcıları seçerken aşağıdaki sözdizimi kurallarına uymalısınız: n n Yalnızca harf (büyük ve küçük). Herhangi bir dilde iyi bir program yazmanın püf noktası şudur: önce dilin sözdizimi ve anlambilimini öğrenmek ve daha sonra dili doğal ve deyimsel yolla kullanmaktır. Bu tanımlayıcılar anahtar sözcükler olarak adlandırılır ve her biri özel bir anlama sahiptir. Tanımlayıcıları Kullanmak Tanımlayıcılar (identifiers). programlarınızda ad alanları. result%. Bununla birlikte. Bunun anlamı şudur: boşluk karakteri ya da satır başı karakteri gibi boşluk karakterleri ayraç olmak dışında bir anlam ifade etmez. Kitap boyunca ilerledikçe. result. _score. . programlarınızın çok daha kolay okunmasını ve değiştirilmesini sağlar. ifadelerinizi istediğiniz stilde yazabilirsiniz. Diğer bir deyişle. rakam ve alt çizgi karakterini kullanabilirsiniz. “serbest biçimli” bir dildir. Bu yaklaşım. Kitapta bölümler boyunca. birçok C# anahtar sözcüğünün anlamını öğreneceksiniz. Önemli C# büyük küçük harfe duyarlı bir dildir: footballTeam ve FootballTeam aynı anlama gelen tanımlayıcılar değildir. Anahtar Sözcükleri Tanımlamak C# dili. footballTeam ve plan9 geçerli iken. bir harf ile (alt çizgi harf olarak kabul edilir) başlamak zorundadır. yöntemler ve değişkenler (birazdan değişkenlerin ne olduğunu öğreneceksiniz) gibi öğeleri tanımlamak için kullandığınız adlardır. Tanımlayıcı. footballTeam$ ve 9plan geçersiz tanımlayıcılardır. C# dilinde. basit ve tutarlı bir görünüm stili programın okunmasını ve anlaşılmasını kolaylaştırır. sınıflar. Anahtar sözcükler aşağıda listelenmiştir.

anahtar sözcükler. bir dükkandaki malların maliyet değerini depolamak istiyorsanız. Değişkeni. aşağıdaki tanımlayıcıları kullanır. maliyet değişkenine başvurduğunuzda elde edilen değer. kullanıldıkları ortamda değişkeni benzersiz olarak tanımlayan tek ve benzersiz bir ad vermek zorundasınız. Daha sonra. yani kendi yöntemleriniz. Örneğin. . Değişkeni tuttuğu değere göre adlandırabilirsiniz. siz yazdıkça mavi renk olarak görüntülenir. Programdaki her bir değişkene. Bu tanımlayıcılar C# tarafından kendi kullanımı için ayrılmamıştır. from get group into join let orderby partial select set value where yield Değişkenleri Kullanmak Değişken (variable) bir değeri tutan depolama konumudur. bilgisayarınızın belleğinde geçici bilgi tutan bir kutu gibi düşünebilirsiniz.Bölüm 2 Değişkenler. değişkenleriniz ve sınıflarınız için tanımlayıcı olarak bu adları kullanabilirsiniz. daha önce değişkende depolanan maliyet değeri olacaktır. fakat mümkün olduğunca bunu yapmaktan kaçınmalısınız. C# ayrıca. İşleçler ve Deyimlerle Çalışmak 31 abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while İpucu Visual Studio 2008 Code and Text Editor penceresinde. maliyet adında bir değişken yaratabilir ve malların maliyet değerini bu değişkende saklayabilirsiniz.

bu önerilere uymalısınız. Not Yalnızca küçük-büyük harf ayrımına bağlı olarak değişen tanımlayıcılar kullanmak. Bir değişkenin adını ve türünü bir tanımlama ifadesi içinde bildirirsiniz. bunları gerçekleştirilmesi zorunlu öneriler olarak düşünmelisiniz. Macar gösterim biçimini kullanmayın. aynı anda kullanılan iki değişkenden birini degiskenim olarak. depolayabileceği ve işleyebileceği çok sayıda farklı değer türüne sahiptir: tamsayı. ilk kelimeden sonra gelen kelimenin ilk harfini büyük yazın (Bu. C#. kayan nokta sayısı ve karakterler dizesi gibi. skor. futbolTakimi. n n Adı küçük harfle başlatın. içinde ne tür bir değişken tutacağını da belirtmelisiniz. Örneğin. _skor ve FutbolTakimi adlarının tümü geçerli bir değişken adıdır fakat sadece ilk ikisi önerilir. Macar gösterim biçimini bilmiyorsanız dert etmeyin!) Önemli Yukarda gösterilen ilk iki öneri Common Language Specification (CLS) (Ortak Dil Özellikleri) ile ilgili olduğundan. Bazı öneriler aşağıda listelenmiştir: n n Tanımlayıcılarda alt çizgi kullanmayın. Bir değişken bildirdiğinizde. Yalnızca küçük-büyük harf ayrımına bağlı olarak değişen tanımlayıcı yaratmayın.NET gibi diğer dillerle birlikte çalışan programlar yazmak istiyorsanız. int age. Değişkenleri Bildirmek Değişkenler değerleri tutar. age adında ve int (tamsayı) değerler taşıyan bir değişkeni bildirir. Birden fazla kelimeden oluşan tanımlayıcılarda. Macar gösterim biçimine aşina olabilir. . Microsoft Visual Basic . Örneğin. çünkü çok kolay karışıklığa neden olabilir. Her zamanki gibi. diğerini de Degiskenim olarak adlandırmayın. camelCase gösterim biçimi olarak bilinir). (Microsoft Visual C++ yazılım geliştiriciler.32 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Değişkenleri Adlandırmak Değişken tanımlamakta karışıklıktan kaçınmanıza yardımcı olan adlandırma kurallarına bağlı kalmalısınız. n Örneğin. aşağıdaki ifade. ifade sonunda noktalı virgül yer alır. Microsoft Visual Basic gibi küçük ve büyük harfe duyarlı olmayan diğer programlama dillerinde yazılan programlardaki sınıfları yeniden kullanabilmenizi engeller.

7 × 10308 ’e kadar 28 basamak Örnek Kullanım int count. away = 0.42M.42F. İşleçler ve Deyimlerle Çalışmak 33 int değişken türü. Aşağıdaki deyim.5 × 10 45 ’ten ±3. double trouble.4 × 1038 ’e kadar ±5. İpucu Visual Studio 2008 Code and Text Editor penceresinde fare işaretçisini bir değişkenin üzerinde tutarsanız. float away. (Bu bölümde daha sonra birkaç temel veri türünü öğreneceksiniz. Aşağıdaki deyim age değişkenine 42 değerini atar. trouble = 0. Tüm değişkenleri. değişkene bir değer atayabilirsiniz. decimal 128 decimal coin. coin = 0.0 × 10−324 ’ten ±1. Temel Veri Türleri ile Çalışmak C#.WriteLine(age). konsola age değişkeninin değeri olarak 42 yazar: Console. long wait. göreceğiniz gibi noktalı virgül gereklidir: age = 42. Eşittir işareti (=). değişkenin türünü gösteren bir ekran ipucu belirir. temel veri türleri olarak adlandırılan birkaç yerleşik türe sahiptir. sağ tarafındaki değeri sol tarafındaki değişkene atayan bir atama işlecidir. count = 42. .Bölüm 2 Değişkenler. kullanmadan önce açıkca (explicit) bildirmelisiniz. age değişkeni tuttuğu değere başvurmak için kodunuzda kullanılabilir. Bu atamadan sonra. Yine. C# dilinin kapalı (implicit) değişken bildirimlerini kabul etmediğine dikkat etmeleri gerekir.) Not Microsoft Visual Basic ile program geliştirenlerin.42. Veri Türü int long float double Açıklama Tam sayılar Tam sayılar (daha büyük aralık) Kayan noktalı sayılar İki kat daha hassas (daha fazla kesin) kayan noktalı sayılar Parasal değerler Boyut (bit) 32 64 32 64 Aralık1 –231 ’den 231 – 1’e kadar –263 ’ten 263 – 1’e kadar ±1. wait = 42L. C# dilinde en çok kullanılan temel veri türleri ve her birinde depolayabileceğiniz değer oranı listelenmiştir. Değişkeninizi bildirdikten sonra. temel C # türlerinden biri olan tamsayıdır. Aşağıdaki tabloda.

char grill.34 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Veri Türü string char bool Açıklama Karakter sıraları Tek karakter Boolean Boyut (bit) Karakter başına 16 bit 16 8 Aralık1 Geçersiz 0’dan 216 – 1’e kadar Doğru ya da yanlış Örnek Kullanım string vest. Visual Studio 2008’i başlatın. Open Project iletişim kutusu görüntülenir. Console. Open’ı işaret edin ve daha sonra Project/Solution’ı tıklayın. vest = “fortytwo”. 2. Bu. Örneğin. Atanmamış Yerel Değişkenler Bir değişken bildirdiğinizde. PrimitiveDataTypes çözüm dosyasını seçin ve Open’ı tıklayın. Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Bu koşul. teeth = false. Open Project‘i tıklayın. birkaç temel veri türünün nasıl çalıştığını göstermek için PrimitiveDataTypes adlı bir C# programı kullanacaksınız. . C ve C++ programlarında zengin bir hata kaynağıydı. grill = ‘x’. aksi takdirde programınız derlenmeyebilir. 3. bool teeth. aşağıdaki ifadeler. PrimitiveDataTypes projesini görüntüler. bir değişkenin yaratıldığı ve değişkene bir değer verilmeden önce yanlışlıkla bilgi kaynağı olarak kullanıldığı. Definite Assignment Rule (Kesin Atama Kuralı) olarak adlandırılır. File menüsünde. değer atanmamış değişkeni kullanmanıza izin vermez. değişkene bir değer atamak zorundasınız. Temel veri türlerinin değerlerini görüntüleyin 1. // derleme zamanı hatası Temel Veri Türü Değerlerini Görüntülemek Aşağıdaki alıştırmada. Belgeler klasörünüzde \Microsoft Press\ Visual CSharp Step by Step\Chapter 2\ PrimitiveDataTypes klasörüne gidin. age değişkenine bir değer atanmadığı için derleme hatası verecektir: int age. C#. Visual C# 2008 Express Edition kullanıyorsanız.WriteLine(age). File menüsü üzerinde. Bir değişkeni kullanmadan önce. siz değişkene bir değer atayana kadar rastgele bir değer içerir. Çözüm yüklenir ve Solution Explorer.

Bölüm 2 Değişkenler. Proje dosyaları. Start Without Debugging ’ı tıklayın. Window1. bir int değerini görüntülemek için gereken ifadelerin halen yazılmamış olduğunu gösteren to do değeri belirir. Denetim. “kırk iki” görünür. Choose a data type listesinde. herhangi bir yeri farenin sağ düğmesiyle tıklayın ve daha sonra View Code’u tıklayın. Window1. 4.xaml formunu gösteren Design View penceresinde. Çözüm dosyası bir ya da daha fazla proje içerir. Çözüm oluşturuyorsanız. Visual Studio 2008 otomatik olarak proje için yeni bir çözüm dosyası oluşturur. Aşağıdaki uygulama penceresi görüntülenir: 5.xaml ’i çift tıklayın. Design View penceresinde uygulama için WPF formu görüntülenir.xaml. . Sample value kutusunda. Çözüm değil de bir proje açarsanız. string türünü tıklayın. Visual Studio 2008 programlama ortamına döner.csproj uzantısına sahiptir. 8. Sample value kutusunda. PrimitiveDataTypes. Window1. . Temel veri türlerini kodda kullanın 1. İşleçler ve Deyimlerle Çalışmak 35 Not Çözüm dosyası. Listede int türünü tıklayın. Solution Explorer ’da.sln gibi. .cs dosyasını görüntüleyen Code and Text Editor penceresi açılır. 6. 7. Double ve bool türleri için de kodun tamamlanması gerektiğini doğrulayın. Pencereyi kapatmak ve programı durdurmak için Quit ’i tıklayın. 2. Visual Studio 2008 yeni oluşturulan ya da güncellenen dosyaları otomatik olarak kaydeder bu nedenle yeni çözüm dosyasını kaydetmek için konum ve ad belirlemek için bir uyarı alırsınız.sln uzantısına sahiptir. Debug menüsünde. Listedeki her bir veri türünü tıklayın.

Text özelliğine bir sayı atamaya çalışırsanız.) Text özelliğine yerleştirdiğiniz veri. İkinci ifade. programınız derlenmez. Bu yöntem aşağıdaki ifadeleri içerir: float variable.36 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Not Koda ulaşmak için ayrıca. fakat bunu yapabilmek için öncelikle C# ve Microsoft . Quick Replace iletişim kutusunu görüntülemek için Ctrl+H tuşlarına basabilirsiniz. İpucu Projenizde bir öğenin yerini bulmak için. diğer seçenekleri de deneyebilirsiniz. F ekini unutursanız. value. WriteLine ifadesini hatırlayın. Gerçek dünya uygulamasında. 0. (F. Quick Find iletişim kutusunu görüntülemek için.) Üçüncü ifade. İlk ifade float türünde.42F değerini atar.Text = “0. Metin kutusu içinde öğeyi görüntüleme yolu. tıklayın ve daha sonra Window1. (“Parametre Dizilerini Anlamak” başlıklı Bölüm 11’de ve “İşleç Aşırı Yüklemesi” başlıklı Bölüm 21’de veri türü dönüşümleri ele alınmıştır. Ne bulmak istediğinizi soran bir iletişim kutusu açılır.) . bir yöntemi çalıştırırken kullandığınız “nokta” gösterimi yoluyla eriştiğinize dikkat edin.42 değeri double olarak ele alınacak ve bir türdeki değişkene. Window1. form üzerinde value metin kutusundaki değişken değerini görüntüler. Find Options etiketi yanındaki artı düğmesini. aynı zamanda Ctrl+F (Control tuşunu basılı tutarken F tuşuna basarak) tuşlarına da basabilirsiniz. variable olarak adlandırılmış değişkeni bildirir. ifade metin kutusundaki “0. cs‘yi çift tıklayın.42F” metnini görüntüler. Varsayılan ayar olarak arama küçük ve büyük harfe duyarlı değildir. biraz dikkatli olmanızı gerektirir. Küçük-büyük harfe duyarlı bir arama yapmak istiyorsanız. showFloatValue yöntemini bulun. Zamanınız varsa. 3.xaml dosyasının solundaki artı işaretini. ilave kod yazmadan farklı türde bir değişken atayamayacağınız için –C# bu konuda çok katıdır– programınız derlenmeyecektir. +. Edit menüsü üzerinde Find and Replace’i işaret edin ve daha sonra Quick Find ’ı tıklayın. variable=0. Edit menüsünü kullanmak yerine. Liste kutusunda float türünü tıkladığınızda showFloatValue yöntemi çalışır.xaml. variable değişkeninin değerini dizeye çeviren ve daha sonra bu değeri Text özelliğine yerleştiren ifadeler ekleyebilirsiniz. tıklayın ve daha sonra Match Case onay kutusunu işaretleyin.42F”. Aynı şekilde. 0. float değer olarak ele alınması gerektiğini belirten bir sonektir. Bu programda. Nesnenin özelliklerine. (Bölüm 1’den Console. +. Bu ifade. sayı değil dize (çift tırnak içine alınmış karakterler dizisi) olmak zorundadır. variable değişkenine 0. Code and Text Editor penceresinde. öğenin Test özelliğini ayarlamaktır.42F. Aradığınız öğenin adını yazın ve daha sonra Find Next ’i tıklayın.NET Framework hakkında biraz daha fazla bilgiye sahip olmanız gerekir.42 değerinin. Solution Explorer ’ı da kullanabileceğinizi hatırlayın.

. açılış küme parantezinden sonra. “to do” dizesini “42” olarak değiştirin. bir yöntemi bulmanın bir diğer yolu. pencere üzerinde beliren Members sürükle bırak listesini tıklamaktır. Şöyle görünmelidir: private void showIntValue() { value. sıkı bir yazım denetimi yapar. İşleçler ve Deyimlerle Çalışmak 37 4. 7. showIntValue yönteminin yerini bulun.Text = “42”. Code and Text Editor penceresinde gösterilen class’daki tüm yöntemlerin (ve diğer öğelerin) listesini gösterir. Bununla birlikte. Code and Text Editor penceresinde. bu nedenle bu ifade derlenmez. Form tekrar görüntülenir. variable = 42. Code and Text Editor penceresinde doğrudan o üyeye götürülürsünüz.Text = variable. üçüncü ifadeyi şu şekilde değiştirmek isteyebilirsiniz: value.Bölüm 2 Değişkenler. İpucu Code and Text Editor penceresinde. Bu yöntem tam olarak şu şekilde görünmelidir: private void showIntValue() { int variable. Debug menüsünde. } 6. Bu pencere. value. 5. Bu yöntemdeki orijinal ifadede. } Liste kutusunda int türünü tıkladığınızda showIntValue yöntemi çağrılır. Bu ifade. showIntValue yönteminin başlangıcında.Text = “to do”. yeni bir satıra aşağıdaki kodda koyu olarak gösterilen iki ifadeyi yazın: private void showIntValue() { int variable. Sayısal ve dize değerleri arasında nasıl dönüşüm yapıldığını daha sonra bu bölümde göreceksiniz. C#. variable = 42. metin kutuları sadece string değerlerini ve variable değişkeninin int türünde olduğunu gösterebilir. form üzerindeki value metin kutusundaki variable değerini göstermeli gibi görünür. Üye adını tıklarsanız. } Not Programlama deneyimine sahipseniz. Start Without Debugging ’i tıklayın.

moneyPaidToConsultant = 750 * 20. Her bir durumda. showBoolValue yöntemini tam olarak aşağıdaki gibi değiştirin: private void showBoolValue() { bool variable. 11. } 14. Sample value metin kutusunda doğru değerin gösterildiğini doğrulayın.42.42”. Debug menüsü üzerinde. variable = 0. moneyPaidToConsultant (ücretDanışman) değişkeni 750 (günlük faiz) ve 20 (danışmanın çalıştığı gün sayısının) çarpımının sonucunu verir: long moneyPaidToConsultant. Pencereyi kapatmak ve programı durdurmak için Quit ’i tıklayın. Code and Text Editor penceresinde.Text = “0. Aşağıdaki örnekte. showBoolValue yöntemini bulun. 16. +. Choose a data type listesinde int türünü seçin. showDoubleValue yöntemini bulun. Aritmetik İşleçleri Kullanmak C#. variable = false. Code and Text Editor penceresinde. çıkarma için eksi işareti (-). küçüklüğünüzde öğrendiğiniz dört işlemin aritmetik işleçlerini destekler: toplama için artı işareti (+). işleçler olarak adlandırılır. Sample value metin kutusunda 42 değerinin gösterildiğini doğrulayın. Choose a data type listesinde. } 12. double ve bool türlerini seçin. 15. -. Programı durdurmak için Quit’i tıklayın. 10. int. * ve / simgeleri. showDoubleValue yöntemini tam olarak aşağıdaki gibi değiştirin: private void showDoubleValue() { double variable. value. . Start Without Debugging ‘i tıklayın. çarpma için yıldız (*) ve bölme için de (/) işareti. value.Text = “false”. yeni değerler yaratmak için değerler üzerinde “işlem” yaptığından. 13.38 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 8. 9.

ondalık sabit sayılar. İpucu . Dize değerlerini birleştirmek için + işlecini kullanabilirsiniz. 5/2 ifadesinin değeri 2’dir. artı işleci dışında aritmetik işleçleri kullanamazsınız. Beklenmeyen bir sonuç verebileceğinden.5’dur. Sonuç türü bu nedenle double (2. 750*20 deyiminde. C#. Çalışmakla birlikte. tür uyumsuzluğunu farkeder ve işlemi gerçekleştirmeden önce int türünü. Bununla birlikte. bu nedenle sonuç türü de double’ dır. float. double türüne dönüştüren kodu üretir.0 ifadesi.WriteLine(“Gillingham” – “Forest Green Rovers”). Bununla birlikte.0 ifadesinin değeri 2. dize değerini tamsayı değerine dönüştürmek için kullanabileceğiniz Int32.WriteLine(“43” + “1”).NET Framework. kullanılan işlenenler türüne bağlı olduğunu farketmiş olmalısınız. double ya da decimal veri türlerinde tüm aritmetik işleçlerini kullanabilirsiniz.Bölüm 2 Değişkenler. tüm veri türlerine uygulanamaz. aşağıdaki ifade konsola “431” (“44” değil) yazar: Console. türleri bu şekilde karıştırmak zayıf bir programlama olarak düşünülür. her iki işlenenin türü double’ dır (C#’de. 5/2. double ’dır). aritmetik işlem sonucundaki değer türünün. Bu defa. . string türü çıkarma işlecini desteklemediğinden aşağıdaki ifade derlenmez (bir dizenin diğer bir dizeden çıkarılması anlamsızdır): // derleme zamanı hatası Console. İşleçler ve Deyimlerle Çalışmak 39 Not İşlecin üzerinde işlem yaptığı değerler işlenen (operands) olarak adlandırılır. dizeler olarak tutulan değerler üzerinde aritmetik hesaplamalar yapmanız gerekirse. yani sonuç değeri de int türündedir. string ya da bool türü değişkenler üzerinde.0/2. mümkün olduğunca kesinlik sağlamak için. Örneğin. C# derleyicisi. Örneğin. 750 ve 20 de işlenendir. değerin türüne bağlıdır. Örneğin. dikkatli olmalısınız. char. int. Ayrıca.Parse adlı bir yöntem sağlar. Bir değer üzerinde kullanabileceğiniz işleçler. İşlenenlerin türünü karışık yaparsanız durum biraz daha karmaşık hale gelir. 5. Örneğin. long. int ve double veri türü içerir. her iki işlenen de int türündedir.5) olur. İşleçler ve Türler Tüm işleçler. bunun gibi koşullarda her zaman değerleri aşağıya yuvarlar. her zaman float değil. Bu nedenle. * işleç.

Ekranda bir form belirir. 3.2’dir.0 ifadesinin sonucu Infinity olur. bu durum için. NaN * 0 ifadesinin sonucu NaN iken. Aritmetik İşleçleri İncelemek Aşağıdaki alıştırma. 9’un 2’ye bölünmesi sonucu 4. double ve float türleri.0 ifadesinin sonucu NaN olur . bu dillerde float ya da double değerler üzerinde kalan işlecini kullanamayacağınızı bilirsiniz. “sayı değil” anlamına gelen ve NaN olarak adlandırılan diğer bir özel değere sahiptir.0 ifadesi sonucudur. . Bununla birlikte.0/0. kalan da 1 olduğundan. Infinity * 0 ifadesinin sonucu 0’dır. Belgeler klasörünüzdeki Microsoft Press\Visual CSharp Step By Step\Chapter 2\ MathsOperators dizinindeki MathsOperators projesini açın. 9 % 2 sonucu 1’dir. x’in y’e bölünmesi sonucunda kalan değerdir. Debug menüsünde Start Without Debugging ’i tıklayın.0 ifadesi bir paradoks olarak sonuçlanır (sonuç değeri sıfır olmalı ve aynı zamanda da sonsuz olmalıdır). Örneğin. Bu kurala istisna olarak.0/0. Kalan işleci.0 % 2. 2. sonsuzu göstermek için özel bir değere sahiptir ve 5. Bu nedenle 5/0 ifadesi hata verir. Bununla birlikte. Genellikle. x % y ifadesinin sonucu. fakat herhangi bir sayıyı sıfıra bölerseniz sonuç sonsuz olur. bu kuralı esnetir. 10 + Infinity ifadesinin sonucu da Infinity olur. Aritmetik işleçlerle çalışın 1. long ve decimal türlerinin aralıkları dışındadır. 7. Bu kurala tek istisna. tüm sayısal türlerde geçerlidir ve sonucun tamsayı olması gerekmez. 0.0/0. Örneğin. az bilinen bir aritmetik işleci destekler: yüzde işareti ile gösterilen kalan ya da mod işleci. daha önceden C# dilinde yazılmış MathsOperators adlı programı kullanarak aritmetik işleçlerin int değerler üzerinde kullanımını gösterir. C# ayrıca. sıfırı herhangi bir sayıya bölerseniz.0/0. left operand metin kutusuna 54 yazın. sonuç sıfır olur. 10 + NaN ifadesinin sonucu NaN.40 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Sayısal Türler ve Sonsuz Değerler C#’da sayıların bir ya da iki özelliği daha olduğunun farkına varmış olmalısınız. 0. NaN ve Infinity deyimler üzerinde yayılır. yani int. Not C ya da C++ diline aşinaysanız. C#. herhangi bir sayıyı sıfıra bölmenin sonucu sonsuzdur.4 ifadesinin sonucu 2. Yani. Örneğin. C#. 0.

Çünkü 54/13 işleminde kalan 2’dir. right operand metin kutusuna 13 yazın. (54 – ((54/13) * 13)) ifadesinde her aşamada aşağıya doğru yuvarlama yaparsanız sonuç 2 olur. Şimdi. Expression metin kutusundaki metin 54/13 olarak değişir ve Result kutusunda 4 değeri görünür.153846’dır. daha önce açıklandığı gibi. Expression metin kutusundaki metin 54-13 olarak değişir ve aşağıdaki resimde gösterildiği gibi. 54/13 sonucu 4. Expression metin kutusundaki metin 54 % 13 olarak değişir ve Result metin kutusunda 2 değeri belirir. Bitirdiğinizde. 5. bir tamsayıyı diğer bir tamsayıya böldüğünüzde sonuç değeri de tamsayıdır. % Remainder seçeneğini işaretleyip Calculate’i tıklayın. şok olurdu! 8. Gerçekte. 7. / Division seçeneğini işaretleyip Calculate ’i tıklayın. Diğer sayılarla işleçleri deneyin. Result kutusunda 41 değeri görünür. Şimdi metin kutularındaki değerlere herhangi bir işleci uygulayabilirsiniz. 6.Bölüm 2 Değişkenler. İşleçler ve Deyimlerle Çalışmak 41 4. Visual Studio 2008 programlama ortamına geri dönmek için Quit ’i tıklayın. MathsOperators programının koduna bir göz atalım. fakat C# tamsayı bölümünde. – Subtraction seçeneğini işaretleyip Calculate ’i tıklayın. Okuldaki yaşlı matematik öğretmenime (54/13) * 13 sonucunun 54 olmadığı söylense. .

Üçüncü ifade outcome adında bir int değişkeni bildirir. Design View penceresinde Window1.xaml. Document Outline penceresini kapatın. kullanıcının girdiği değerleri tutar . Form üzerinde. Window1. bu denetimlerin her birinin Text özelliği.xaml formunu görüntüleyin (Solution Explorer ’da Window1. 3.Text = lhsOperand. 7. 4. View menüsü üzerinden. kullanıcı türleri sayısındaki iki TextBox denetimini tıklayın. İkinci ifade. Document Outline penceresi belirir. rhs adı verilen bir int değişkeni bildirir ve rhsOperand metin kutusundaki değeri int türüne çevirdikten sonra başlagıç değeri olarak atar.Text. Other Windows ’u işaret edin ve daha sonra Document Outline’ı tıklayın. int outcome. result. Formun altına doğru.42 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş MathsOperators programının kodunu inceleyin 1.cs dosyasının kodunu. gerçekleştirilen deyimin.xaml dosyasını çift tıklayın). int veri türü tam olarak bunu yapan int. int rhs = int.Text).Parse(lhsOperand. Document Outline penceresinde denetim adı vurgulanır. expression. 2. outcome = lhs – rhs.ToString(). Document Outline penceresinde. int değişkenine atayabilmeniz için bu dizeyi tamsayıya çevirmeniz gerekir. 5. subtractValues yöntemini bulun. Şu şekilde görünür: private void subtractValues() { int lhs = int.Text + “ – “ + rhsOperand. bu nedenle.Text = outcome.Parse yöntemi sağlar. lhs adı verilen bir int değişkeni bildirir ve kullanıcı tarafından lhsOperand metin kutusunda girilen değere uygun tamsayı değeri ile başlatır. Form üzerindeki denetimlerin adını ve türünü gösteren. Metin kutusu denetiminin Text özelliğinin dize içerdiğini hatırlayın. Aynı şekilde.) Form çalıştığında. .Parse(rhsOperand. Form üzerindeki denetimlerin her birini tıklarsanız. lhsOperand ve rhsOperand olarak adlandırıldığını doğrulayın. Design View penceresinde de uygun denetim seçilir. (denetimin sağındaki parantezde denetimin adını görebilirsiniz. Code and Text Editor penceresinde. 6. Code and Text Editor penceresinde gösterin.Text). Document Outline penceresinde bir denetimi seçerseniz. } Bu yöntemdeki ilk ifade. deyim olarak ve hesaplama sonucunun sonuç olarak adlandırıldığını göstermek için TextBox denetiminin kullanıldığını doğrulayın.

Kendi sınıflarınızı yarattığınızda. ToString Yöntemi . bir nesneyi dize gösterimine dönüştürmektir.NET Framework’deki her sınıf. int türünün ToString yöntemi bunu yapar. toplama sonucu (2+3). önce toplama işlemini mi yoksa çarpma işlemini mi yaparsınız? Diğer bir deyişle. “Sınıflar ve Nesneleri Yaratmak ve Yönetmek” başlıklı Bölüm 7’de.Bölüm 2 Değişkenler. form üzerindeki expression metin kutusunda dizenin belirmesine neden olur. + ve * işleçlerini kullanan aşağıdaki deyimi düşünün: 2 + 3 * 4 Bu ifade belirsiz olmaya yatkındır. ToString yöntemine sahiptir. * işlecinin sol tarafındaki işleneni oluşturur ve tüm ifadenin sonucu 5*4. İşleçler ve Deyimlerle Çalışmak 43 Dördüncü ifade. n . gerçekleştirilen hesaplamayı gösteren üç dizeyi birleştirir (+. sınıfınızın dize olarak nasıl gösterileceğini belirlemek için ToString yönteminin nasıl uygulanacağını tanımlayabilirsiniz. Bu. result metin kutusunun Text özelliğinde değeri göstermek için bu dönüşüm gereklidir (Text özelliği sadece dizeler içerebilir). yani 14 olur. ToString yönteminin amacı. kendi sınıflarınızı yaratmak konusunda daha fazlasını göreceksiniz. hesaplama sonucunu result metin kutusunun Text özelliğine atamak yoluyla gösterir. outcome tamsayı nesnesinin ToString yöntemi. Text özelliğinin dize ve hesaplama sonucunun int olduğunu hatırlayın. yani 20 olur. çarpım sonucu (3*4). Önceliği Denetlemek Öncelik bir deyimdeki işleçlerin gerçekleştirilme sırasıdır. Altıncı ifade. bu nedenle dizeyi Text özelliğine atamadan önce int türüne çevirmeniz gerekir.Text özelliğine atar. outcome değişkeninin tamsayı değerini dize değerine dönüştürmek için kullanılmıştır. İlk olarak çarpma işlemini yaparsanız. Önceki örnekte. 3 değeri soldaki + işlecine mi yoksa sağdaki * işlecine mi bağlıdır? İşleçlerin sırası önemlidir çünkü sonucu değiştirir: n İlk olarak toplama işlemini yaparsanız. + işlecinin sağ tarafındaki işleneni meydana getirir ve tüm ifadenin sonucu 2+12. Beşinci ifade. lhs değişkeninin değerinden rhs değişkeninin değerini çıkarır ve sonucu outcome değişkenine atar. artı işlecini kullanarak) ve sonucu expression.

[ ] imleri ise köşeli parantez olarak adlandırılır. yani 4/12 olur. işlecin önceliği de açıklanacaktır. (4/2) sonucu * işlecinin solundaki işleneni meydana getirir ve tüm ifadenin sonucu (4/2)*6. / ve * işleçleri kullanan aşağıdaki ifadeyi düşünün: 4 / 2 * 6 Bu ifade de biraz belirsizdir. İşlemleri Gerçekleştirmek İçin Birleşim Özelliğini Kullanmak İşlem önceliği. (2*6) çarpımının sonucu. * işlecinin sol işlenenini meydana getirir ve sonuç 20 olur: (2 + 3) * 4 Not ( ) imleri parantez. Birleşim işlecin uygulanan işleneninin (sol ya da sağ) yönüdür. ilk olarak 4/2 işlemi yapılır. . Sonraki bölümlerde her bir işleç incelendikce. işleçlerin birleşimi. aşağıdaki ifadede. ifadenin nasıl gerçekleştirileceğini belirler. yani 12 olur. Örneğin. İlk önce çarpım işlemini yaparsanız. İlerleyen bölümlerde yeni işleçler incelendikce. birleşim önemli hale gelir. Bölme işlemini mi yoksa çarpma işlemini mi önce yaparsınız? Her iki işlecin de önceliği aynıdır (her ikisi de çarpma işlemi ile ilgili) fakat iki farklı sonuç elde edebileceğinizden hangi işlemin önce yapılacağı önemlidir: n İlk önce bölme işlemini yaparsanız. bu nedenle 2 + 3 * 4 gibi bir ifadede. {} imleri küme parantezi. n Bu durumda. Bu nedenle 2 + 3 * 4 ifadesinin sonucu 14’dür. yani işlenenler soldan sağa doğru işlem görür. daha sonra 6 ile çarpılır ve 12 sonucunu verir. * ve / işleçlerinin her ikisi de sola birleşim özelliği taşır. Aynı önceliğe sahip farklı işleçler içeren bir ifade olduğunda ne olacak? Bu noktada. parantez 2 ve 3 değerini + işlecine bağlanmaya zorlar (sonuç 5 olur) ve bu toplamanın sonucu. Bu örnekte.44 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş C#’da. ilk önce çarpma daha sonra toplama işlemi gerçekleştirilir. hikayenin sadece yarısıdır. çarpma işlemi ile ilgili işleçler (*. / ve %). Önceliği geçersiz kılmak ve işlenenleri işleçlere farklı şekilde bağlamak için ayraç kullanabilirsiniz. toplama ile ilgili işleçlere (+ ve -) göre önceliğe sahiptir. / işlecinin sağındaki işleneni meydana getirir ve tüm ifadenin sonucu 4/(2*6). birleşim özelliği de ele alınacaktır.

aynı zamanda myInt değişkenine atanan değerdir. bu teknik oldukça kullanışlıdır. C# dili sadece bu amaç için ayrı bir işleç sağlar: ++ işleci. Herhangi bir değişken daha önce bir değere sahipse. İlk olarak sağ taraftaki atama gerçekleşir ve atanan değer sağdan sola doğru değişkenler boyunca yayılır. myInt = 10. myInt2 değişkenine atanan değer.Bölüm 2 Değişkenler. Birkaç değişkeni aynı değerle başlatmak isterseniz. atama ifadesinin başka bir oluşumunda da aynı değeri kullanabilirsiniz: int myInt. Değişkenleri Artırmak ve Azaltmak Bir değişkene 1 eklemek isterseniz. sağ tarafındaki işlenen değerlendirilir ve daha sonra sol taraftaki işlenende depolanır. sol işlenene atanmış olan değerdir. atama işlecinin sağdan sola doğru birleşim özelliğine sahip olduğunu ortaya çıkarabilirsiniz. eşittir işareti (=) bir işleçtir. bir değişkeni 1 artırmak oldukça yaygındır. atanan değer üzerine yazdırılır. + işlecini kullanabilirsiniz: count = count + 1. atama işleci tarafından döndürülen değer 10’dur. tüm değişkenlerin aynı değerde olması gerektiği daha net anlaşılır: myInt5 = myInt4 = myInt3 = myInt2 = myInt = 10. Bununla birlikte. her iki değişkene de aynı değeri atar. int myInt. bunun oldukça hoş ve nadir bir şey olduğunu düşünebilirsiniz fakat ne işe yarar? Atama işleci bir değer döndürdüğünden. işlenenlerine bağlı olarak bir değer döndürür. . //atama ifadesinin değeri 10 Bu noktada. myInt2 = myInt = 10. Atama ifadesi. Kodunuzu okuyan birisi için. Tüm işleçler. İşleçler ve Deyimlerle Çalışmak 45 Birleşim ve Atama İşleci C# dilinde. İki işlenen alır. Atama işlecinin değeri. int myInt2. aşağıdaki atama ifadesinde. myInt değişkenine atanmış olan değerle aynıdır. Bu ifadeden. count değişkenini 1 artırmak için aşağıdaki ifadeyi yazabilirsiniz: count++. Örneğin. Atama işleci (=) de farklı değildir.

Örneğin: count++. Örneğin. bu nedenle x değeri değerlendirilmeden önce artırma işlemi gerçekleştirilir. neden iki farklı yazım biçimi olduğunu merak edebilirsiniz. ! birli işleci ile aynı önceliği ve sol birleşim özelliğini paylaşır. sadece tek bir işlenen alan anlamına gelen. C#. x = 42. // x şimdi 43’tür. 42 yazılır x = 42. işlenenin önek (prefix) biçimi olarak ve değişkenden sonra yer alması da sonek (postfix) biçimi olarak adlandırılır. değişkenden önce ve sonra yerleştirebilirsiniz. -—count. ++ ve – – simgelerinin işleç olduğunu ve tüm işleçlerin bir değere sahip deyimi değerlendirmek için kullanıldığını hatırlayın. Console. count--. 43 yazılır Önek ya da sonek ifadesinde. bir değişkenden 1 azaltmak için kullanabileceğiniz – işleci sağlar: count--. Bunun nedenini anlamak için. Bölüm 4. bu nedenle x artırılmadan önceki değeri deyimin değeri olarak kullanılır. ++count. ilk olarak işleç yer alır. ++x deyiminde. . yaygın olarak while ve do ifadelerinde kullanılır ve “Bileşik Atama ve Yineleme İfadelerini Kullanmak” başlıklı Bölüm 5’te gösterilmiştir. Console. artırma ve ––. count++ tarafından oluşturulan değer. değişkenin artırılması ya da azaltılmasında bir fark oluşturmaz. hangi işlenenin ne olduğunu hatırlamanın yolu. “Karar İfadelerini Kullanmak” bölümünde incelenen. ilk olarak x değişkeni yer alır. İşleç simgesinin değişkenden önce yer alması. count++ yazsanız da ++count yazsanız da. Artırma ve azaltma işleçlerini ayrı olarak kullanıyorsanız.46 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Benzer şekilde. Bir örnek verelim: int x. x++ deyiminde. // x şimdi 43’tür. öğelerin (işlenen ve işleç) sırasına bakmaktır. sonek biçimini tercih edin ve bu konuda tutarlı olun.WriteLine(x++). // // // // sonek artırma önek artırma sonek azaltma önek azaltma ++ ya da – – işlecinin önek ya da sonek biçimini kullanmak. Not ++ ve – işleçleri.WriteLine(++x). tekli işleçlerdir. count değişkeninin artırım gerçekleşmeden önceki değeridir oysa ++count tarafından oluşturulan değer sayının artırma gerçekleştirildikten sonraki değeridir. azaltma işleçlerini. Önek ve Sonek ++. Öyleyse. Bu işleçler. count değeri 1 artar.

int türünde değişkene sadece int türü değer atayabilirsiniz. aynı ifadede değişkeni bildirebilir ve başlangıç değeri atayabilirsiniz: int myInt = 99. değişkene atadığınız değerlerin türü. bir değişkende herhangi bir türde değer saklamak için kullanabileceğiniz Variant türüne aşina olabilirsiniz. Ayrıca. bir değişkene başlangıç değeri atamak için kullanılan ifadenin türünü hızlı bir şekilde ortaya çıkarabilir ve değişkenin türü ile aynı değilse size bildirebilir. myVariable ve myOtherVariable değişkenleri. değişken ile aynı türde olması gerektiğini hatırlayın. İşleçler ve Deyimlerle Çalışmak 47 Kapalı Türde Yerel Değişkenleri Bildirmek Bu bölümde daha önce. double ya da string değerler atayamazsınız. sadece değişken bildirmek için bir kolaylıktır ve değişken bildirildikten sonra değişkene sadece derleyicinin ortaya çıkardığı değeri atayabilirsiniz. Hatta. değişkene başlangıç değeri atamak için kullanılan ifadeden çıkarmasına neden olur. başlangıç değeri atanmış tamsayı değişken olduğunu varsayarsak. Aşağıdaki gibi. aşağıdaki gibi değişken bildirebilir ve başlangıç değeri atayabilirsiniz: int myInt = myOtherInt * 99. derleyicinin. Bu örneklerde. Bir değişkene atadığınız değerin. Anahtar sözcükler benzer görünmekle birlikte. değişkene başlangıç değeri atamak için kullanılan türden sonra değiştirilemez. kapalı türde değişkenler olarak adlandırılır. veri türü ve bir tanımlayıcı belirtmek yoluyla bildirildiğini görmüştünüz: int myInt. Aşağıdaki bildirim geçerli değildir ve derleme hatasına neden olur. // Hata – derleyici türü ortaya çıkaramadı Önemli Daha önce Visual Basic ile programlama yaptıysanız. aşağıdaki gibi. değişkenlerin türünü. myOtherInt değişkeninin. var anahtar sözcüğünü sadece. var yetAnotherVariable. C# dilinde var anahtar sözcüğünü kullanarak değişken bildirdiğinizde. Ayrıca. var ve Variant tamamen farklı şeylerdir. bulduğu türü kullanmasını isteyebilirsiniz: var myVariable = 99. var anahtar sözcüğü. değişkeni kullanmaya başlamadan önce değişkene bir değer atamanız gerektiğinden bahsedilmişti. C# derleyici. myVariable değişkeni int türünde ve myOtherVariable değişkeni de string türündedir. var myOtherVariable = “Hello”. .Bölüm 2 Değişkenler. Visual Basic ile programlama yaptığınız zaman Variant değişkenlerle ilgili öğrendiğiniz her şeyi unutmalısınız. bir değişkene başlangıç değeri atamak için bir ifade sağladığınızda kullanabilirsiniz. Örneğin. C# derleyicisinden bir ifadedeki değişkenin türünü bulmasını ve aşağıdaki gibi tür yerine var anahtar sözcüğünü kullanarak değişken bildirdiğinizde. bir değişkenin. Ayrıca. myVariable değişkenine float. Bu.

Bir değişkenin değerini değiştirmek Değişkenin adını sola yazın.Parse yöntemini çağırın.Int32.147.808’e eşittir. ardından atama işlecini yazıp sonra da değeri hesaplayan deyimi yazın. Save iletişim kutusunu görüyorsanız.536. sonuna da noktalı virgül ekleyin. n Bir sonraki bölümden devam etmek istiyorsanız. kapalı tür gerekli olana kadar değişken türünü açık bir şekilde belirtmeye devam edeceğiz.48 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş C# gibi düzenli bir dilin tasarımcılarının. var anahtar sözcüğünün C#’da geçerli bir yere sahip olduğunu göreceksiniz. Visual Studio 2008’i çalışır halde bırakın ve Bölüm 3’e geçin.775. sonuna da noktalı virgül ekleyin. Neticede.648.Parse(“42”). ilerleyen bölümlerin birçoğu üzerinde çalıştığınızda. Yes’i tıklayın (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayın (Visual C# 2008 Express Edition kullanıyorsanız) ve projeyi kaydedin. File menüsünde. Bununla birlikte.483.223.Int32. Örneğin: int outcome. Örneğin: myInt4 = myInt3 = myInt2 = myInt = 10. İşlenenleri belirli işleçlere zorlamak için deyimlerde ayraç kullanın. string ’i int ’e dönüştürmek Önceliği geçersiz kılmak System. bana güvenin. Örneğin: (3 + 4) * 5 Birkaç değişkene aynı başlangıç değerini atamak Bir değişkeni artırmak ya da azaltmak Tüm değişkenlere başlangıç değeri atayan atama ifadesini kullanın. Bununla birlikte. Örneğin: outcome = 42. neden bu dilde var anahtar sözcüğü gibi bir özelliğin var olmasına izin verdiğini merak ediyor olabilirsiniz. ++ ya da – – işleçlerini kullanın. 231 değeri 2.036. Örneğin: System. Örneğin: count++. Exit’i tıklayın. (Dipnotlar) 1 216 değeri 65. bir kısım programcı tarafından aşırı tembellik mazereti gibi görünür ve programın ne yaptığını anlamayı ve hataları bulmayı zorlaştırabilir (hatta kodunuza yeni hatalar bile getirebilir). n Bölüm 2 Hızlı Başvuru Bunun İçin Bir değişken bildirmek Şunu Yapın Türün adını sonra da değişkenin adını yazın. şimdilik. Visual Studio 2008’den şimdi çıkmak istiyorsanız.854. .372. ve 263 değeri 9.

yöntemin. Yöntem adı. işlemek üzere veri alır ve işleminin sonucu olan verileri döndürür. bir yönteme bilgi aktarmak için bağımsız değişkenler ve parametreleri kullanmayı ve return ifadelerini kullanmak yoluyla yöntemden bilgi almayı öğreneceksiniz. Yöntemden bilgi almak. Birçok yöntem. yöntemleri öğreneceksiniz. Son olarak. adlandırılmış ifadeler grubudur. yöntem çağrıldığında çalışacak olan gerçek ifadeleri içerir. “Değişkenler. Yöntemler temel ve güçlü mekanizmalardır. Yöntemler çalışırken yöntem içine girmek ve yöntem içinden çıkmak için tümleşik hata ayıklayıcıyı kullanmak. Yöntem gövdesi. Bu.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n Yöntemleri bildirmek ve çağırmak. Daha önce C ya da Microsoft Visual Basic ile programlama yaptıysanız. 49 . Ayrıca. Yerel ve sınıf kapsamı tanımlamak. Microsoft Visual Studio 2008 tümleşik hata ayıklayıcıyı kullanarak yöntemlerin içlerine girmeyi ya da çıkmayı göreceksiniz. yöntemin tüm amacını gösteren anlamlı bir tanımlayıcı olmalıdır (örneğin. İşleçler ve Deyimlerle Çalışmak” başlıklı Bölüm 2’de. değişkenleri bildirmeyi. Yöntemleri Bildirmek Yöntem (method). Yönteme bilgi geçirmek. CalculateIncomeTax (GelirVergisi Hesapla)). beklediğiniz gibi çalışmadıklarında yöntemlerinizin işleyişlerini izlemek için çok yararlı olabilir. işleçler kullanarak deyimler yaratmayı ve birden fazla işleç içeren deyimlerde öncelik ve birleşim denetimini öğrendiniz. Bu bölümde. işlev ya da alt yordama oldukça benzer olduğunu bilirsiniz.

. Şimdilik. bir türün adıdır ve yöntemin işlem sonucu olarak döndüreceği bilgi türünü belirler. Örneğin. arasında yer alırlar. methodName. Herhangi bir değer döndürmeyen bir yöntem yazıyorsanız.. yöntem çağrıldığında çalıştırılacak olan kod satırlarıdır. örneğin. parantez içinde değişken bildiriyormuş gibi yazarsınız. int ya da string gibi. isteğe bağlıdır ve işlemesi için yönteme verebileceğiniz bilginin adlarını ve türlerini tanımlar. } Not Yöntemin dönüş türünü ve parametrelerin türünü açık bir şekilde belirtmeniz gerekir. var anahtar sözcüğü kullanamazsınız.50 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Yöntem Bildirme Sözdizimini Belirlemek Microsoft Visual C# yönteminin sözdizimi aşağıdaki gibidir: returnType methodName ( parameterList ) { // yöntem gövde ifadeleri buraya gelir } n returnType. // yöntem gövde ifadeleri buraya gelir // . displayCustomer . Yöntem adları da değişken adlarının uyması gereken tanımlayıcı kurallarına uymalıdır. C#'ın genel yöntemleri desteklemediğine dikkat etmeliler. n n n Önemli C. dönen tür yerine void anahtar sözcüğünü kullanmanız gerekir... leftHandSide (sol taraf) ve rightHandSide (sağ taraf) adlı iki int parametre alan ve bir int döndüren addValues adlı yöntemin tanımı aşağıdaki gibidir: int addValues(int leftHandSide. addValues (ekleDeğerler) adı geçerli bir yöntem addır fakat add$Values geçerli bir ad değildir. { }. Parametreleri. int rightHandSide) { // . method body statements (yöntem gövde ifadeleri). parameterList. . C++ ve Microsoft Visual Basic ile program geliştirenler. Bu. yöntem adları için camelCase kuralına uymalısınız. herhangi bir tür olabilir. parametreleri virgülle ayırmanız gerekir. önce tür adı daha sonra da parametre adı olacak biçimde. Yazdığınız yöntem iki ya da daha fazla parametreye sahip olacaksa. Kodunuzun derlenebilmesi için tüm yöntemlerinizi bir sınıf içinde yazmanız gerekir. Küme parantezleri. yöntemi çağırmak için kullanılan addır.

return.. derleyici sizi uyarır).. } return ifadesi. yöntem içinde bir return ifadesi yazmalısınız. yöntemden çıkmak için return ifadesinin farklı bir biçimini kullanabilirsiniz. } . dönüş türü void ise). return anahtar sözcüğünden sonra. } Yöntemin bir değer döndürmediğini göstermek için void anahtar sözcüğünün kullanıldığına dikkat edin. yöntemin bitmesine neden olduğundan. Deyimin türü.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 51 Sadece answer (yanıt) adında int parametre alan ve bir değer döndürmeyen showResult (gösterSonuç) yönteminin tanımı ise şöyledir: void showResult(int answer) { // .. return İfadeleri Yazmak Yönteminizin bir bilgi döndürmesini istiyorsanız (başka bir deyişle dönüş türünün void olmasını istemiyorsanız). return leftHandSide + rightHandSide. Önemli Visual Basic ile program geliştirenler.. programınız derlenmez. Örneğin: void showResult(int answer) { // yanıtı görüntüle . yöntem bir int türü döndürüyorsa. aksi takdirde. genellikle yöntemin sonunda yer alır.. Her zaman bir dönüş türü belirtmeniz ya da void anahtar sözcüğünü kullanmanız gerekir. dönen değeri hesaplayan deyim ve sonunda noktalı virgül yer alır. return ifadesi de int türü döndürmelidir. Yönteminizin bir değer döndürmesini istemiyorsanız (diğer bir deyişle.. int rightHandSide) { // . Örneğin: int addValues(int leftHandSide. return anahtar sözcüğünden sonra noktalı virgül yazarsınız. yöntem tarafından belirtilen dönüş türü ile aynı olmak zorundadır. Diğer bir deyişle. C#’ın değer döndüren (işlev) ve değer döndürmeyen (yordam ya da altyordam) yöntemleri birbirinden ayırmak için farklı anahtar sözcükler kullanmadığına dikkat etmeliler. return ifadesinden sonra yer alan herhangi bir ifade çalıştırılmaz (return ifadesinden sonra herhangi bir ifade yazarsanız.

Code and Text Editor penceresinde Window1. leftHandSide ve rightHandSide int değişkenlerinin değerlerini toplamak için + işlecini kullanır ve işlemin sonucunu döndürür. Debug menüsünde. divideValues ve remainderValues yöntemlerine bakarsanız. Code and Text Editor penceresinde. Aşağıdaki alıştırmada. Visual Studio 2008.ToString() + “ + “ + rightHandSide. form üzerindeki expression metin kutusunda yapılan hesaplamayı gösterir. Bu uygulama yaygın olmakla birlikte. 6.ToString(). 3. Bu sürüm. int rightHandSide) { expression. yani addValues yönteminin dönüş türü de int olur .52 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Yönteminiz herhangi bir şey döndürmüyorsa. İkinci ifade. Yöntem şu şekilde görünmelidir: private int addValues(int leftHandSide. İlk ifade. } addValues yöntemi iki ifade içerir. çünkü sondaki küme parantezi kapatma işaretine ulaştığında yöntem otomatik olarak sonlanır. 5. Yöntem tanımlamalarını inceleyin 1. 2. aynı şekilde olduğunu görürsünüz. uygulamayı oluşturur ve çalıştırır. subtractValues. .Text = leftHandSide. 4. addValues yöntemini bulun. bazı küçük yöntemlerin dikkatlice kullanımıyla geliştirilmiştir. Start Without Debugging ’i tıklayın. Uygulamanın nasıl çalıştığını deneyin ve daha sonra Quit ’i tıklayın. iyi bir kullanım şekli değildir. Documents klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\ Chapter 3\Methods klasöründeki Methods projesini açın. İki int değerinin toplanmasının başka bir int değer oluşturduğunu hatırlayın. return ifadesini yazmayabilirsiniz. multiplyValues.xaml.cs için kodu görüntüleyin. Bölüm 2’deki MathsOperators uygulamasının farklı bir sürümünü inceleyeceksiniz. return leftHandSide + rightHandSide. Visual Studio 2008’i başlatın. leftHandSide ve rightHandSide parametrelerinin değerleri dizelere çevrilir (Bölüm 2’de gördüğünüz ToString yöntemi kullanılarak) ve ortasında (+) işlevinin string gösterimi ile birbirine bağlanır.

fakat genellikle yönteminizin kodunu. Yöntem bir bilgi döndürüyorsa (dönüş türü ile belirtildiği gibi). Yöntemin Çağrılma Sözdizimini Belirlemek Bir C# yönteminin çağrılma sözdizimi şu şekildedir: result = methodName ( argumentList ) n methodName tam olarak çağırdığınız yöntemin adı olmalıdır. Yöntem bilgi gerektiriyorsa (parametreleriyle belirtildiği gibi). Yöntem void ise (bir sonuç değeri döndürmüyorsa). verileri istendiği gibi sunmalısınız. Yöntemleri Çağırmak Yöntemler çağrılmak için vardır! Bir yöntemi. bu bilgiyi bir biçimde yakalamalısınız.Text = answer. Code and Text Editor penceresinde. görevini gerçekleştirmesi için adını kullanarak çağırırsınız. result = cümlesi isteğe bağlıdır. argumentList (bağımsızdeğişkenListesi) yöntemin alacağı isteğe bağlı bilgiyi sağlar. showResult yöntemi şu şekilde görünür: private void showResult(int answer) { result.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 53 7. Bir yöntem için aynı zamanda maksimum uzunluk sınırlandırması da yoktur. result (sonuç) olarak tanımlanmış değişken. Eğer kullanılmışsa. Unutmayın. result metin kutusunda answer parametresinin string gösterimini gösteren bir ifade içerir. Eğer bir yöntem tekrarlamadan kaçınmanıza yardımcı oluyorsa ve programınızı daha kolay anlaşılır hale getiriyorsa. n n . bağımsız değişkenleri virgülle ayırmalısınız. C# büyük küçük harfe duyarlıdır. işlevini yerine getirmeye yetecek uzunlukta tutmak istersiniz.ToString(). } Bu yöntem. ne kadar küçük olursa olsun yöntem kullanışlıdır. showResult yöntemini bulun. yöntemden dönen değeri içerir. ifadeden result = cümlesini çıkarmalısınız. İpucu Bir yöntem için minimum uzunluk sınırlaması yoktur. Her parametre için bir bağımsız değişken vermeniz gerekir ve her bağımsız değişkenin değeri kendine karşılık gelen parametrenin türüne uygun olmalıdır. Çağırdığınız yöntemin iki ya da daha çok parametresi varsa.

bu proje zaten Visual Studio 2008’de açık olmalı. (Bir önceki alıştırmadan devam ediyorsanız. Açık değilse. hatası.54 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Önemli Yöntemleri bağımsız değişkenler olmadan çağırsanız bile. addValues(). } addValues yönteminin iki adet int parametresi vardır. int türünde bir değer döndürür.. showResult(addValues(39. addValues yöntemine tekrar bakalım: int addValues(int leftHandSide. addValues(39). hatası.) 2. aşağıda tanımlanan nedenlerden dolayı başarılı olamazsınız: addValues. 3). Aşağıda gösterildiği gibi.. aşağıdaki gibi bağımsız değişkenler olarak yönteme verilir: int arg1 = 99. 3). her yöntem çağrılışında parantezleri yazmalısınız. int arg2 = 1. Code and Text Editor penceresinde Window1. int değerlerin kullanılabileceği her yerde kullanılabilir. // okay 39 ve 3 değerlerini iki int değişkenine atayabilirsiniz. Belgeler klasöründeki \Microsoft Press\ Visual CSharp Step by Step\Chapter 3\Methods klasöründen açın.xaml. Bu noktaları netleştirmek için. Bu defa. “3”).cs için kodu görüntüleyin. bazı yöntem çağrılarını inceleyeceksiniz. Bu değişkenlerdeki değerler daha sonra. parantez yok yetersiz bağımsız değişken yetersiz bağımsız değişken yanlış türler addValues yöntemi. arg2). // bir atamanın sağ tarafında // başka bir yöntem çağrısında bağımsız değişken olarak Aşağıdaki alıştırma. hatası. int rightHandSide) { // . addValues yöntemini farklı şekillerde çağırırsanız. addValues(“39”. Örneğin: int result = addValues(39. Yöntem çağrılarını inceleyin 1. Methods uygulamasına bakmaya devam ediyor. Methods projesine dönün. . addValues(arg1. bu nedenle bu yöntemi virgülle ayrılmış iki int bağımsız değişkenle çağırmalısınız: addValues(39. 3)). Bu int değer. // // // // derleme derleme derleme derleme zamanı zamanı zamanı zamanı hatası.

Text). calculateClick yöntemindeki dördüncü ifadeye bakın (if ifadesinden ve diğer açılan parantezden sonra): calculatedValue = addValues(leftHandSide.Text).ToString() deyimi. Bu yöntemi daha önce gördünüz. Bu iki kod satırı.Int32. 6. showResult yöntemini çağırır. answer nesnesine ait ToString yöntemini çağırır. rightHandSide). Code and Text Editor penceresinde daha önce incelediğiniz showResult yöntemini bulun. nesnenin adını yöntem adının önüne ekleyerek çağırabilirsiniz. calculatedValue değişkenindeki değeri bağımsız değişken olarak yönteme geçirir. 4. İpucu Diğer nesnelere ait olan yöntemleri. calculateClick yöntemini bulun ve try ifadesinden ve açılan parantezden sonraki ilk iki ifadeye bakın. (try ifadelerinin amacını. Int32 sınıfının Parse yöntemi çağrılır (System. leftHandSide ve rightHandSide adında iki int değişkeni bildirir. Bu ifade.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 55 3. Bu iki ifade. addValues yöntemi tarafından döndürülen değer. Her iki durumda da.Int32. Bu yöntemin tek ifadesi şudur: result. Bir sonraki ifadeye bakın: showResult(calculatedValue).ToString(). answer.Parse(lhsOperand. “Hataları ve Özel Durumları Yönetmek” başlıklı Bölüm 6’da ele aldık. .) İfadeler aşağıdaki gibidir: int leftHandSide = System. Ama. calculatedValue değişkeninde saklanır. bağımsız değişkenler olarak yönteme geçirir. ilginç olan kısım değişkenlere başlangıç değeri atanma yollarıdır. 5. Önceki örnekte. ToString yönteminin bağımsız değişkeni olmadığı halde parantezler kullanılarak çağrıldığına dikkat edin. tek bir string parametresi alır ve int değerine dönüştürür. kullanıcının form üzerindeki lhsOperand ve rhsOperand metin kutularına yazdıklarını alır ve int değerlerine dönüştürür.Parse(rhsOperand.Text = answer. System. showResult yöntemi bir değer döndürmez. ad alanıdır ve Int32 ise bu ad alanındaki sınıfın adıdır). int rightHandSide = System. Bu ifade addValues yöntemini çağırır ve leftHandSide ve rightHandSide değişkenlerinin değerini.

kendi kapsamında olmayan myVar (benimDeğişkenim) değişkenini kullanmaya çalıştığından. öğreneceğiniz gibi. } void anotherMethod() { myVar = 42. bu değişkenler ortadan kalkar. bir değişkenin kapsamı. } } anotherMethod (başkaYöntem). yöntem bittiğinde ortadan kalkarlar ve sadece o yöntemde çalışan kod ile erişilebilirler. Kapsam. o yöntemin kapsamına eklenir. kapsamı tanımlar. Örneğin: class Example { void firstMethod() { int myVar. bu kodun derlemesi başarısızlıkla sonuçlanacaktır.. Yöntem tamamlandığında. o tanımlayıcıyı program içinde tanımlayan bildirimin yeri ile bağlantılıdır. Bir yöntemin gövdesi içinde bildirdiğiniz bütün değişkenler. Tanımlayıcının (değişken ya da yöntemin) kapsamı. Bu değişkenler tanımlandıkları yerde yaratılırlar ve aynı yöntemdeki sonraki ifadeler bu değişkenleri daha sonra kullanabilir. yerel değişkenleri yöntemler arasında bilgi paylaşımı için kullanamayacağınız anlamına gelir. değişkenin o program içinde kullanılabildiği bölgedir. // hata – değişken kapsamda değil . Sınıf gövdesi içinde (fakat bir yöntem içinde değil) bildirdiğiniz bütün değişkenler.56 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Kapsam Uygulamak Bazı örneklerde. Başka bir yöntemin kapsamı içinde değillerdir. değişkenler için olduğu gibi yöntemler için de geçerlidir. değişken o konumda kapsam (scope) içindedir. bu değişkenler yerel değişkenler olarak adlandırılır. Bu düzenleme. o sınıfın .. . myVar değişkeni sadece firstMethod (ilkYöntem) ifadesinde geçerlidir ve myVar değişkenini bildiren kod satırından sonra ortaya çıkar. yöntem içinde değişken yaratabileceğinizi görebilirsiniz. Farklı bir biçimde ifade etmek gerekirse.. programda belirli bir konumda kullanılabiliyorsa. Değişken yaratıldıktan hemen sonra kullanılabilir. Bildirildikleri yöntem için yerel olduklarından. Sınıf Kapsamını Tanımlamak Bir sınıfın gövdesini oluşturan açılan ve kapanan küme parantezleri de bir kapsam oluşturur.. Bir değişken. Yerel Kapsamı Tanımlamak Bir yöntemin gövdesini oluşturan açılan ve kapanan küme parantezleri.

aşırı yüklü (overloaded) oldukları söylenir. Yerel değişkenlere rağmen. aynı sınıf içinde aynı adla iki alan ya da aynı sınıf içinde tümüyle aynı iki yöntem bildirirseniz yine derleme zamanı hatası alırsınız.. aynı yöntem içinde aynı adla iki yerel değişken bildirirseniz. Console sınıfının WriteLine yöntemini düşünün. Alanlar biraz farklıdır.. Bir tanımlayıcıyı aşırı yüklemenin hem yararı hem de önemli bir yöntemi vardır. Bu örnek ile ilgili bir başka önemli nokta daha var. Sınıf tarafından tanımlanmış değişkenler C#’da en uygun olarak field (alan) olarak adlandırılır. Yöntemleri Aşırı Yüklemek İki tanımlayıcı aynı ada sahipse ve aynı kapsam içinde bildirildilerse. Bununla birlikte. sınıf içinde fakat firstMethod ve anotherMethod yöntemleri dışında bildirilmiştir. bir diğeri bool parametre alır ve parametre değerinin dize gösterimi sonucunu verir. yöntemler arasında bilgiyi paylaşmak için alanları kullanabilirsiniz. } int myField = 0. Örneğin: class Example { void firstMethod() { myField = 42.. alanı tanımlayan ifadeden önce. } myField (benimAlanım) değişkeni.. Daha önce ekrana bir dize çıktısı görüntülemek için bu yöntemi kullandınız. // tamam . o alanı kullanabilir (derleyici detayları sizin için düzenler!). Bir yöntem. Bir yöntemde. derleme zamanı hatası olarak yakalanan bir hatadır. Benzer şekilde. Çoğunlukla aşırı yüklü bir tanımlayıcı. myField değişkeni sınıf kapsamına sahiptir ve sınıf içindeki tüm yöntemler tarafından kullanılabilir. Örneğin. Bu nedenle. C# kodu yazarken Code and Text Editor penceresinde WriteLine yazdığınızda. } void anotherMethod() { myField++. derleme zamanı hatası alırsınız.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 57 kapsamındadır. IntelliSense’ın size 19 farklı seçenek sunduğuna dikkat edin! WriteLine yönteminin her bir sürümü farklı parametre kümesi alır. bir sürüm hiç bir parametre almaz ve boş bir satır sonucu verirken. başka bir sürüm de decimal (ondalık) . tüm bunların söz etmeye değmeyecek şeyler olduğunu düşünebilirsiniz. // tamam . Şimdiye dek her şeyin bir derleme zamanı hatası olduğunu düşünürsek. kullanmadan önce değişkeni bildirmeniz gerekir.

) . Solution Explorer’da.WriteLine(42). 2. } Aşırı yükleme öncelikle. Uygulama mantığını geliştirmekle başlayacak ve daha sonra bu mantıkta kullanılan yöntemleri yazmanıza yardımcı olması için Generate Method Stub Wizard kullanacaksınız. Aşırı yüklenmiş yöntemlerden birini seçmek için bağımsız değişken sayısı ve türleri derleyici tarafından kullanılır. noOfDays)). Console. Parantez arasındaki run yönteminin gövdesine aşağıdaki ifadeleri ekleyin: double dailyRate = readDouble(“Enter your daily rate: “).) Yöntemler Yazmak Aşağıdaki alıştırmalarda. Code and Text Editor penceresinde. Derleme zamanında. bir yöntem çağırdığınızda. “Sınıflar ve Nesneleri Yaratmak ve Yönetmek” başlıklı Bölüm 7’de inceledik. Bu güç ile. aynı işlemi farklı veri türleri üzerinde gerçekleştirmeniz gerektiğinde kullanışlıdır. başka bir deyişle. yöntemler çalışırken içlerine girmek ve çıkmak için Visual Studio 2008 hata ayıklayıcıyı kullanacaksınız. sabit bir günlük oranla çalışan bir danışmana belirli sayıda gün çalıştığında ne kadar ödeme yapılacağını hesaplayan bir yöntem yaratacaksınız. 3. (Çağrılış yolunu anlamak için sınıfların anlaşılması gerekir. yalnızca dönüş türleri farklı olan aynı ada sahip iki yöntem bildiremezsiniz (Derleyici akıllıdır. Bu konuyu. Diğer bir deyişle. Program. int noOfDays = readInt(“Enter the number of days: “). writeFee(calculateFee(dailyRate. programı anlamak için Konsol uygulamasında bu yöntemleri çalıştıracaksınız. Örneğin: static void Main() { Console. Son olarak.WriteLine(“The answer is “). Main yöntemi tarafından run yöntemi çağrılır.cs dosyasını çift tıklayın. program kodunu görüntülemek için. Uygulama mantığını geliştirin 1. Bununla birlikte. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 3\DailyRate klasöründe yer alan DailyRate projesini açın. virgülle ayrılmış bağımsız değişkenler listesi sağlayabilirsiniz.58 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş parametre alır ve dizi olarak sonuç verir. yöntemin parametrelerini aşırı yükleyebilmenize karşın yöntemin dönüş türünü aşırı yükleyemezsiniz. aynı ada fakat farklı parametre sayısına sahip olduklarında ya da parametre türleri farklı olduğunda. Daha sonra. Farklı uygulamalar farklı parametre kümelerine sahip olduğunda yöntemi aşırı yükleyebilirsiniz. Uygulama başladığında. fakat o kadar da değil. Visual Studio 2008’i kullanarak. derleyici yönteme verdiğiniz bağımsız değişken türlerine bakar ve daha sonra parametre kümesine uygun olan yöntemi çağırır.

kodu üretmek ve düzenlemek için yararlı komutlar içeren kısayol menüsü görünür. Sonraki ifade. Code and Text Editor penceresinde. Henüz uygulamayı oluşturmaya çalışmayın.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 59 run yöntemine eklediğiniz kod bloğu. günlük oran ve gün sayısını alarak ödenecek toplam ücreti hesaplayan calculateFee yönteminden (yazmanız gereken son yöntem) dönen değer olduğuna dikkat edin. readInt. gün sayısını elde etmek için readInt yöntemini (bunu da yazacaksınız) çağırır. run yöntemindeki readDouble yöntem çağrısını farenin sağ düğmesiyle tıklayın. danışmanın günlük ücret oranını kullanıcıya sormak için readDouble yöntemini (bu yöntemi yazacaksınız) çağırır. Kısayol menüsünde. Aşağıda gösterildiği gibi. bu kodu yazdığınızda IntelliSense bu yöntemleri göstermez. writeFee yöntemine verilen değerin. Generate Method Stub’ı tıklayın. Son olarak. Not Henüz readDouble. Generate Method Stub Wizard kullanarak yöntemleri yazın 1. bu nedenle. 2. . sonuçları ekranda görüntülemek için writeFee yöntemi (yöntem yazılmıştır) çağrılır. başarısızlıkla sonuçlanır. writeFee ya da calculateFee yöntemlerini yazmadınız.

hemen NotImplementedException (özel durumlar Bölüm 6’da tanımlanmıştır) oluşturur. } .WriteLine ifadesi ile aynıdır.Parse(line).Parse yöntemi kullanılarak double türüne dönüştürülür. return double. Aşağıdaki gibi. Not Console. parametrelerini ve dönüş değerinin türünü öğrenir ve varsayılan uygulama ile yöntemi üretir: private double readDouble(string p) { throw new NotImplementedException(). 3. readInt yöntemi oluşturulur: private int readInt(string p) { throw new NotImplementedException(). ekrana p değişkenindeki dize çıktısını verir. Bu kod bloğu. } Yeni yöntem. readDouble yönteminin çağrılmasını denetler. Bölüm 7’de açıklanan private tanımlandırıcı ile yaratılmıştır. 4. çağrılan yöntemin dönüş değeri olarak verilir. yöntem çağrıldığında yönteme verilen dize türü parametredir ve kullanıcıdan günlük oranı girmesini isteyen iletiyi içerir. readDouble yönteminden throw new NotImplementedException(). ifadesini silin ve aşağıdaki kod satırını yazın: Console. kullanıcının Enter tuşuna basana kadar klavyeden girdiği karakterleri okur.60 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Generate Method Stub Wizard. Kullanıcı bir değer yazar. daha önceki alıştırmalarda kullandığınız Console.ReadLine().Write(p). Bir sonraki basamakta. iletiden sonra yeni satır karakteri olmaması dışında. Bu değişken. run yönteminde readInt yönteminin çağrısını farenin sağ düğmesiyle tıklayın ve daha sonra readInt yöntemini oluşturmak için Generate Method Stub’ı tıklayın. string line = Console.Write yöntemi. yöntem gövdesini kendi kodunuzla değiştireceksiniz. Yöntem gövdesi. Not ReadLine yöntemi WriteLine yöntemine benzerdir. Bu değer ReadLine yöntemi tarafından string türü olarak okunur ve double. Kullanıcı tarafından girilen metin dönüş değeri olarak verilir. Sonuç.

7.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 61 5. Bu kod bloğu.ReadLine(). Bölüm 7’de object türü hakkında daha fazlasını öğreneceksiniz. Aşağıda koyu renk olarak gösterildiği gibi. } 8. bu yöntem int değeri döndürür. Tek fark. calculateFee yöntemini. object türü sadece “bir tür” anlamındadır ve bunu yönteme kod eklerken istediğiniz tür ile değiştirmelisiniz. return int. calculateFee yöntemi oluşturulur: private object calculateFee(double dailyRate. 6. Aşağıdaki gibi.) Daha ilginç olanı. run yönteminde calculateFee yönteminin çağrısını farenin sağ düğmesiyle tıklayın ve daha sonra Generate Method Stub’ı tıklayın. yöntemden dönen değer türünün object olmasıdır.Write(p). 9. yani kullanıcının klavyeden girdiği string türü değer. readInt yöntemindeki throw new NotImplementedException(). int noOfDays) { throw new NotImplementedException(). çağrılan içerikten yöntem tarafından döndürülecek değer türünün ne olması gerektiğini tam olarak hesaplayamaz.Parse(line). (Elbette. readDouble yöntemi kodu ile benzerdir. ifadesini aşağıdaki kod ile değiştirin: Console. Generate Method Stub Wizard. run yönteminde writeFee yönteminin çağrısını farenin sağ düğmesiyle tıklayın ve daha sonra Generate Method Stub’ı tıklayın. int. uygun olmayan parametre adlarını değiştirebilirsiniz. string line = Console. double türü döndürecek şekilde değiştirin: private double calculateFee(double dailyRate.Parse yöntemi kullanılarak tamsayıya dönüştürülür. . iki parametreyi çarparak ödenecek ücreti hesaplayan aşağıdaki ifade ile değiştirin: return dailyRate * noOfDays. calculateFee yönteminin tanımlamasını. } Generate Method Stub Wizard’ın parametre adları için verilen bağımsız değişken adlarını kullandığına dikkat edin. int noOfDays) { throw new NotImplementedException().

uygulamada aynı kodu (ya da benzer kodu) birden fazla yerde yazdığınızı görürsünüz. yani yöntem void türündedir: private void writeFee(double p) { . Kod Unsurlarını Yeniden Belirlemek Visual Studio 2008’in oldukça kullanışlı bir özelliği. kod unsurlarını yeniden belirleme (refactor) imkanıdır.. WriteLine yönteminin ilk parametresi olarak kullanılan dizedeki {0} metni. } İpucu Sözdizimini yeterince iyi bildiğinizi düşünüyorsanız. . Bu kodu içerecek olan yeni yönteme bir ad vermenizi isteyen Extract Method iletişim kutusu açılır. p * 1. Build menüsünde Build Solution’ı tıklayın. biçim dizesinin kullanımını gösterir. writeFee yöntemine aşağıdaki ifadeleri yazın: Console.1).WriteLine(“The consultant’s fee is: {0}”. Böyle bir durumda. Bir ad yazın ve OK’i tıklayın.. calculateFee yönteminin tanımını kullanarak yöntemin parametresinin double olması gerektiğini anladığına dikkat edin. Kodunuzu içeren yeni yöntem oluşturulur ve yazdığınız kod yerine bu yöntemin çağrıldığı ifade yer alır. Aynı zamanda. çalışma zamanında değeri hesaplanan (p * 1. Extract Method ayrıca. Code and Text Editor penceresinde yöntemi doğrudan yazabilirsiniz. Not WriteLine yönteminin bu sürümü. yazdığınız kodu seçerek Refactor menüsünde Extract Method’ı tıklayın. yöntemin bir parametre alıp almayacağını ve bir değer döndürüp döndürmeyeceğini anlayacak kadar akıllıdır. Her zaman Generate Method Stub menü seçeneğini kullanmak zorunda değilsiniz. 11. yöntem çağrısı bir dönen değer kullanmaz. Bazen.62 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Generate Method Stub Wizard’ın. 10.1) dizesi deyiminin değeri ile yer değiştiren yertutucudur.

Enter your daily rate (Günlük oranı girin) satırına 525 yazın ve Enter’a basın. Code and Text Editor penceresinde run yöntemini bulun. stepping into the method –yöntemin içine adım atmak– olarak adlandırılır) ve her return ifadesinin. View menüsünden Toolbars’ı işaret edip Debug araç çubuğunun seçili olduğundan emin olun. 3. Code and Text Editor penceresinin sol tarafındaki sarı ok. run yöntemindeki ilk ifadeye ulaşana kadar çalışır ve sonra durur . View menüsünden Toolbars komutunu kullanarak onu seçim dışı bırakmayı deneyin ve hangi düğmelerin kaybolduğuna dikkat edin. konsol penceresine aşağıdaki iletiyi yazar: The consultant’s fee is: 9817. Visual Studio 2008 programı oluşturur ve çalıştırır.5 4. Enter the number of days (Gün sayısını girin) satırına 17 yazın ve Enter’a basın. 4. 3. etkin ifadeyi gösterir. Etkin ifade ayrıca sarı bir arka planla vurgulanır. Program. 2. Seçili değilse. Son alıştırmada programınızı yavaş biçimde çalıştırmak için Visual Studio 2008 hata ayıklayıcısını kullanacaksınız. Debug araç çubuğu aşağıdaki gibi görünür (Visual Studio 2008 ve Microsoft Visual C# 2008 Express Edition araç çubukları arasında biraz farklılık vardır): Step into Step over Continue Step out . Her yöntemin ne zaman çağrıldığını (bu. aynı komutlar uygulama Debug modunda çalışırken Debug menüsünde de bulunur.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 63 Programı sınayın 1. Start Without Debugging’ı tıklayın. Bir konsol penceresi açılır. Debug araç çubuğu açılır. Visual Studio 2008 hata ayıklayıcısını kullanarak yöntemler arasında gezinin 1. Diğer araç çubuklarıyla yanaşık olabilir. Onu ayırt edemiyorsanız. Uygulamayı kapatmak ve Visual Studio 2008 programlama ortamına dönmek için Enter tuşuna basın. çağıran ifadeye denetimi nasıl aktardığını (bu. Sonra araç çubuğunu tekrar görüntüleyin. Debug menüsünde. Bununla birlikte. stepping out of the method –yöntemin dışına adım atmak– olarak adlandırılır) göreceksiniz. Bu satırda herhangi bir yeri farenin sağ düğmesiyle tıklayın ve kısayol menüsünde Run To Cursor’ı tıklayın. Yöntemlerin içine girerken ve yöntemlerden çıkarken Debug araç çubuğundaki araçları kullanacaksınız. Fare işaretçisini run yöntemindeki ilk ifadeye götürün: double dailyRate = readDouble(“Enter your daily rate: “). Program. 2.

sarı imleç yok olur ve program Console.) Bu hareket. (Console penceresi Visual Studio arkasında gizlenmiş olabilir.ReadLine yöntemini çalıştırdığından Console penceresi etkin hale gelir ve bir şeyler yazmanızı bekler.) İpucu Debug araç çubuğunda Step Over’a tıklamak yerine F10 tuşuna da basabilirsiniz. (Soldan sekizinci düğme. Fare işaretçisiyle yöntemin ikinci ya da üçüncü satırındaki (hangisi olduğu önemli değil) line değişkenini işaret edin. (Soldan altıncı düğme. Sarı imleç. Debug araç çubuğunda Step Over’ı tıklayın. bir değişkenin istenilen değerde olduğundan emin olmak için bu özelliği kullanabilirsiniz. 11. Step Out’u tıklayın. Sarı imleç readDouble yönteminin parantez açma ifadesine atlar. Debug araç çubuğunda.) . Denetim Visual Studio 2008’e döner. Debug araç çubuğunda Step Over’ı tıklayın. Yöntemler içinde gezinirken. fakat tıklamayın.64 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu Debug araç çubuğunu kendi penceresinde görüntülemek için solundaki tutamacı tıklayıp Code and Text Editor penceresine sürükleyin. Ekran İpucu görünür. Tekrar Step Into’yu tıklayın. Console penceresinde 525 yazın ve daha sonra Enter’a basın. line değişkeninin geçerli değerini (“525”) görüntüleyen. hata ayıklayıcının çağrılan yöntemin içine adım atmasına neden olur. İpucu Tekrar tekrar Debug araç çubuğundaki Step Into düğmesine basmak yerine F11 tuşuna basabilirsiniz. 7. yöntemin üçüncü satırında görünür. 10. Sarı imleç yöntemin ikinci ifadesine hareket eder ve Visual Studio 2008’e dönmeden önce program Consol penceresinde Enter your daily rate (Gün sayısını girin) satırını görüntüler. hata ayıklama yapmadan (yöntemin içine girmeden) bir sonraki ifadenin çalıştırılmasını sağlar. 8. 5. İmleç ilk ifadeye ilerler: Console. 6. 9.Write(p). Bu defa. (Soldaki yedinci düğme.) Bu hareket. Debug araç çubuğunda Step Into düğmesini tıklayın.

0 olarak görüntülenir. Bu defa. calculateFee yönteminden dönen değer.) Sarı imleç. Debug araç çubuğunda Step Out’u tıklayın. Denetim Visual Studio 2008’e döner. . çalışmaya devam eder. Debug araç çubuğunda Step Into’yu tıklayın. (Console penceresi Visual Studio 2008 arkasına gizlenmiş ise. Step Into’yu tıklayın. 14. calculateFee yöntemi daha önce çalışır. Sarı imleç calculateFee yönteminin açılan parantez ifadesine atlar. Debug araç çubuğunda Step Over’ı tıklayın. Console penceresinde 17 yazın ve Enter’a basın.5) iletisi görüntülenir. 17. Sarı imleç. 12. noOfDays)). ön tarafa getirmeniz gerekebilir. Continue’u tıklayın (araç çubuğundaki ilk düğme). p değişkeninin değeri. 19. Console penceresinde The consultant’s fee is: 9817.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 65 Bu eylem. Debug araç çubuğunda. Sarı imleç run yönteminin üçüncü ifadesine hareket eder: writeFee(calculateFee(dailyRate. 20. Sarı imleç run yönteminin ikinci ifadesine hareket eder: int noOfDays = readInt(“Enter the number of days: “).5 (Danışman ücreti:9817. Debug araç çubuğunda Step Out’u tıklayın. writeFee yöntemine verilecek parametre olacağından. yöntemi içine girmeden çalıştırmayı seçmiş olursunuz. Debug araç çubuğunda. geçerli yöntemin kesintiye uğramadan sonuna kadar çalışmasına neden olur. 16. Debug araç çubuğunda Step Into’yu tıklayın. Bu defa. 18. İpucu Debug araç çubuğunda Step Out’u tıklamak yerine Shift+F11 tuşlarına basabilirsiniz. program her ifadede durmadan. Ekran İpucu’nda 8925. run yöntemindeki üçüncü ifadeye döner. Fare işaretçisiyle yöntem tanımındaki p değişkenini işaret edin. Tekrar Console penceresi görünür ve gün sayısı girmenizi ister. readDouble yöntemi tamamlanır ve sarı imleç run yönteminin ilk ifadesine geri döner. 15. sarı imleç writeFee yönteminin başındaki açılan parantez ifadesine atlar. 13. run yönteminin üçüncü ifadesine atlar.

Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakarak. n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Bölüm 3 Hızlı Başvuru Bunun İçin Yöntem bildirmek Şunu Yapın Yöntemi bir sınıfın içine yazın.. int rightHandSide) { .. Save iletişim kutusunu görürseniz. Uygulama tamamlanır ve çalışması sona erer. Örneğin: addValues(39. Yöntemin adını ve ardından da parantez içinde gereken bağımsız değişkenleri yazın. Örneğin: int addValues(int leftHandSide.66 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu Hata ayıklayıcının çalışmaya devam etmesi için F5 tuşuna basabilirsiniz. Örneğin: return. } Bir yöntemin içinden değer döndürmek Bir yöntemden yöntemin sonundan önce dönmek Bir yöntemi çağırmak Yöntemin içine bir return ifadesi yazın. Örneğin: return leftHandSide + rightHandSide. Bir yöntemin dışına adım atmak Debug araç çubuğunda Step Out’u tıklayın ya da Debug menüsünde Step Out’u tıklayın. Yöntemin içine bir return ifadesi yazın. . 3). Tebrikler! Başarılı bir şekilde yöntemler yazıp çağırdınız ve çalışmakta olan yöntemlerin içine ve dışına adım atmak için Visual Studio 2008 hata ayıklayıcısını kullandınız. Generate Method Stub Wizard kullanmak Debug araç çubuğunu görüntülemek Bir yöntemin içine adım atmak Yöntemin çağrısını farenin sağ düğmesiyle tıklayın ve daha sonra kısayol menüsünden Generate Method Stub’ı tıklayın. View menüsünde Toolbars’ı işaret edin ve daha sonra Debug’ı tıklayın. Debug araç çubuğunda Step Into’yu tıklayın ya da Debug menüsünde Step Into’yu tıklayın. “Karar İfadeleri Kullanmak” başlıklı Bölüm 4’e geçin.

ilişkili ifadeleri yöntemler içinde nasıl gruplayacağınızı öğrendiniz. programınız derlenmez. Ayrıca. gerekli bir tasarım stratejisidir. Bunun gibi şeyler. Atanmamış değişken. Sonuçları doğru ya da yanlış olan deyimler yaratmak için Boolean işleçleri kullanmak. tüm programlama dilleri için kesin değildir. Bu bölümde. Bunlar Boolean deyimlerine örnektir. her biri belirli bir görevi ya da hesaplamayı yapmak için tasarlanmış ayrı ayrı yöntemlere bölmek. Bir Boolean deyiminin sonucu her zaman doğru ya da yanlıştır. Bir programı. Daha karmaşık karar verme işlemleri için switch ifadeleri yazmak. koşullara bağlı olarak farklı eylemleri gerçekleştiren seçici yöntemler yazabilmeniz gerekir. Not Bu soruların yanıtları. x adında bir tamsayı değişken yaratıp buna 99 değerini atadıktan sonra “x 99 değerini mi içerir?” diye sorduğunuzda yanıt kesinlikle doğru olacaktır. n “Yöntemler Yazmak ve Kapsam Uygulamak” başlıklı Bölüm 3’te.Bölüm 4 Karar İfadeleri Kullanmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n Boolean değişkenleri bildirmek. Örneğin. Microsoft Visual C# derleyicisi. tanımlanmamış değere sahiptir ve örneğin 10’dan küçük olduğunu kesin olarak söyleyemezsiniz. doğru ya da yanlıştır. C ve C++ programlarında yaygın olan hata kaynaklarıdır. bir değişkeni sorgulamadan önce her zaman bir değer atadığınızdan emin olarak bu problemi çözer. yöntemlere bilgi geçirmek için bağımsız değişkenleri ve parametreleri kullanmayı ve bir yöntemden bilgi alabilmek için return ifadelerinin kullanımını da öğrendiniz. her şey siyah ya da beyaz. Bir değer atanmamış değişkenin içeriğini sorgulamaya çalıştığınızda. her seferinde bir parçası olmak üzere problemleri nasıl çözeceğinizi anlamanıza yardımcı olur. bunu yapmayı göreceksiniz. Ayrıca. Birçok programın geniş ve karmaşık problemleri çözmesi gerekir. “x 10’dan küçük mü?” diye sorduğunuzda da yanıt kesinlikle yanlış olacaktır. Boolean Değişkenleri Bildirmek Programlama dünyasında (gerçek dünyanın aksine). Boolean deyimlerinin sonuçlarına dayanarak karar verme işlemi gerçekleştirmek için if ifadeleri yazmak. Programı yöntemlere bölmek. 67 .

areYouReady = true. sonucu doğru ya da yanlış olan hesaplamayı gerçekleştiren bir işleçtir. İlişkisel işleçleri. true değerini atıyor ve sonra da bu değeri konsola yazıyor: bool areYouReady. areYouReady değişkeninin değeri doğru ise. Console. x==y deyimi. Aşağıdaki tabloda. C#’da birçok yararlı Boolean işleci vardır. x ile y’yi karşılaştırır ve değerler aynıysa true değerini içerir. bool adı verilen bir veri türü sağlar. Bir önceki örnekte. // True yazar Boolean İşleçlerini Kullanmak Boolean işleci. bu işleçlerin kullanımını gösterir. aşağıdaki üç ifade areYouReady (SenHazırmısın) adında bool veri türünde bir değişken tanımlıyor.WriteLine(areYouReady). bir değerin aynı türde başka bir değerden küçük ya da büyük olup olmadığını bulmak için kullanırsınız. . sonuç o değerin tersi olur. En basit Boolean işleci ünlem işareti (!) ile gösterilen NOT işlecidir. atama işleci (=) ile karıştırmayın.68 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Microsoft Visual C#. bu işleçlerin nasıl çalıştığı özetlenmiştir. İşleç < <= > >= Anlamı Küçüktür Küçük ya da eşittir Büyüktür Büyük ya da eşittir Örnek age < 21 age <= 18 age > 16 age >= 30 Yaş 42 ise sonuç False False True True Not Eşitlik işlecini (==). x=y deyimi ise y’nin değerini x’e atar. Örneğin. Eşitlik ve İlişkisel İşleçleri Anlamak Sık olarak kullanacağınız iki Boolean işleci de. Aynı türdeki iki değerin birbiri ile aynı olup olmadığını bulmak için bu ikili işleçleri kullanırsınız. ! işlecini Boolean değere uygularsanız. eşitlik (==) ve eşitsizlik (!=) işleçleridir. örnek olarak age adı verilen int değişkeni kullanılarak. !areYouReady deyiminin değeri yanlış olur. İşleç == != Anlamı Eşittir Eşit değildir Örnek age == 100 age != 0 Yaş 42 ise sonuç False True Bu iki işleçle yakından ilgili diğer işleçler ise ilişkisel (relational) işleçlerdir. bool değişkeni şu iki değerden birini tutabilir: true (doğru) ya da false (yanlış). Aşağıdaki tablo.

İpucu Yeni başlayanların en sık yaptıkları hata. ayrıca iki Boolean işleç daha içerir: && simgesi ile gösterilen mantıksal AND işleci ve || simgesi ile gösterilen mantıksal OR işleci. Bu iki işlecin amacı. Örneğin. >= ve <= işleçlerine göre önceliğe sahiptir Bununla birlikte. invalidPercentage (geçersizYüzde) değişkenine true değerini atar: bool invalidPercentage. Çünkü && işleci. Boolean deyimlerinin birleşimlerinden birinin true olup olmadığını belirlemek için || işlecini kullanın. sonuçlarının true ya da false olması açısından eşitlik işleçlerine ve ilişkisel işleçlere benzerdir ancak üzerlerinde işlem gerçekleştirdikleri değerlerin kendileri true ya da false olmalıdır. invalidPercentage = (percent < 0) || (percent > 100). ancak ve ancak üzerlerinde işlem gerçekleştirdiği her iki değer de true ise true’dur. Bunlar koşullu mantıksal işleçler olarak bilinir. Bu ikili işleçler. aşağıdaki ifade ancak ve ancak percent değeri sıfırdan büyük ya da sıfıra eşitse ve 100’den küçük ya da 100’e eşitse.Bölüm 4 Karar İfadeleri Kullanmak 69 Koşullu Mantıksal İşleçleri Anlamak C#. && işlecinin sonucu. Örneğin. || işlecinin sonucu. ikinci deyim. validPercentage = (percent >= 0) && (percent <= 100). daha iyi okunabilir ve anlaşılırdır. true olur. bool validPercentage. aşağıdaki iki deyimi karşılaştırın: validPercentage = percent >= 0 && percent <= 100 ve validPercentage = (percent >= 0) && (percent <= 100) Her iki deyim de aynı değeri döndürür. aşağıdaki ifade ancak ve ancak percent değeri sıfırdan küçükse veya 100’den büyükse. percent değişkenini sadece bir defa kullanarak iki sınamayı birleştirmeye çalışmaktır: percent >= 0 && <= 100 // bu ifade derlenmeyecektir Parantezler kullanmak bu tür hatalardan kaçınmanıza yardımcı olur ve ayrıca deyimin amacını netleştirir. validPercentage (geçerliYüzde) değişkenine true değeri atar. iki Boolean deyimini ya da değerlerini tek bir Boolean sonuçta birleştirmektir. Üzerinde işlem gerçekleştirdiği Boolean deyimlerinden biri true ise. . Örneğin.

koşullu mantıksal işlecin sol tarafına ve daha karmaşık deyimleri de sağ tarafa yerleştirin. Bazı örnekler verelim: (percent >= 0) && (percent <= 100) Bu deyimde. Örneğin. İşleç Önceliği ve Birleşim Özelliğini Özetlemek Aşağıdaki tablo. Aynı kategorideki işleçler aynı özelliğe sahiptir. sağ taraftaki işlenenin değerine bakılmaksızın sonuç değeri true olur. buraya kadar öğrendiğiniz işleçlerin önceliklerini ve birleşim özelliklerini özetliyor. Benzer şekilde. tüm deyimin sonucu false olmak zorundadır. (percent < 0) || (percent > 100) Bu deyimde. percent değeri sıfırdan küçükse. Kolaylıkla gerçekleştirilen basit Boolean deyimleri. Koşullu mantıksal işleçler kullanan deyimleri dikkatlice tasarlarsanız. Bazen. && işlecinin sol tarafındaki işlenen false değeri veriyorsa. && işlecinin sol tarafındaki Boolean deyiminin sonucu false olur. gereksiz çalışmadan kaçınarak kodunuzun performansını artırabilirsiniz. Bunun anlamı sağ tarafındaki deyim ne olursa olsun tüm deyimin sonucu false olur. percent değeri sıfırdan küçükse. Üst kategorideki işleçler alt kategoridekilere göre önceliklidir. bu yüzden && işlecinin sağ tarafındaki deyimler atlanır. sağ işlenenin değeri ne olursa olsun. || işlecinin sol tarafındaki Boolean deyiminin sonucu true olur.70 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Kestirmeler Yaratmak && ve || işleçlerinin her ikisi de kestirmeler yaratmak (short-circuiting ) adı verilen bir özelliğe sahiptir. programın karmaşık deyimleri değerlendirmesi gerekmeyecektir. bu yüzden || işlecinin sağ tarafındaki deyimler atlanır. . Birçok durumda. koşullu mantıksal deyimin sonucunu öğrenmeye çalışırken her iki işleci de gerçekleştirmek gerekmez. Bunun anlamı sağ tarafındaki deyim ne olursa olsun tüm deyimin sonucu true olur. || işlecinin sol tarafındaki işlenenin değeri true ise. Bu durumlarda && ve || işleçleri sağ taraflarındaki deyimleri atlar.

. else statement-2. if İfadesinin Sözdizimini Anlamak if ifadesinin sözdizimi (if ve else C# anahtar sözcükleridir) aşağıdaki gibidir: if ( booleanExpression ) statement-1. if ifadesini kullanabilirsiniz.Bölüm 4 Karar İfadeleri Kullanmak 71 Kategori Birincil İşleçler () ++ -! + ++ -* / % + < <= > >= == != && || = Açıklama Önceliği geçersiz kılar Sonra artırma Sonra azaltma Mantıksal NOT Toplama Çıkarma Önce artırma Önce azaltma Çarpma Bölme Kalan Toplama Çıkarma Küçüktür Küçük ya da eşittir Büyüktür Büyük ya da eşittir Eşittir Eşit değildir Mantıksal AND Mantıksal OR Birleşim Sol Tekli Sol Çarpımsal Sol Toplamsal İlişkisel Sol Sol Eşitlik Koşullu AND Koşullu OR Atama Sol Sol Sol Sağ Karar Vermek için if İfadelerini Kullanmak Boolean deyiminin sonucuna bağlı olarak iki farklı kod bloğu arasında seçim yapmak istediğinizde.

. aksi takdirde.. if (seconds = 59) // derleme zamanı hatası . if (inWord == true) // doğru ama yaygın olarak kullanılmaz . seconds (saniyeler) değişkeninin değeri 59 ise. Bazı başka programlama dillerinde (özellikle C ve C++).. statement-1 çalışır. Bir if ifadesinde. C ve C++ programlarındaki yaygın hatalardan bir diğeridir. deyim mutlaka Boolean olmalıdır... eşitlik sınaması işleci. Bu arada. Boolean değişkeni kullanabilirsiniz: bool inWord. ==.. =. aşağıda gösterildiği gibi. Eğer else koşulu yoksa ve booleanExpression değeri false ise. else seconds++. C# bunu desteklemez ve böyle bir deyim yazarsanız derleyici hata verir. kronometrenin saniye kısmını (dakikalar şimdilik yok sayılmıştır) gösteren değişkeni artıran if ifadesi aşağıdadır. yerine yanlışlıkla atama işleci. Buna ek olarak. aksi takdirde statement-2 çalışır. yine parantez arasında yer alacak şekilde. Örneğin: int seconds.. tamsayı deyim yazabilirsiniz ve derleyici tamsayı değeri arka planda true (sıfırdan farklı) ya da false (sıfır) olarak değiştirir. if (inWord) // daha iyi . Boolean deyimine 59 değerinin atanması (sıfırdan farklı bir sayı. 0 değerine sıfırlanır. if ifadesinden sonraki kod ile çalışmaya devam eder. yazarsanız.. ++ işleci kullanılarak artırılır: int seconds. . true anlamına gelir). . bir if ifadesi deyimi olarak. if (seconds == 59) seconds = 0. if ifadesinden sonraki kodun her zaman gerçekleştirilmesi ile sonuçlanır.72 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş booleanExpression deyiminin sonucu true ise. if (seconds == 59) // tamam Yanlışlıkla atama işleci kullanılması... . else anahtar sözcüğü ve sonraki statement-2 isteğe bağlıdır. uygulama. Örneğin. C# derleyicisi hatanızı fark eder ve kodu derlemez. Yalnızca Boolean Deyimleri Lütfen! Bir if ifadesindeki deyim parantez içinde yazılmalıdır.

if (day == 0) dayName = “Sunday”. if (Boolean deyimi)’nden sonra tek bir ifade ve else anahtar sözcüğünden sonra da tek bir ifade belirttiğine dikkat edin. else if (day == 1) dayName = “Monday”. biri true sonucunu verene kadar art arda sıralamak için birbirine bağlayarak bir zincir oluşturabilirsiniz. Sonraki ifade (minutes++. üçüncü if ifadesine de yalnızca birinci ve ikinci sınama false olduğunda erişilir. Benzer şekilde. minutes++. fakat bu değişkenler blok sonunda yok olur. int minutes = 0.Bölüm 4 Karar İfadeleri Kullanmak 73 İfadeleri Gruplamak için Bloklar Kullanmak Daha önce gösterilen if ifadesi sözdiziminin. Aşağıdaki örnekte. ilk sınama başarısız olur ve denetim. Aşağıdaki örnekte. C# derleyicisi yalnızca ilk ifadeyi (seconds = 0. . program derlendiğinde if ifadesinden bağımsız olarak her zaman çalıştırılır. ancak daha basit bir çözüm olarak ifadeleri bir block (blok) içinde gruplayabilirsiniz. Bazen. if İfadelerini Basamaklamak if ifadelerini başka if ifadeleriyle iç içe kullanabilirsiniz. derleyici else anahtar sözcüğüne ulaştığında. Bir blok. Boolean deyimi true olduğunda birden fazla ifadeyi gerçekleştirmek istersiniz. Bu ifadeleri bir yöntem içinde gruplayabilir ve sonra yeni yöntemi çağırabilirsiniz. day değişkeninin değeri sıfır değilse. Önemli Parantezleri kullanmazsanız. Bu yolla Boolean deyimlerini.) if ifadesi ile ilişkilendirir.). Blok içinde değişkenler tanımlayabilirsiniz. day (gün) değişkeninin değeri sıfırsa ilk sınama true değeri verir ve dayName (günAdı) değişkenine “Sunday” (Pazar) atanır. parantez içinde gruplanmış ifadeler kümesidir. Blok aynı zamanda yeni bir kapsam başlatır. if (seconds == 59) { seconds = 0. } else seconds++. seconds değişkenini sıfırlayan ve minutes (dakikalar) değişkenini artıran iki ifade blok içinde gruplandırılmıştır ve seconds değeri 59’a eşit ise tüm blok gerçekleştirilir: int seconds = 0. önceki if ifadesi ile ilişkilendiremez ve sözdizimi hatası verir. .. ikinci if ifadesini çalıştırıp day değişkenini 1 ile karşılaştıracak olan else yantümcesine geçer. Ayrıca..

iki tarihi karşılaştırmak için basamaklı if ifadeleri kullanan bir yöntem yazacaksınız. Aslında. if ifadeleri yazın 1. 3. Microsoft Visual Studio 2008’i başlatın. Aşağıdaki metin. çünkü her ikisi de bugünün tarihini gösteriyor. yalnızca küçüktür ve büyüktür işleçleri doğru çalışıyor gibi görünüyor! . 2.) Her iki denetim de bugünün tarihine ayarlıdır. Visual Studio 2008 uygulamayı oluşturur ve çalıştırır. aşağı açılır okunu tıklayarak tarih seçmenizi sağlayan bir takvim görüntüler. Compare’i tıklayın.74 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş else if (day == 2) dayName = “Tuesday”. else dayName = “unknown”. (Bu denetimler. Debug menüsünde Start Without Debugging’i tıklayın. else if (day == 3) dayName = “Wednesday”. metin kutusunda belirir: first first first first first first == != < <= > >= second second second second second second : : : : : : False True False False True True first == second Boolean deyimi true olmalıdır. else if (day == 6) dayName = “Saturday”. Aşağıdaki alıştırmada. Form üzerinde first ve second adında iki DateTimePicker denetimi vardır. 4. else if (day == 4) dayName = “Thursday”. else if (day == 5) dayName = “Friday”. Belgeler klasörünüzde \Microsoft Press\Visual CSharp Step by Step\Chapter 4\Selection klasöründe yer alan Selection projesini açın.

parametrelerindeki değere bağlı olarak 0. 7. diff >= 0). DateTime rightHandSide) { // TO DO return 42. Aşağıdaki gibi görünür: private int compareClick(object sender.Value. 6. show(“first != second”. Code and Text Editor penceresinde.cs kodunu görüntüleyin.Value). diff == 0). show(“first == second”.Text = “”. ne zaman çağrılırsa çağrılsın aynı değeri döndürür. diff <= 0). show(“first > second”. Window1. diff > 0). diff < 0). Aşağıdaki şekilde görünür: private int dateCompare(DateTime leftHandSide.xaml. compareClick yöntemini bulun. Bu yöntemin amacı. bağımsız değişkenlerini sorgulamak ve göreceli değerlerine dayanarak bir tamsayı değeri döndürmektir. diff != 0). show(“first < second”. show yöntemi. Bu. } Kullanıcı form üzerindeki Compare düğmesini tıkladığında bu yöntem çalışır. show(“first >= second”. neden uygulamanın beklenildiği gibi çalışmadığını açıklar. -1 ya da +1 değerleri döndürmez.Bölüm 4 Karar İfadeleri Kullanmak 75 5. dateCompare yöntemini bir sonraki basamakta inceleyeceksiniz. show(“first <= second”. bağımsız değişkenler aynı değere sahipse . info. Visual Studio 2008 programlama ortamına dönmek için Quit’i tıklayın. form üzerindeki info metin kutusunda karşılaştırma sonuçlarını özetler. RoutedEventArgs e) { int diff = dateCompare(first. dateCompare yöntemini bulun. second. } Bu yöntem. 8. Form üzerinde first ve second DateTimePicker denetimlerinde gösterilen tarihlerin değerlerini karşılaştırmak için dateCompare adında bir başka yöntem çağırır.

Year < rightHandSide deyimi true ise. leftHandSide değişkenindeki tarih. else if (leftHandSide. aşağıda koyu renkle vurgulanan ifadeleri dateCompare yöntemine ekleyin: private int dateCompare(DateTime leftHandSide. 10. . yani program result değişkenine -1 değeri atar. böylece program result değişkenine +1 değeri atar. rightHandSide değişkenindeki tarihten sonraki bir gün olmalıdır.Year) result = +1. } leftHandSide.Year < rightHandSide.Month > rightHandSide. her iki tarihin de Year özelliği aynıdır. leftHandSide değişkenindeki gün.Year) result = -1. leftHandSide. Aşağıda koyu renkle vurgulanan ifadeleri dateCompare yönteminin gövdesine ekleyin: private int dateCompare(DateTime leftHandSide. Bir önceki basamakta yazdığınız koddan sonra. 11..Year > rightHandSide. } Bu ifadeler. rightHandSide değişkenindeki günden önce gelmelidir. bu nedenle programın her bir tarihteki ayları karşılaştırması gerekir. DateTime rightHandSide) { int result. Aksi halde. leftHandSide.Year > rightHandSide deyimi de false ise.76 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 0 döndürmeli.Year deyimi ve leftHandSide.. ilk bağımsız değişken değeri ikincisinden küçükse -1 ve büyükse +1 döndürmelidir. bir önceki basamakta yılların karşılaştırılması için kullanılan mantığı izler. (Kronolojik olarak bir gün diğerinden sonra geliyorsa büyük olduğu düşünülür. else if (leftHandSide.Year > rightHandSide. DateTime rightHandSide) { . // TO DO açıklamasını ve return ifadesini dateCompare yönteminden silin.Month) result = -1.Month < rightHandSide.Year < rightHandSide. 9. if (leftHandSide.Month) result = +1. else if (leftHandSide.) İki tarihi doğru olarak karşılaştırmak için bu yöntemdeki mantığı uygulamanız gerekir.Year deyimi true ise.

Day > rightHandSide. else if (leftHandSide.Day > rightHandSide.Day < rightHandSide. aşağıda koyu renkle vurgulanan ifadeleri dateCompare yöntemine ekleyin: private int dateCompare(DateTime leftHandSide.Month deyimi ve leftHandSide. (first ve second). 15. 14. Month değerleri ve Year değerlerinin de aynı olması. her iki tarihin de Month özelliği aynı olmalıdır.Month < rightHandSide.Day deyimlerinin her ikisi de false ise.Day ve leftHandSide. 13.. .. Month deyiminin her ikisi de false ise. Compare’i tıklayın.Day < rightHandSide. her iki değişkendeki Day özelliklerinin değerinin aynı olması gerekir.Day) result = -1. İki DateTimePicker denetimi (günün tarihini) ayarlar. DateTime rightHandSide) { .Month > rightHandSide. bu nedenle iki tarihin aynı olması gerekir ve program result değişkenine 0 değeri atar. Önceki iki basamakta yazdığınız koddan sonra. bu mantıktaki modeli anlamış olmalısınız. Metin kutusunda aşağıdaki metin görünür: first first first first first first == != < <= > >= second second second second second second : : : : : : True False False True False True Bunlar aynı olan tarihler için doğru sonuçlardır. 12. Son ifade. return result.Bölüm 4 Karar İfadeleri Kullanmak 77 leftHandSide. } Şimdi. else result = 0. else if (leftHandSide. bu nedenle programın son olarak her iki tarihteki günleri karşılaştırması gerekir. result değişkeninde depolanan değeri döndürür. İkinci DateTimePicker denetiminin açılır okunu ve daha sonra da yarının tarihini tıklayın. Debug menüsünde Start Without Debugging’i tıklayın.Day) result = +1. Uygulama yeniden oluşturulur ve yeniden başlatılır. leftHandSide.

tarihler DateTime adı verilen özel bir tür kullanılarak tutulur. bunun gerçek dünyada tarihleri karşılaştırmak için kullanmayacağınız bir teknik olduğunu söylemeliyim. leftHandSide ve rightHandSide parametrelerinin DateTime değerlerinde olduğunu görürsünüz. Compare yöntemi iki DateTime bağımsız değişkeni alır ve bunları karşılaştırır. ilk bağımsız değişken ikinciden küçük ise sonuç olarak negatif bir değer. Başka tarihleri de sınayın ve sonuçların beklediğiniz gibi olduğunu doğrulayın. Bir önceki alıştırmada yazdığınız dateCompare yöntemine bakarsanız. Metin kutusunda aşağıdaki metin görünür: first first first first first first == != < <= > >= second second second second second second : : : : : : False True True True False False Aynı şekilde.NET Framework sınıf kütüphanesinde. İki DateTime değerinin eşit olduğu düşünülürse. bu değişkenlerde sadece tarih kısmını karşılaştırır. Bitirdiğinizde Quit’i tıklayın. Örneğin. bunlar doğru sonuçlardır. Gerçek Dünya Uygulamalarında Tarihleri Karşılaştırmak Şimdiye kadar. büyük ise pozitif bir değer ya da iki bağımsız değişken aynı ise sonuç olarak 0 değeri döndürür. Tek fark. hepsi de benzer deyimleri karşılaştırırlar. day değişkenindeki değeri . Yazdığınız mantık.78 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 16. switch İfadeleri Kullanmak Basamaklanmış bir if ifadesi yazdığınızda kimi zaman tüm if ifadelerinin benzer göründüğünü fark edersiniz. her if ifadesinin aynı deyimin sonucunu farklı bir değerle karşılaştırıyor olmasıdır.ayrıca zaman öğesi de vardır. DateTime türü Compare adı verilen yerleşik yönteme sahiptir. ilk tarih ikinciden önce geldiğinde. sadece aynı tarihe değil aynı zamana da sahip olmaları gerekir. Tarihleri ve zamanı karşılaştırmak için. Compare’i tıklayın. Microsoft . uzun ve karmaşık if ve else ifadelerini nasıl kullanacağınızı gördünüz. 17.

herhangi bir constantExpression değeri ile eşleşmezse ve bir default etiketi yoksa program switch ifadesinin kapanan parantezinden sonraki ilk ifade ile çalışmaya devam eder.Bölüm 4 Karar İfadeleri Kullanmak 79 incelemek ve haftanın hangi günü olduğunu bulmak için if ifadesi kullanan aşağıdaki kod bloğunu düşünün: if (day == 0) dayName = “Sunday”.. case ve default anahtar sözcüklerdir) ifadesinin sözdizimi aşağıdaki gibidir: switch ( controllingExpression ) { case constantExpression : statements break. Hiçbir constantExpression değeri. case constantExpression : statements break.. Not Her constantExpression değeri benzersiz olmak zorundadır. programınızı daha etkin ve kolay okunur yapmak için basamaklanmış if ifadelerini bir switch ifadesi olarak yeniden yazabilirsiniz.. switch İfadelerinin Sözdizimini Anlamak Bir switch (switch. controllingExpression değeri. isteğe bağlı olan default etiketinin altındaki ifadeler çalışır. . controllingExpression değerine eşit değilse. else if (day == 2) dayName = “Tuesday”. Uygulama break ifadesine kadar çalışır. else if (day == 1) dayName = “Monday”. bu nedenle controllingExpression bunlardan sadece biri ile eşleşir. Bu durumlarda çoğu zaman. else if (day == 3) . else dayName = “Unknown”. bu noktada switch ifadesi biter ve program switch ifadesinin kapanan parantezinden sonraki ilk ifade ile devam eder. } controllingExpression (denetimDeyimi) bir kez değerlendirilir ve constantExpression (sabitDeyim) deyiminin değeri controllingExpression değerine eşit olan case (durum) altındaki ifadeler çalıştırılır. .. default : statements break.

case Clubs : color = "Black". önceki basamaklanmış if ifadesini aşağıdaki gibi bir switch ifadesi ile yeniden yazabilirsiniz: switch (day) { case 0 : dayName = break. 42 ya da “42” gibi.. } “Sunday”. “Monday”. // Hearts ve Diamonds için kod çalıştırılır break. “Unknown”. Arada ifadeler olmadan durum etiketlerini listelemek yoluyla aynı ifadeleri birden fazla değer için çalıştırabilirsiniz. aynı değere sahip iki durum etiketi yazamazsınız. Böyle bir durumda. case Spades : // Hata – etiketler arasında kod var color = "Black". if ifadesi kullanmanız gerekir. .. bir etiket birden fazla ilişkili ifadeye sahipse. case 1 : dayName = break. Durum etiketleri benzersiz deyimler olmalıdır. Durum etiketleri. case 2 : dayName = break. uygulama sonraki etiketlere geçemez ve derleyici hata verir. Yazdığınız switch ifadesi aşağıdaki kurallara uymak zorundadır: n switch ifadesini sadece int ya da string gibi temel veri türleriyle kullanabilirsiniz. Bununla birlikte. sabit deyimler olmalıdır. } n n n . switch İfadesi Kurallarını İzlemek switch ifadesi oldukça kullanışlıdır fakat ne yazık ki her zaman istediğiniz gibi kullanamazsınız. default : dayName = break. listedeki tüm durumlar için son etiket kodu uygulanır. bir if ifadesi kullanmanız gerekir.80 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Örneğin. Diğer veri türleri ile (float ve double dahil) kullanmak isterseniz. Örneğin: switch (trumps) { case Hearts : case Diamonds : // Geçişe izin verildi – etiketler arasında kod yok color = "Red". “Tuesday”. break. Durum etiketlerinizi çalışma zamanında hesaplamak isterseniz. Diğer bir deyişle.

) C ve C++ programcıları. C ya da C++ programlarında break ifadesinin unutulması oldukça yaygın bir durumdur. bir dizenin karakterlerini okuyan ve her karakteri XML karşılığına eşleyen bir programı tamamlayacaksınız. bunun bir XML yapısı parçası değil. sonraki case ya da default etiketine gitmek için goto ifadesini kullanarak. Debug menüsünde. böyle olmak zorunda değildir. . Start Without Debugging’i tıklayın. fakat aynı zamanda return ifadesi ya da throw ifadesi de kullanabilirsiniz. “Hataları ve Özel Durumları Yönetmek” başlıklı Bölüm 6’da tanımlanmıştır. switch ifadeleri yazın 1. Örneğin. bir veri olduğunu anlar.” olarak değiştirilmelidir.Bölüm 4 Karar İfadeleri Kullanmak 81 Not break ifadesi. default etiketi için de geçerlidir. (&). switch Geçiş Kuralları İki case etiketi arasında herhangi bir kod varsa. Uygulama. “<” karakterinin XML’de özel bir anlamı vardır (öğeleri biçimlendirmek için kullanılır) ve “&lt. Genel olarak goto ifadesi kullanmak önerilmez ve bu kitapta bunu nasıl yapacağınız gösterilmeyecektir! Aşağıdaki alıştırmada. Copy düğmesi ile ayrılmış iki metin kutusu içeren bir form gösterir. throw ifadesi. break ifadesinin. uygulamayı oluşturur ve çalıştırır. Genellikle son etiket olarak yazılmakla birlikte. Belgeler klasörünüzde \Microsoft Press\Visual CSharp Step by Step\Chapter 4\ SwitchStatement klasöründe bulunan SwitchStatement projesini açın. 3. Visual Studio 2008’i başlatın. switch ifadesindeki her durum için (default için bile) zorunlu olduğuna dikkat etmeliler. (bu. başarısız olmayı engellemenin en yaygın yoludur. Bu iyi bir şeydir. Gerçekten istiyorsanız. C#’daki başarısızlığı taklit edebilirsiniz. Benzer kurallar (<). (‘) ve (“) için de geçerlidir. bir case etiketinden diğerine geçemeyeceğiniz için. Karakterin değerini sınayan ve özel XML karakterlerini durum etiketleriyle yakalayan bir switch ifadesi yazacaksınız. uygulamanın bir sonraki etikete geçmesine imkan verir ve çözülmesi oldukça zor bir bilgisayar hatasına neden olur . Visual Studio 2008. switch ifadesinin case etiketi bölümlerini istediğiniz gibi düzenleyebilirsiniz. Böylece XML işlemcisi. 2.

xaml. Kopyalanan geçerli karakter “<” ise. 7. çıkış olacak metnin sonuna “&lt. “<” karakteri “&lt. copyOne yalnızca default bölümü olan bir switch ifadesi içermektedir.”. copyOne yöntemi. break. case ‘&’ : target. Şimdiki adımlarda bu switch ifadesini. break. Örneğin.” dizesini ekleyecektir. 9. 6. Formu kapatın ve Visual Studio 2008’e dönün. 5. Code and Text Editor penceresinde Window1. üstteki metin kutusundan alttaki metin kutusuna bir karakter kopyalar. switch ifadesine. break. Copy düğmesini tıklayın.”. açılan parantezden sonra ve doğrudan default etiketinden önce switch ifadesine ekleyin: case ‘<’ : target.Text += “&lt. bu kod. Şu anda.”. yeni eklediğiniz break ifadesinden sonra ve default etiketinden önce aşağıdaki ifadeleri ekleyin: case ‘>’ : target. İfade.82 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 4. .cs için kodu görüntüleyin ve copyOne yöntemini bulun. Aşağıdaki ifadeleri.” dizesine dönüştürülecektir. XML’e özgü karakterleri XML karşılıklarına dönüştürmek için değiştireceksiniz. karakter karakter aşağıdaki metin kutusuna kopyalanır.Text += “&amp. Üstteki metin kutusuna aşağıdaki ifadeyi yazın: inRange = (lo <= number) && (hi >= number).Text += “&gt. 8.

Son iki case etiketindeki ters kesme işareti (\). Hedef metin kutusu aşağıdaki metni görüntüler: inRange = (lo &lt. XML’de olduğu gibi C#’da özel bir anlama sahiptir (karakter ve dize sabitlerini sınırlamak için kullanılırlar). n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Diğer dizelerle denemeler yapın ve tüm özel karakterlerin (<. “. Start Without Debugging’i tıklayın. ve ‘) doğru olarak ele alındığını doğrulayın.= number) 13.Text += “&#34. &. İfade aşağıdaki metin kutusuna kopyalanır. case ‘\’’ : target. Üstteki metin kutusuna aşağıdaki metni yazın: inRange = (lo <= number) && (hi >= number). Save iletişim kutusu görünürse. .Text += “&#39. 12.Bölüm 4 case ‘\”’ : target. Copy’yi tıklayın. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Bu defa. Karar İfadeleri Kullanmak 83 Not: Tek tırnak işareti (‘) ve çift tırnak işareti (“). break. C# derleyicisinin bu karakterleri sınırlayıcı olarak değil sabitler olarak ele almasına neden olan çıkış karakteridir.= number) &amp. Debug menüsünde. (hi &gt.&amp. 14. Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 5’e geçin. her karakter switch ifadesinde gerçekleştirilen XML karşılığıyla geçer. 10. Formu kapatın. >. 11.”.”. break.

. If (seconds == 59) { seconds = 0.. <. break. } switch (current) { case 0: . Değişken türü olarak bool anahtar sözcüğünü kullanın. Örnek answer == 42 Age >= 21 bool inRange. || işlecini kullanın.. default : .. <=. Bir if ifadesi kullanın.. minutes++. If (inRange) process(). } Bir denetim deyiminin farklı değerlerini farklı ifadelerle ilişkilendirmek Bir switch ifadesi kullanın. break. case 1: . break.84 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bölüm 4 Hızlı Başvuru Bunun İçin İki değerin eşit olup olmadığını görmek İki deyimin değerini karşılaştırmak Boolean değişken bildirmek Yalnızca iki koşul da doğru olduğunda doğru olan bir Boolean deyimi yaratmak İki koşuldan biri doğru olduğunda doğru olan bir Boolean deyimi yaratmak Bir koşul doğru ise bir ifadeyi çalıştırmak Bir koşul doğru ise birden fazla ifadeyi çalıştırmak Şunu Yapın == ya da != işlecini kullanın.. > ya da >= işlecini kullanın. inRange = (lo <= number) && (number <= hi). Bir if ifadesi ve bir blok kullanın. outOfRange = (number < lo) || (hi < number).. && işlecini kullanın.

değişkenin değerini her yinelemede güncelleyerek ve değişken belirli bir değere ulaştığında yineleme sürecini durdurarak bunu yapabilirsiniz. Bir değişken kullanarak. Yineleme ifadeleri yazdığınızda. Bir değişkenin değerini değiştirmek için atama ifadelerini nasıl kullanacağınızı da görmüştünüz.WriteLine(answer + 42). Örneğin. Bu ifade çalıştıktan sonra.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n Bir değişkenin değerini güncellemek için bileşik atama işleçleri kullanmak. Bu durumlarda değişkenin değerini güncellemek için kullanmanız gereken bazı özel atama işleçlerini de öğreneceksiniz. önceki değerinin 42 fazlası olur: answer = answer + 42. Bileşik Atama İşleçleri Kullanmak Aritmetik işleçler kullanarak yeni değerler yaratmayı görmüştünüz. yineleme işleminin kaç kez yinelendiğini denetlemek için bir değişkeni güncellemeniz gerekir. aşağıdaki ifade answer değişkenine 42 ekler. bir ya da daha çok ifadeyi yinelenen biçimde çalıştırmak için çeşitli yineleme (ya da looping-döngüye sokma) ifadelerini kullanmayı öğreneceksiniz. Bir değişkenin değerine 42 eklemek istiyorsanız. answer değişkeninin değeri. Bu bölümde. answer değişkeninin değerini 42 olarak değiştirmek için atama işleci kullanır: answer = 42. Örneğin. ifadeleri seçime bağlı olarak çalıştırmak için if ve switch yapılarının kullanımını öğrendiniz. 85 . Console. atama işleci ile toplama işlecini birleştirebilirsiniz. while. for ve do yineleme ifadelerini yazmak. Aşağıdaki ifade. Bir do ifadesinin içine girmek ve değişkenleri değişirken izlemek. aşağıdaki ifade answer değişkeninden 42 fazla olan bir değeri konsolda görüntülemek için + işlecini kullanır. “Karar İfadelerini Kullanmak” başlıklı Bölüm 4’te.

yerine count++. . değişken += sayı. aşağıdaki kod. değişken = değişken + sayı. değişken %= sayı. string greeting = “Hello “. kısayoldan yapmanızı sağlar. Bir değişkene bir değer eklemek o kadar sık rastlanan bir durumdur ki C#. konsolda “Hello John” iletisini gösterir: string name = “John”. basit atama işleçleri ile aynı öncelik ve birleşim özelliklerine sahiptir.86 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bu ifade çalışıyor olmakla birlikte. değişken -= sayı. değişken /= sayı. Böyle yazın değişken *= sayı. Böyle yazmayın değişken = değişken * sayı. deneyimli bir programcının böyle bir ifade kullandığını göremezsiniz. greeting += name. Not Bir değişkeni bir artırmak ya da bir azaltmak için bileşik atama işleci yerine artırma (++) ve azaltma (--) işleçlerini kullanın. Örneğin: count += 1. İpucu Bileşik atama işleçleri. += işleci aynı zamanda dizeler üzerinde de çalışır. Diğer bileşik atama işleçlerini dizelerde kullanamazsınız. Bu işleçler toplu olarak bileşik atama işleçleri olarak bilinir. Örneğin. bunu += işleci kullanarak. Aşağıdaki tabloda gösterildiği gibi. değişken = değişken % sayı. değişken = değişken / sayı.sayı. Console.WriteLine(greeting). answer değişkenine 42 eklemek için aşağıdaki ifadeyi yazabilirsiniz: answer += 42. değişken = değişken . Bir dizeyi başka bir dizenin sonuna ekler. atama işleci ile herhangi bir aritmetik işleci birleştirmek için bu kısayolu kullanabilirsiniz.

yani while ifadesinden çıkıldığı zamana kadar bu işlem sürer. while ifadesinin denetimi altında birden çok sayıda ifade gerçekleştirmek istiyorsanız. her seferinde bir satır olmak üzere bir metin dosyası boyunca yineleme yapmak ve her satırı formdaki metin kutusuna yazmak için bir while döngüsü yazacaksınız. Deyimin değeri hala doğru ise ifade yeniden çalıştırılır ve Boolean deyimi yeniden değerlendirilir. 0’dan 9’a kadar olan değerleri yazan bir while ifadesi şöyledir: int i = 0. . Boolean deyiminin değerini hatalı yapacak ve döngüyü sonlandıracak bir ifade eklemek. başlangıç seviyesindeki programcıların yaygın olarak yaptığı bir hatadır. i++. bu ifadeleri parantez içinde blok halinde gruplandırmalısınız. Boolean deyimi false olana kadar. Bu örnekte. programın sonsuza kadar çalışmasına neden olur. Aşağıdaki alıştırmada. Bu. while ifadesinin sözdizimi aşağıdaki gibidir: while ( booleanExpression ) statement Boolean deyimi değerlendirilir ve true ise ifade çalıştırılır. Uygulama daha sonra while ifadesinden sonraki ilk ifade ile devam eder. parantez içinde yazılmalıdır. Not while döngüsündeki i değişkeni. daha sonra Boolean deyimi yeniden değerlendirilir.WriteLine(i).Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 87 while İfadeleri Yazmak Bir Boolean deyiminin değeri true olarak kaldığı sürece bir ifadeyi tekrar tekrar çalıştırmak için while ifadesini kullanırsınız. bir Boolean deyim olmalıdır. Boolean deyiminin sonucu ilk işlemde yanlış olursa. gerçekleştirilen yineleme sayısını kontrol eder. i++ ifadesi bunu yapmaktadır. Boolean deyimi. anahtar sözcük dışında sözdizimi aynıdır): n n n n Deyim. ifade çalışmaz. while (i < 10) { Console. } Tüm while ifadeleri bir noktada sonlanmalıdır. Bu oldukça yaygın bir deyimdir ve bu rolü gerçekleştiren değişken bazen Sentinel değişken olarak adlandırılır. sözdizimi kuralı bakımından if ifadesi ile birçok benzerlik gösterir (aslında. while ifadesi.

uygulamayı oluşturur ve çalıştırır. OpenFileDialog sınıfının bir örneğidir.Name. Window1. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 5\ WhileStatement\WhileStatement klasörüne gidin.xaml. dosyanın içeriğini okuyacak ve gösterecek olan kodu henüz çalıştırmamış olmanızdır.Text = src. bir dosyayı seçmek ve içeriğini görüntülemek için kullanabileceğiniz basit metin dosyası görüntüleyicisidir.FileName.ComponentModel. Bu sınıf. Yöntem ifadeleri aşağıdaki gibi uygulanır: private void openFileDialogFileOk(object sender.xaml. . 3.cs.88 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bir while ifadesi yazın 1. Open iletişim kutusunda seçilen kaynak dosyasının tam adını (klasör de dahil) içerir. 4. fullPathname adında bir string değişken bildirir ve openFileDialog nesnesinin FileName özelliğini başlangıç değeri olarak atar. Bu özellik. // add while loop here } İlk ifade. 2.xaml. standart Windows Open iletişim kutusunu görüntülemek. Open iletişim kutusu açılır. filename.xaml. Bu fonksiyonelliği aşağıdaki basamaklarda ekleyeceksiniz. Code and Text Editor penceresinde Window1. Kullanıcı Open iletişim kutusunda bir dosyayı seçtikten sonra Open düğmesini tıkladığında bu yöntem çalışır. Uygulama. Window1. Visual Studio 2008. form üzerindeki küçük metin kutusunda görünür fakat Window1. 7. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 5\WhileStatement klasöründe bulunan WhileStatement projesini açın.cs dosyasını açın ve daha sonra Open’ı tıklayın. 5. Bunun nedeni.cs dosyası için kodu görüntüleyin ve openFileDialogFileOk yöntemini bulun. 6. Debug menüsünde Start Without Debugging’i tıklayın. Formu kapatın ve Visual Studio 2008’e dönün. FileInfo src = new FileInfo(fullPathname). Dosya adı. Open File’ı tıklayın. Not openFileDialog nesnesi. System. Microsoft Visual Studio 2008 kullanarak.cs dosyasının içeriği geniş metin kutusunda görünmez. dosya seçmek ve seçilen dosyanın adını ve yolunu elde etmek için kullanabileceğiniz yöntemler sağlar. CancelEventArgs e) { string fullPathname = openFileDialog.

Open iletişim kutusunda seçilen dosyanın adını tutar. src adı verilen bir FileInfo değişkeni bildirir ve Open iletişim kutusunda seçilen dosyayı gösteren nesneyi başlangıç değeri olarak atar.ReadLine().OpenText(). openFileDialogFileOk yöntemine eklediğiniz bir önceki satırdan sonra aşağıdaki ifadeyi ekleyin: string line = reader. TextReader. bu metin kutusunda görüntülenen mevcut metni temizler. openFileDialogFileOk yöntemine eklediğiniz satırdan hemen sonrasına aşağıdaki ifadeyi yazın: TextReader reader = src. okunacak dosyayı açmak için OpenText yöntemi sağlar. tüm satırlar bitene kadar her seferinde dosyadaki bir satır üzerinde yinelenen bir while döngüsüdür. dosyaları işlemek için kullanabileceğiniz Microsoft . böylece reader değişkeni bu dosyanın içeriğini okuyabilir. source değişkeni. (FileInfo. 10. klasör adı olmadan.Text = “”. ya metnin bir sonraki satırını ya da başka bir satır yoksa null adı verilen özel bir değeri döndürür. 9. (başlangıçta herhangi bir satır yoksa dosya boş olmalıdır. dosyanın adını form üzerindeki metin kutusunda gösterir. Bu yöntem. reader adında bir TextReader değişkeni bildirir.Text += line + ‘\n’. Bu ifade.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 89 İkinci ifade. filename denetiminin Text özelliğini. . line = reader. src değişkeninin Name özelliği. } Bu. dosya gibi bir kaynaktan karakter akışını okumak için kullanabileceğiniz başka bir sınıftır. Son yazdığınız koddan sonra openFileDialogFileOk yöntemine aşağıdaki ifadeleri ekleyin: while (line != null) { source. form üzerindeki geniş metin kutusunu gösterir.ReadLine yöntemini çağırır. // add while loop here (buraya while döngüsünü ekleyin) yorum satırı yerine aşağıdaki ifadeyi yazın: source. Bu değişkenin Text özelliğine boş dize (“”) atamak. Bu ifade. kullanıcı tarafından Open iletişim kutusunda seçilen dosyayı açar.ReadLine(). FileInfo sınıfı. line adında bir string değişken bildirir ve dosyadan ilk satırı okuyarak bu değişkene atamak için reader. Bu ifade. src değişkeninin Name özelliğine atar .) Üçüncü ifade. . 8.IO ad alanında yer alır.NET Framework tarafından sağlanan. System. İfade.NET Framework tarafından sağlanan bir sınıftır.) 11.

bir sonraki yinelemeyi gerçekleştirmeden önce. Bu yöntemin eklediğiniz kodu içerdiğini doğrulayın. metindeki geçerli satırı gösterir. Window1.Close(). seçilen dosyanın içeriği metin kutusunda görünür. while döngüsünün sonundaki kapanan küme parantezi sonrasına aşağıdaki ifadeyi ekleyin: reader.90 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş while döngüsünün başlangıcındaki Boolean deyimi.) While döngüsü. Open File iletişim kutusunda. Değer boş (null) değilse.cs dosyasını seçin ve daha sonra Open’ı tıklayın. (‘\n’ — TextReader nesnesinin ReadLine yöntemi. düzenlediğiniz kodu tanımış olmalısınız: 16. Bu defa. 15. yani dosyada okunacak başka satır kalmadığında. Dosya sonuna gelindiğinde. line değişkenindeki değeri inceler. 14. bu nedenle kodun yeni satır karakterini yeniden eklemesi gerekir. . döngü gövdesi değişkenin değerini yeni satır karakteri ile birlikte. metnin sonraki satırını okur. 13. Bu ifade dosyayı kapatır. 17. Form göründüğünde. Open File’ı tıklayın. source metin kutusunun Text özelliğinin sonuna ekleyerek. 12. her satırı okudukça satır sonundaki yeni satır karakterini çıkarıp atar. Debug menüsünde Start Without Debugging’i tıklayın. while döngüsü sona erer ve ReadLine yöntemi boş değer döndürür. xaml. Metin kutusundaki metni kaydırın ve openFileDialogFileOk yöntemini bulun. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 5\WhileStatement\WhileStatement klasörüne gidin. Formu kapatın ve Visual Studio 2008 programlama ortamına dönün.

denetim değişkenini güncelleme) ifade Daha önce gösterilen. for döngüsü kullanarak yeniden yazabilirsiniz: for (int i = 0.WriteLine(i). Boolean deyimini kullanmazsanız. Aşağıdaki for ifadesi sonsuza kadar çalışacaktır: for (int i = 0. ifade yeniden çalışır. başlatma. döngünün en başında bir defa gerçekleşir.i++) { Console. ifade çalışır. Koşul hala true ise. i < 10. Bu üç kısımdan herhangi birini unutmak daha zor olacağından. } . denetim değişkeni güncellenir. ifadenin her seferinde güncelleme gerçekleşmeden önce çalıştığına ve güncellemenin Boolean deyiminin sonucu bulunmadan önce gerçekleştiğine dikkat edin. Boolean deyim ve güncelleme (döngünün “düzeni”) işlemlerini birleştirerek bu tip bir while ifadesinin daha biçimsel bir sürümünü yazmanızı sağlar.WriteLine(“somebody stop me!”). Başlatma işleminin bir defa gerçekleştiğine. 0’dan 9’a kadar tamsayıları gösteren while döngüsünü. i++) { Console. Boolean deyimi. Boolean deyimi yeniden değerlendirilir ve böyle devam eder. for ifadesini kullanışlı bulacaksınız. for ifadesinin sözdizimi aşağıdaki gibidir: for (başlatma. for ifadesinin üç bölümünden istediğinizi kullanmayabilirsiniz. . varsayılan olarak true kabul edilir. Boolean deyiminin sonucu true ise.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 91 for İfadeleri Yazmak Birçok while ifadesi aşağıdaki genel yapıya sahiptir: başlatma while (Boolean deyimi) { ifade denetim değişkenini güncelleme } Bir for ifadesi. } Başlatma. Denetim değişkeni güncellenir ve Boolean deyimi yeniden değerlendirilir.

ReadLine()) { source.. gelecekte döngüye ifade ekleme işini kolaylaştırmış olursunuz. Boolean deyimi ve denetim değişkenini güncelleme bölümleri. i++. İlk olarak. başka bir ifade eklediğinizde. çeşitli başlatmaları ve güncellemeleri virgülle ayırırsınız: for (int i = 0. Örneğin: for (int i = 0. Bu kuralın iki önemli sonucu vardır. } İpucu if. Bu değişkenin kapsamı. } Console.. for (string line = reader. line = reader. Bunun için. tek bir ifade içerse bile açık biçimde bir ifade bloğu kullanmak iyi bir alışkanlık olarak görülür. while ve for gövdelerinde blok. i <= j. i++. line != null.Text += line + ‘\n’. j = 10. i++) { .ReadLine(). bir for döngüsünde birden fazla başlatma ve birden fazla güncelleme kullanabilirsiniz (sadece bir Boolean deyimine sahip olabilirsiniz).. Blok kullanarak. for İfadesinin Kapsamını Anlamak Bir for ifadesinin başlatma bölümünde bir değişken bildirebildiğinizi fark etmişsinizdir. j--) { . Gerekirse.. parantezleri de eklemeyi unutmamanız gerekir ve bu. bu değişkeni for ifadesi bittikten sonra kullanamazsınız çünkü artık kapsam içinde değildir. oldukça kolay unutulur. Blok kullanmazsanız. for döngüsü olarak aşağıda gösterilmiştir. ) { Console.WriteLine(i). } Not Bir for ifadesinin başlatma. } Son örnek olarak. i < 10. garip bir şekilde yazılmış bir while ifadesi elde edersiniz: int i = 0. kullanılmasa bile virgülle ayrılmalıdır. daha önceki alıştırmadaki while döngüsü. for (. // derleme zamanı hatası .WriteLine(i). aşağıdaki örnekte gösterildiği gibi. i < 10.92 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Başlatma ve güncelleme bölümlerini kullanmazsanız. for ifadesinin gövdesi ile sınırlıdır ve for ifadesi tamamlandığında yok olur.

do { Console. do ifadesinin sözdizimi aşağıdaki gibidir (sondaki noktalı virgülü unutmayın): do statement while (booleanExpression). i < 10..Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 93 İkinci olarak. . deyim ilk değerlendirmede false sonucunu verirse. i += 2) // tamam { . bir ifade bloğu kullanmanız gerekir. Bunun anlamı şudur.WriteLine(i). Döngü gövdesinin birden fazla ifade içermesini isterseniz. yani ifadenin gövdesi her zaman en azından bir kez çalışır. döngü bir kez bile çalıştırılmaz. Örneğin: for (int i = 0. do ifadesi farklıdır: Boolean deyimi her yinelemeden sonra değerlendirilir. } while (i < 10). i < 20. yan yana iki ya da daha çok for ifadesini aynı değişkeni kullanarak oluşturabilirsiniz çünkü her değişken farklı kapsam içindedir. } do İfadeleri Yazmak while ve for ifadelerinin her ikisi de Boolean deyimini döngünün başlangıcında test eder. 0’dan 9’a kadar olan değerleri konsola yazan örnek aşağıdaki gibidir: int i = 0. Bu defa do ifadesi ile yazılmış. i++) { . } for (int i = 0.. i++...

Çoğu programcılık kılavuzu continue ifadesinin ya çok dikkatli kullanılmasını ya da hiç kullanılmamasını önerir. pozitif bir tamsayıyı. else break. bir for ifadesinin içinden bir continue ifadesi çalıştırırsanız. sayıyı sürekli 8’e bölerek her . Debug menüsünde. Üstteki metin kutusuna pozitif bir tamsayı yazdığınızda (program negatif tamsayılarla çalışmaz) ve Show Steps düğmesini tıkladığınızda program yazdığınız sayıyı sekizlik gösterimde dize karşılığına çevirir. 2. Bir do ifadesini inceleyin 1. } Bu kesinlikle berbat bir kod. Ayrıca continue ifadesinin davranışı çok zor anlaşılır bir davranıştır. Konsola 0’dan 9’a kadar olan değerleri yazan. Uygulama. Start Without Debugging’i tıklayın. Bir döngüyü kırdığınızda döngü aniden sonlanır ve uygulama döngüden sonraki ilk ifadede devam eder. Örneğin. break ifadesini yineleme ifadesi gövdesinden çıkmak için de kullanabilirsiniz. çünkü her zaman anlaşılması çok zor kodlar oluşturur.WriteLine(“continue “ + i). üzerinde iki metin kutusu ve Show Steps adında bir düğme bulunan bir form görüntüler. devam koşulu da yeniden çalıştırılmaz. döngünün bir sonraki yinelemesi gerçekleşmeden önce güncelleme kısmı çalışır. programın döngünün bir sonraki yinelemesini hemen gerçekleştirmesine neden olur (Boolean deyimini yeniden değerlendirdikten sonra). Program. i++.94 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş break ve continue İfadeleri Bölüm 4’te. bu defa break ve continue ifadelerini kullanan örnek aşağıdaki gibidir: int i = 0. while (true) { Console. if (i < 10) continue. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 5\DoStatement klasöründeki DoStatement projesini açın. Güncelleme de. Aşağıdaki alıştırmada. continue ifadesi. sekizlik gösteriminde dize gösterimine dönüştürmek için bir do ifadesi yazacaksınız. switch ifadesinden çıkmak için kullanılan break ifadesini görmüştünüz. Bunun aksine. Visual Studio 2008 kullanarak.

Bu yöntem. 6.Text += current + “\n”. amount /= 8. steps. Üstteki metin kutusuna 2693 yazın ve daha sonra Show Steps’i tıklayın. showStepsClick yöntemini bulun.Text = “”. int türünün Parse yöntemini kullanarak. 5. Visual Studio 2008 programlama ortamına dönmek için pencereyi kapatın. . char digit = Convert. 3. Alttaki metin kutusu 2693 sayısının sekizlik gösterimini (5205) oluşturmak için kullanılan basamakları gösterir: 4. string current = “”.Text). Bu yöntem aşağıdaki ifadeleri içerir: int amount = int. Code and Text Editor penceresinde Window1. } while (amount != 0). do { int nextDigit = amount % 8. int digitCode = ‘0’ + nextDigit.cs için kodu gösterin.ToChar(digitCode). current = digit + current.xaml.Text). kullanıcı form üzerindeki Show Steps düğmesini tıkladığında çalışır. Aşağıdaki metin kutusu sekizlik gösterimi oluşturmak için tekrarlanan basamakları gösterir.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 95 seferinde kalan değeri hesaplar.Parse(number. number metin kutusunun Text özelliğindeki dize değerini int değerine dönüştürür: int amount = int. steps. İlk ifade.Parse(number.

Bu ifade biraz açıklama gerektirir! Karakterler. Microsoft Windows işletim sistemi tarafından sıklıkla kullanılan karakter kümesinde. Kodu daha yakından incelediğinizde. Bu sayı 0 ile 7 arasında bir sayı olacaktır. ‘0’ + nextDigit deyimi. } while (amount != 0). dördüncü ifade olan do ifadesi tarafından gerçekleştirilir: do { . C# dili. amount değeri 0 olduğunda. En sonunda. bir karakteri tamsayı olarak ele almanıza ve üzerinde aritmetik işlem yapabilmenize imkan tanır. Döngü gövdesinin en azından bir defa çalışması gerektiğine dikkat edin. her başarılı bölme işlemi oluşturulan dizede bir sonraki sayıyı oluşturur. Aritmetik işlemlerde C# değer olarak karakterin kodunu kullanır. . do döngüsü içindeki ilk ifadenin aşağıdaki gibi olduğunu görürsünüz: int nextDigit = amount % 8. steps. ‘2’ için 50’dir ve ‘9’ karakterine kadar kod bir artarak devam eder. ‘1’ karakteri için kod 49. Algoritma. döngü biter. do döngüsünün içindeki üçüncü ifade şudur char digit = Convert. işletim sistemi tarafından kullanılan karakter kümesine uygun olarak benzersiz koda sahiptir.96 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İkinci ifade. Bu ifade nextDigit (sonrakiBasamak) adı verilen bir int değişkeni bildirir ve amount değişkenindeki değeri 8’e böldükten sonra kalan değeri atar. Bu davranış. ‘9’ karakteri için kod 57’dir.ToChar(digitCode). Bu yöntemde gerçek çalışma. Üçüncü ifade current adı verilen bir string değişken bildirir ve değişkene boş dize atar: string current = “”.Text = “”. sonuç olarak 48 ve 55 arasında bir değer verecektir (nextDigit değerinin 0 ile 7 arasında bir değer olacağını hatırlayın). Sonraki ifade şu şekildedir: int digitCode = ‘0’ + nextDigit. alttaki metin kutusunda (steps adı verilen) gösterilen metnin Text özelliğini boş dize olarak ayarlayarak.. ‘0’ karakteri için kod 48 tamsayı değeridir. 0 sayısı da bir sekizlik sayıya sahip olduğundan gerçekten istenilen bir davranıştır.. metni temizler. sürekli olarak amount değişkenini 8’e böler ve kalanı hesaplar. Yani.

Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 97 Bu ifade. ‘6’ karakterini döndürür. Convert. kullanıcının girdiği sayı ile ilgili olarak en küçük anlamlı (en sağda bulunan) sekizlik sayıyı gösteren karakteri hesaplar. döngünün sonundaki while yan tümcesindeki koşul gerçekleştirilir: while (amount != 0) amount değişkeninin değeri henüz 0 olmadığından.cs dosyasını gösteren Code and Text Editor penceresinde. Bu bir bileşik atama ifadesidir ve amount = amount / 8. do döngüsündeki son ifade şöyledir: amount /= 8.Text). üstteki metin kutusuna 2693 yazın ve daha sonra Show Steps’i tıklayın. örneğin. Bir sonraki görev.ToChar(digitCode) yöntemi. Son olarak. digitCode değişkeni 54 değerine sahipse. Window1.ToChar(digitCode). . Form göründüğünde. amount değişkeninin değeri 2693 ise. Yani.Text += current + “\n”. Özet olarak. Program durur ve Visual Studio 2008 hata ayıklama moduna geçersiniz. Bu ifade. do döngüsündeki ilk üç ifade. bu ifade çalıştıktan sonra amount değeri 336 olur. 2. döngü başka bir yineleme gerçekleştirir. Son alıştırmada.xaml. do ifadesinin içine girin 1. Visual Studio 2008 hata ayıklayıcısını kullanarak önceki do ifadesinin içine gireceksiniz. İlk ifadede herhangi bir yeri farenin sağ düğmesiyle tıklayın ve daha sonra Run To Cursor’ı tıklayın. karakter kodunu tutan tamsayıyı alarak uygun karakteri döndürür. nasıl çalıştığını anlamanıza yardımcı olması için. do döngüsündeki sonraki ifade şöyledir: steps. Steps metin kutusuna ekler. digit (basamak) adı verilen bir char değişkeni bildirir ve değişkene Convert. bu sayıyı sonuç dizesine aşağıdaki gibi eklemektir: current = digit + current. sayının sekizlik gösterimi için şimdiye kadar üretilen sayıları içeren dizeyi. Code and Text Editor penceresinin sol tarafındaki sarı ok geçerli ifadeyi gösterir. Convert. imleci showStepsClick (basamaklarıTıklaGöster) yönteminin ilk ifadesine getirin: int amount = int.Parse(number. ifadesi ile aynıdır. ToChar(digitCode) yöntemi çağrısının sonucunu atar. 3.

) 5. Not Windows simgesi. Windows açılır okunu tıklayın. Locals penceresi görünür (zaten açık değilse). Debug araç çubuğunda en sağdaki simgedir. Bu pencere. Menüden Locals’i tıklayın. 6. değerini ve türünü gösterir. Aşağıdaki menü görünür: Not Microsoft Visual C# 2008 Express Edition kullanıyorsanız. Debug araç çubuğunu görüntüleyin. sonraki resimde gösterilenleri içerir. amount yerel değişkeni de dahil olmak üzere. Debug araç çubuğunda.98 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 4. geçerli yöntemde. ortaya çıkan kısayol menüsü. Zaten açık değilse. yerel değişkenlerin adını. amount değişkeninin değerinin 0 olduğuna dikkat edin: . (View menüsünde Toolbars’ı işaret edin ve daha sonra Debug’ı tıklayın.

do döngüsü içindeki ilk ifadeye hareket eder. 9.Parse(number. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: string current = “”. Bu. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: int amount = int. Sarı ok bir sonraki ifadeye hareket eder. Sarı ok. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: steps. Sarı ok. 10. . Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: int nextDigit = amount % 8. Step Into’yu tıklayın. Tekrar Step Into’yu tıklayın. 2693’ün 8’e bölünmesi sonucu kalan değerdir. Bu. Step Into’yu tıklayın. Bu ifade. do döngüsünün başındaki açılan paranteze hareket eder. 11. do döngüsü üç yerel değişken içerir: nextDigit. Locals penceresindeki digitCode değeri 53 olarak değişir. Bu yerel değişkenlerin Locals penceresinde göründüğüne ve üç değişkenin tümünün değerinin 0 olduğuna dikkat edin.Text = “”. Locals penceresini etkilemez çünkü steps bir yerel değişken değildir. Debug araç çubuğunda Step Into düğmesini tıklayın. 8. digitCode ve digit. 12. Locals penceresinde amount değişkeninin değeri 2693 olarak değişir ve sarı ok bir sonraki ifadeye geçer. ‘5’ karakterinin kodudur (48+5). Step Into’yu tıklayın. form üzerinde bir denetimdir. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: int digitCode = ‘0’ + nextDigit. Locals penceresindeki nextDigit değeri 5 olarak değişir.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 99 7.Text). Step Into’yu tıklayın.

arkasında metin kutusunda yeni satırın gösterilmesi için yeni satır karakteri ile birlikte “5” metnini steps metin kutusunda gösterir. amount değeri 336’dır ve 336 != 0 deyimi true sonucunu verir.Text += current + “\n”. current değişkeninin değerinin “” olduğuna dikkat edin. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: amount /= 8.ToChar(digitCode). 15.100 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 13. bu nedenle do döngüsü diğer yinelemeyi gerçekleştirir. 19. 14. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: while (amount != 0). Step Into’yu tıklayın. 18. 53) ve aynı zamanda karakter gösteriminin (‘5’) her ikisini kullanarak char değerlerini gösterir. Locals penceresi.) 16. (Form. Sarı ok while ifadesine hareket eder. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: char digit = Convert. Step Into’yu tıklayın. 17. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: steps. . Locals penceresinde amount değeri 336 olarak değişir. Sarı ok do döngüsündeki ilk ifadeye hareket eder. do döngüsünün başındaki açılan paranteze atlar. Locals penceresinde current değeri “5” olarak değişir. Step Into’yu tıklayın. Step Into’yu tıklayın. Locals penceresinde. Visual Studio arkasına gizlenmiştir. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: current = current + digit. Step Into’yu tıklayın. bu nedenle göremeyebilirsiniz. altı çizili sayısal değer (bu örnekte. Bu ifade. Step Into’yu tıklayın. Sarı ok do döngüsünün sonundaki kapanan paranteze hareket eder. Step Into’yu tıklayın. Locals penceresindeki digit değeri ‘5’ olarak değişir. Sarı ok.

23. Debug araç çubuğundaki Continue düğmesini tıklayın. 21. Tebrikler! Anlamlı while ve do ifadelerini başarıyla yazdınız ve do ifadesinin içine girmek için Visual Studio 2008 hata ayıklayıcısını kullandınız. bu nedenle amount != 0 deyimi false olacak ve do döngüsü sonlanacaktır. Tahmin edileceği gibi.Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 101 20. 24. amount değeri 0 ve current değeri “5205” olur. Save iletişim kutusu görünürse. Visual Studio 2008 programlama ortamına dönmek için formu kapatın. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. 22. do döngüsünün sonraki üç yinelemesinin içine girmek için tekrar tekrar Step Into’yu tıklayın ve Locals penceresinde değişkenin değerinin nasıl değiştiğini izleyin. n . while (amount != 0). ”05”. 2693 sayısının sekizlik gösterimini oluşturmak için kullanılan dört basamağı gösteren form görüntülenir: ”5”. Döngünün dördüncü yinelemesinin sonunda. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakın ve Bölüm 6’ya geçin. do döngüsünün sürdürme koşulu üzerindedir. ”205” ve “5205”. Step Into’yu tıklayın. Sarı ok. do döngüsü sonlanır ve sarı ok showStepsClick yönteminin sonundaki kapanan paranteze hareket eder. amount değeri şimdi 0’dır. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: while (amount != 0).

WriteLine(i). i++. while ifadesi kullanın. Örneğin: variable -= amount. . i++) { Console. } while (i < 10).102 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bölüm 5 Hızlı Başvuru Bunun İçin Bir değişkene bir miktar eklemek Bir değişkenden bir miktar çıkarmak Bir koşul doğru iken bir ya da daha fazla ifade çalıştırmak Şunu Yapın Bileşik toplama işlecini kullanın. do { Console. while (i < 10) { Console. Örneğin: int i = 0. Örneğin: for (int i = 0. i++. Örneğin: int i = 0.WriteLine(i). } İfadeleri bir ya da daha fazla sayıda tekrar tekrar uygulamak do ifadesi kullanın. } Ya da for ifadesi kullanın. Örneğin: variable += amount. i < 10.WriteLine(i). Bileşik çıkarma işlecini kullanın.

Yöntemler yazmak ve okumak. UNIX gibi eski sistemler tarafından benimsenmiş tipik yaklaşım. yöntem başarısızlığa uğradığında özel bir genel değişken atamak için işletim sisteminde bir düzenleme içerirdi. Güçlü C# programları yazmak istiyorsanız. Yazdığınız uygulamalar hataları fark edebilmeli ve bu hataların üstesinden gelebilmelidir. Lastikler patlar. özel durumlar (exceptions) kullanırlar. Hatalarla Başa Çıkmak Bazen kötü şeylerin meydana gelmesi hayatın gerçeğidir. piller biter. Program çalışırken hemen hemen her aşamasında hatalar meydana gelebilir. “Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş” başlıklı Kısım 1’in bu son bölümünde. önceki bölümler bazı şeylerin ters gidebileceği olasılığını hesaba katmadı. Bununla birlikte.Bölüm 6 Hatalar ve Özel Durumları Yönetmek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n try. tornavidalar hiçbir zaman bıraktığınız yerde olmaz ve uygulamalarınız önceden bilinmeyen şekilde davranır. Bunun yerine. checked ve unchecked anahtar sözcüklerini kullanarak tamsayı taşmalarını denetlemek. Daha sonra. Bu oldukça zahmetlidir. C#’ın bir hata oluştuğunda haber vermek için nasıl özel durumlar oluşturduğunu ve bu özel durumların gösterdiği hataları yakalamak ve hataların üstesinden gelmek (hataları işlemek) için try. değerler yaratmak için işleçleri kullanmak. değişkenler bildirmek. Birçoğu programcı olarak sizin kontrolünüz dışında olan çok sayıda nedenden dolayı hatalar meydana gelebilir. catch ve finally ifadelerinin nasıl kullanılacağını öğreneceksiniz. çok sayıda mekanizma geliştirilmiştir. yöntemin başarılı olup olmadığını görmek için genel değişkeni denetlerdiniz. kodları seçime bağlı olarak çalıştırmak için if ve switch ifadeleri yazmak ve kodları tekrar tekrar çalıştırmak için while. öyleyse hataları çözmek için onları nasıl fark edeceksiniz? Yıllar boyunca. Bir finally bloğu kullanarak. catch ve finally ifadelerini kullanarak özel durumları işlemek. 103 . for ve do ifadeleri yazmak için gereken temel Microsoft Visual C# ifadelerini gördünüz. özel bir durum meydana gelse bile kodunuzun her zaman çalıştığından emin olmak. “C# Dilini Anlamak” başlıklı Kısım 2’de kullanacağınız çok sağlam bir C# temeline sahip olacaksınız. C# ve birçok diğer nesne-yönelimli programlama dilleri hataları bu yolla ele almaz. Bu bölümün sonunda. özel durumları bilmeniz gerekir. throw anahtar sözcüğünü kullanarak kendi yöntemlerinizde özel durumlar oluşturmak. Kod parçalarının her zaman beklenildiği gibi çalışacağından emin olmak oldukça zordur. her yöntem çağrıldıktan sonra.

Bir try bloğundan sonra. bir hata koşulu meydana gelirse. rightHandSide). result. } catch (FormatException fEx) { // Özel durumu işle . Kodunuzu bir try bloğu (try . catch işleyici.Text). 2. biri diğerinden sonra olmak üzere tüm ifadeler çalışır. Dizeler geçersiz karakterler içerirse.Text = answer.104 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Kodu Denemek ve Özel Durumları Yakalamak C#. int rightHandSide = int.. } . Bununla birlikte. Kullanıcının form üzerindeki bazı metin kutularına yazdığı dizeleri tamsayı değerlere çeviren. hata işleme kodunu programın ana akışını gerçekleştiren koddan ayırmayı kolaylaştırır. Herhangi bir olası hata koşullarının üstesinden gelmek için try bloğundan hemen sonra bir ya da birden fazla catch işleyici (catch bir başka C# anahtar sözcüğüdür) yazın. try bloğundan sonraki catch işleyiciyi sınar ve denetimi doğrudan ilk eşleşen işleyiciye iletir.ToString(). program işleyiciden sonraki ilk ifade ile devam eder: try { int leftHandSide = int.Parse yöntemi FormatException (BicimOzelDurumu) özel durumunu oluşturur ve uygulama uygun catch işleyiciye aktarılır. int. Bir dizeyi tamsayıya çevirmek için dizenin düzenli sıralanmış geçerli karakterler içermesi gerekir.Parse(lhsOperand. try bloğu içindeki ifadelerden herhangi biri bir hataya neden olursa. bir değeri hesaplamak için yöntem çağıran ve sonucu başka bir metin kutusuna yazan try bloğundaki kod örneği aşağıdadır. özel durumlar ve özel durum işleyicileri kullanarak. belirli bir tür özel durumu yakalamak ve işlemek için tasarlanmıştır. try bloğu içindeki tüm ifadeleri çalıştırmaya kalkışır ve ifadelerin hiçbiri bir özel durum oluşturmazsa. Çalışma zamanı daha sonra.Parse(rhsOperand. int answer = doCalculation(leftHandSide. catch işleyici bittiğinde. Böylece try bloğu içinde oluşabilecek farklı hatalar için farklı işleyiciler sağlayabilirsiniz. C# anahtar sözcüğüdür) içinde yazın..Text). Kod çalıştığında. çalışma zamanı özel bir durum oluşturur. uygulama try bloğu dışına ve özel durumu yakalamak ve işlemek için tasarlanmış başka bir kod parçasına atlar. Özel durumları fark eden programlar yazmak için aşağıdaki iki işlemi yapmanız gerekir: 1. her biri belirli bir özel durumu yakalamak ve işlemek için tasarlanmış birden fazla catch işleyiciye sahip olabilirsiniz.

çalışma zamanı. yöntem parametresi tarafından kullanılan sözdizimine benzer sözdizimi kullanır. yöntem aniden sona erer ve uygulama çağrılan yönteme döner. Bu özelliklerin birçoğu tüm özel durumlar için ortaktır. Önemli Bir özel durumun yakalanmasından sonra. int. Böyle bir durum meydana gelirse. Çağrılan yöntemler listesine dönüldükten sonra. catch işleyici çalışır ve uygulama yakalayan yöntemdeki catch işleyiciden sonraki ilk ifadeden devam eder. . Bu durumda.Parse ifadesi FormatException catch işleyicisi tarafından yakalanamayacak bir OverflowException (TasmaOzelDurumu) özel durumu oluşturacaktır. lhsOperand metin kutusundaki geçerli bir dizenin tamsayı karşılığı C# tarafından desteklenen geçerli tamsayı aralığı dışında (örneğin. Önceki örnekte. İşlenmemiş Özel Durumlar Bir try bloğu özel bir durum oluşturursa ve uygun bir catch işleyicisi yoksa ne olur? Bir önceki örnekte. uygulamanın özel durumu yakalayan catch bloğunu içeren yöntemde devam ettiğine dikkat edin. program işlenmemiş bir özel durum ile sonlanır. yöntemin çağrıldığı noktaya döner. try bloğu yöntemin bir parçasıysa. çağrılan yöntemdeki try bloğundan sonra eşleşen catch işleyiciyi bulmaya ve uygulamaya çalışır. aşağıdaki bilgi iletisi görünür ve uygulama. özel durumun gerçek nedenini belirlemek için sınayabileceğiniz çok sayıda özelliğe sahiptir. çalışma zamanı eşleşen bir catch işleyici bulamazsa. FormatException türü. ya da eşleşen bir catch işleyici yoksa çağrılan yöntemden hemen çıkılır ve uygulama sürecin tekrarlandığı.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 105 Bir Özel Durumu İşlemek catch işleyici. “2147483648”) olabilir. Sonunda eşleşen bir catch işleyici bulunursa. Özel durumu işlerken. Bir yöntemde oluşan özel durum. FormatException özel durumu oluşturulduğunda. denetim. özel duruma neden olan yönteme dönmez. özel durumun nedenini belirlemenizi sağlayan hata ayıklayıcıya atlar. özel durumun ayrıntılarını içeren nesne fEx değişkenine yerleştirilir. Uygulamayı Microsoft Visual Studio 2008 hata ayıklama modunda çalıştırıyorsanız (uygulamayı çalıştırmak için Debug menüsünden Start Debugging’i seçtiyseniz). özel duruma neden olan hatanın tanımını yapan bir metin içerir. belki ayrıntıları bir günlük dosyasına kaydederken ya da kullanıcıya hata oluştuğunu bildiren ve kullanıcının tekrar denemek isteyip istemediğini soran anlamlı bir ileti görüntülerken bu bilgiyi kullanabilirsiniz. yakalanacak olan özel durumu belirtmek için. Çağrılan yöntem bir try bloğu kullanmıyorsa. Çağrılan yöntem bir try bloğu kullanırsa. catch işleyiciyi içerenden farklı ise. Message özelliği. Örneğin.

NET Framework tarafından sağlanan özel durum yakalama mekanizması oldukça kapsamlıdır.. farklı hatalar farklı hata durumlarını ifade etmek için farklı türde özel durum yaratır. } Birden Çok Özel Durumu Yakalamak C# ve Microsoft . aşağıdaki gibi arka arkaya birden çok catch işleyicisi yazabilirsiniz: try { int leftHandSide = int.. } catch (OverflowException oEx) { //.Text).Parse(rhsOperand. . Böyle durumların üstesinden gelmek için. int answer = doCalculation(leftHandSide..106 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Birden Çok catch İşleyici Kullanmak Kuşkusuz..Text).Text = answer.NET Framework’de birçok farklı özel durum tanımlanmıştır ve yazdığınız . int rightHandSide = int.Parse(lhsOperand. result.ToString(). } catch (FormatException fEx) { //. rightHandSide).

ToString(). Aşağıdaki örnek tüm olası sistem özel durumlarının nasıl yakalanacağını gösterir: try { int leftHandSide = int.. catch işleyiciye özel durumun adını vermeyebilirsiniz: catch { // . } İpucu Bir Exception yakalamak istiyorsanız. bu her zaman önerilmez. Özel durumlar. varsayılan özel durum olduğundan. int rightHandSide = int. işleyici. (“Kalıtım ile Çalışmak” başlıklı Bölüm 12’de kalıtım hakkında daha fazla şey öğreneceksiniz) FormatException ve OverflowException özel durumlarının her ikisi de SystemException (SistemOzelDurumu) ailesindendir. SystemException’ı yakalayan bir işleyici yaratabilirsiniz. meydana gelebilecek her olası özel durumu yakalar.Text = answer.Parse(rhsOperand. Not Exception ailesi. geniş bir özel durum çeşitliliği içerir.Text). int answer = doCalculation(leftHandSide. Bu noktada sormanız gereken son bir soru var: Bir özel durum. try bloğunun sonunda birden çok catch işleyicisi ile eşleşirse ne olur? İki farklı işleyicide FormatException ve Exception yakalarsanız. rightHandSide). Peki. Bu bilgi. } Bununla birlikte. programlarınızın tüm olası özel durumları yakalayacağından ve işleyeceğinden nasıl emin olabilirsiniz? Bu sorunun yanıtı.Parse(lhsOperand. Bunların bazıları. Bu özel durumların her birini ayrı ayrı yakalamak yerine.Text).. result. özel durum ile ilgili yararlı bilgi içerebilir. Bunların birçoğu . kalıtım hiyerarşileri adı verilen aileler olarak düzenlenir.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 107 herhangi bir program bunların birçoğunu oluşturabilmelidir! Kodunuzun oluşturabileceği her özel durum için catch işleyiciler yazmak istemezsiniz. } catch (Exception ex) // bu genel bir catch işleyicidir { //. yukarıdaki catch yapısı kullanıldığında mevcut değildir. hangisi çalışır (ya da her ikisi de çalışacak mıdır)? . Exception yakalarsanız. SystemException ailesi de Exception adı verilen tüm özel durumların büyük ailesinin bir üyesidir. farklı özel durumların bir diğeri ile ilişkili olmasında yatar... özeldir fakat onların da nasıl yakalanacağını anlamak yararlı olacaktır. catch işleyiciye verilen özel durum nesnesi.NET Framework’un çeşitli kısımları tarafından kullanılmak için tasarlanmıştır.

Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step By Step\Chapter 6\ MathsOperators klasöründe yer alan MathsOperators çözümünü açın.) . Bu. Programı kapatmak için Don’t Send düğmesini tıklayın. Visual Studio 2008’i başlatın. Bu nedenle. programın şu anki durumunun sağlamlıktan ne kadar uzak olduğunu gösterecek. bir try bloğundan sonraki genel catch işleyicisinin üstüne yerleştirmelisiniz. 3. Debug düğmesini tıklayın dendiğinde Debug the program bağlantısını tıklayın. Windows XP kullanıyorsanız. Yukardaki iletişim kutusunu görürseniz. Exception için işleyici bulunursa. Bir iletişim kutusunda. Send Error Report ve Don’t Send düğmeleri olan farklı bir iletişim kutusu göreceksiniz. Bir try/catch ifadesi yazın 1. daha özel catch işleyicilerini.108 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Özel bir durum meydana geldiğinde. Left Operand metin kutusuna geçerli olmayan bir metin girin. Farklı aritmetik işleçleri göstermek için kullanılmıştı. Bunun anlamı şudur: FormatException için işleyiciden önce. Debug düğmesi görünmeyecektir. “Değişkenler. Left Operand metin kutusuna John yazıp Calculate düğmesini tıklayın. Not Microsoft Visual C# 2008 Express Edition kullanıyorsanız. Bir form açılır. 2. Denetim Masası’nda problem raporlamayı nasıl yapılandırdığınıza bağlı olarak iletişim kutusunun farklı bir sürümünü (daha sonra gösterilecektir) görebilirsiniz. Özel catch işleyicilerinin hiçbiri özel durumla eşleşmezse. Debug. genel catch işleyici eşleşecektir. özel durum ile eşleşen çalışma zamanı tarafından bulunan ilk işleyici kullanılır ve diğerleri yok sayılır. İşleçler ve Deyimlerle Çalışmak” başlıklı Bölüm 2’de görmüştünüz. aşağıdaki basamaklardaki yönergelerde Close Program düğmesini tıklayın dendiğinde Close the program bağlantısını tıklayın. Left Operand metin kutusunda girdiğiniz metnin uygulamanın başarısız olmasına neden olduğu. (Windows Vista değil. Aşağıdaki alıştırmada bir try bloğu yazacak ve bir özel durumu yakalayacaksınız. işlenmemiş özel durum oluştuğu rapor edilir. 4. Bu çözümü. FormatException işleyicisi hiçbir zaman çalışmayacaktır. Debug menüsünde Start Without Debugging’i tıklayın.

Visual Studio 2008 kullanıyorsanız.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 109 5. Visual C# 2008 Express Edition da kullansanız Visual Studio 2008 hata ayıklayıcı başlar ve özel duruma neden olan kod satırını vurgulayıp özel durum hakkında bazı ek bilgiler görüntüler: . Possible Debuggers listesinden MathsOperators – Microsoft Visual Studio: Visual Studio 2008’i seçin ve Yes’i tıklayın: 6. Visual C# 2008 Express Edition kullanıyorsanız. 7. Debug’ı tıklayın. Visual Studio 2008 de kullansanız. Debug menüsünde Start Debugging’i tıklayın. Close Program’ı tıklayın. Visual Studio Just-In-Time Debugger iletişim kutusundaki. Left Operand metin kutusuna John yazın ve Calculate’i tıklayın.

Left Operand metin kutusuna John yazın ve daha sonra Calculate’i tıklayın. bu yöntemin “John” metnini geçerli bir sayıya ayrıştıramamasıdır.xaml. yönteme dört ifadeden oluşan try bloğunu ekleyin: try { int leftHandSide = int. int answer = doCalculation(leftHandSide.Parse tarafından oluşturulan FormatException özel durumunu yakalar ve daha sonra özel durumun Message özelliğindeki metni. Bu yeni try bloğunun kapanan küme parantezinden hemen sonra bir catch bloğu ekleyin: catch (FormatException fEx) { result. 13. Problem. } Bu catch işleyici. 12.Text = answer. Debug menüsünde Start Without Debugging’i tıklayın.110 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş calculateClick yöntemindeki int. 10. result. int. Uygulama şimdi biraz daha güçlüdür.Text = fEx.ToString(). 8. int rightHandSide = int. formun alt tarafındaki result metin kutusunda gösterir. Not Özel duruma neden olan kodu. catch işleyici başarılı bir şekilde FormatException özel durumunu yakalar ve Result metin kutusuna “Input string was not in a correct format (Giriş dizesi doğru biçimde değildi)” iletisi yazılır.Parse(rhsOperand.Text). Debug menüsünde Stop Debugging’i tıklayın.cs dosyasının kodunu görüntüleyin ve calculateClick yöntemini bulun. Code and Text Editor penceresinde Window1.Parse yöntemini çağırmak yoluyla özel durum oluşturulduğunu görebilirsiniz. rightHandSide). 9.Parse(lhsOperand.Message.Text). } 11. ancak bilgisayarınızda gerçekten kaynak koda sahip olursanız görebilirsiniz. . Aşağıdaki gibi.

yanlış sonuç alırsınız. Visual Studio 2008 programlama ortamına dönmek için Quit’i tıklayın. İpucu Kod içinde int’in en düşük ve en yüksek değerini bulmak isterseniz. hesaplamanın sessizce taşmasına izin veren kod üretir. hesaplama en geniş negatif tamsayı değerine gider ve sonuç –2147483648 olur. (Aslında. bir C# int tam olarak 32 bittir. Birçok durumda. 15. Right Operand metin kutusuna Sharp yazın ve daha sonra Calculate’i tıklayın. int türünün sabit boyutu sorun yaratır. Örneğin. Varsayılan ayar olarak. değeri 2147483647 olan bir int değişkenine 1 eklemek isterseniz ne olur? Bu sorunun cevabı.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 111 14. int. Bu yaklaşımı beğenmediyseniz. temel veri türlerinin sabit boyutları olduğunu da öğrendiniz. try bloğu her iki metin kutusunu da ayrıştıran ifadeleri çevrelediğinden. aynı özel durum işleyicisinin her iki metin kutusundaki kullanıcı girişini işlediğine dikkat edin. Ayrıca. int değerinizin sınırları aşmayacağını bildiğinizden (ya da umduğunuzdan!). + ve * gibi ikili aritmetik işleçlerini int ve double gibi temel veri türleri üzerinde nasıl kullanacağınızı öğrendiniz. Diğer bir deyişle. . int türünün sabit bir boyutu olmasından dolayı.) Bu davranışın nedeni performanstır: tamsayı aritmetiği neredeyse her programda olan bir işlemdir ve her tamsayı deyimine taşma denetimi eklemek performansı oldukça düşürebilir. Denetimli ve Denetimsiz Tamsayı Aritmetiği Kullanmak Bölüm 2’de. bu risk göze alınabilir. Örneğin. John metnini 10 sayısı ile değiştirin. C# derleyicisi.MaxValue (tamsayıMaksimumDeger) alanlarını kullanabilirsiniz.MinValue (tamsayıMinimumDeger) ya da int. taşma denetimi ekleyebilirsiniz. tamsayı aralığının tam olarak ne kadar olduğunu bilirsiniz: –2147483648’den 2147483647’ye kadardır. uygulamanın nasıl derlendiğine bağlıdır.

uygulamanızın gerekli olduğunu düşündüğünüz kısmında aritmetik taşma denetimini etkinleştirmek ya da iptal etmek için checked ve unchecked anahtar sözcüklerini kullanabilirsiniz. aşağıda gösterildiği gibi bloktaki tamsayı hesaplamasında taşma olursa. Build sekmesini tıklayın. Sayfanın sağ alt köşesindeki Advanced düğmesini tıklayın. Advanced Build Settings iletişim kutusunda. Bu anahtar sözcükler proje için belirlenen derleme seçeneğini etkisiz kılar. Örneğin.112 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu Visual Studio 2008’de proje özelliklerini ayarlayarak taşma denetimini etkinleştirebilirsiniz. her zaman OverflowException özel durumu oluşturur. Bir uygulamayı nasıl derlediğinize bakılmaksızın. denetlenmiş ifadelerden birisi yöntem çağrısı ise.MaxValue. Project menüsününde Projeniz Properties’i tıklayın (Projeniz. int number = int. projenizin adıdır. başında checked anahtar sözcüğü ile başlayan bir bloktur.MaxValue.) Proje özellikleri iletişim kutusunda. Console. Denetlenmiş ifadedeki tüm tamsayı aritmetiği.WriteLine(“this will be reached”). checked { int willThrow = number++. unchecked bloktaki hiçbir tamsayı aritmetiği denetlenmez ve asla bir OverflowException özel durumu oluşturmaz. } . Check for arithmetic overflow/underflow onay kutusunu işaretleyin ya da temizleyin. denetim çağrılan yöntemde çalışan koda uygulanmaz. Örneğin: int number = int. Denetlenmiş İfadeler Yazmak Denetlenmiş ifade. Console.WriteLine(“this won’t be reached”). checked bloğu içindeki tamsayı aritmetiğinde yapılır. unchecked blok ifadesi yaratmak için de unchecked anahtar sözcüğünü kullanabilirsiniz. } Önemli Taşma denetimi sadece. unchecked { int wontThrow = number++.

5. sessizce taşan çarpma işlemi vardır. Bileşik işleçler (+= ve -= gibi) ile artırma (++) ve azaltma (--) gibi işleçler aritmetik işleçlerdir ve checked ve unchecked anahtar sözcükleri kullanılarak denetlenebilirler. 4. Şimdi çok büyük iki değeri çarpmayı deneyeceksiniz.cs dosyasını gösteren Code and Text Editor penceresinde. Visual Studio 2008’e dönün. . } return ifadesinde. int türünün 32 bit sınırından sessizce taşmış olan çarpma işleminin sonucudur. Window1. 3. aynı şeydir. Önemli checked ve unchecked anahtar sözcüklerini.) Aşağıdaki alıştırmada. Bu negatif bir değerdir.MaxValue + 1).xaml. checked ya da unchecked anahtar sözcükleri sadece int ve long gibi tamsayı aritmetiklerini denetler.NET Framework sonsuzluk gösterimine sahiptir. parantez içinde yazılmış bir tamsayı deyiminin başında kullanarak bu tür deyimlerdeki taşmayı denetlemek için de kullanabilirsiniz.MaxValue + 1).ToString(). Bu değer. Quit’i tıklayın ve Visual Studio 2008 programlama ortamına geri dönün. Kayan noktalı aritmetikler 0. int willThrow = checked(int.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 113 Denetlenmiş Deyimler Yazmak checked ve unchecked anahtar sözcüklerini. doğru sonuç olamaz. Multiplication’ı seçin ve Calculate’i tıklayın. (. 2. Örneğin: int wontThrow = unchecked(int. Form üzerindeki Result metin kutusunda –1195595903 değeri görünür. Denetlenmiş deyimler kullanın 1. Right Operand metin kutusuna da 9876543 yazın. int rightHandSide) { expression.ToString() + “ * “ + rightHandSide. x += y.Text = leftHandSide. Debug menüsünde Start Without Debugging’i tıklayın. kayan noktalı (tamsayı olmayan) aritmetikleri denetlemek için kullanamazsınız. return leftHandSide * rightHandSide. Şu şekilde görünür: private int multiplyValues(int leftHandSide.0’a bölseniz bile asla özel durum yaratmazlar. Unutmayın. multiplyValues (degerleriCarp) yöntemini bulun. ile x = x + y. Visual Studio 2008 kullandığınızda denetlenmiş aritmetiği nasıl gerçekleştireceğinizi göreceksiniz. Left Operand metin kutusuna 9876543.

bunun gibi durumlar için tasarlanmış çok sayıda özel durum içerir.114 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 6. Visual Studio 2008 programlama ortamına dönmek için Quit’i tıklayın. Özel Durumlar Oluşturmak Tek bir int bağımsız değişkeni alan ve ilgili ayın adını veren monthName (ayAdi) adlı bir yöntem yazdığınızı düşünün. FormatException catch işleyicinin mantığı ile aynıdır. 7. 10. } İpucu Bu catch işleyicinin mantığı. Dönen değer denetlenmiş olacak şekilde. Çarpma işlemi şimdi denetimlidir ve sessizce hatalı bir değer döndürmek yerine bir OverflowException oluşturur. İkinci catch işleyici başarılı bir şekilde OverflowException özel durumunu yakalar ve Result metin kutusunda “Arithmetic operation resulted in an overflow” (Aritmetik işlem bir taşma ile sonuçlandı) iletisini gösterir.Text = oEx. return ifadesini aşağıdaki gibi düzenleyin: return checked(leftHandSide * rightHandSide). Bağımsız değişken 1’den küçük ya da 12’den büyük olduğunda ne döndürmelidir? Bu sorunun en iyi yanıtı yöntem hiçbirşey döndürmemeli ve özel bir durum oluşturmalıdır. Left Operand metin kutusuna 9876543. Right Operand metin kutusuna da 9876543 yazın. Örneğin. Bununla birlikte.NET Framework sınıf kütüphaneleri. monthName(1) “January”(Ocak). monthName(2) “February” (Şubat) değerini döndürür. ancak bunu yapmadan önce C# dili .Message. 8. yine de genel bir Exception catch işleyicisi yazmak yerine bu işleyicileri ayırmak önemlidir çünkü gelecekte bu özel durumları farklı şekilde işlemeye karar verebilirsiniz. Birçok durumda bu sınıflardan birinin sizin özel durumunuza uyduğunu ve onu kullanabileceğinizi göreceksiniz. kendinizinkini kolayca yaratabilirsiniz. Multiplication’ı seçin ve Calculate’i tıklayın. (Uyan bir tane bulamazsanız. 11. calculateClick yöntemini bulun. . calculateClick yöntemindeki FormatException catch işleyicisinin hemen sonrasına aşağıdaki catch işleyiciyi ekleyin: catch (OverflowException oEx) { result. 9. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.

Bölüm 6 Hatalar ve Özel Durumları Yönetmek 115 hakkında biraz daha bilgiye sahip olmanız gerekir. özel durumun ayrıntılarını içerir. bir özel durum oluşturmak için MathsOperators proje kodu ekleyeceksiniz. 2. Aşağıdaki alıştırmalarda. Visual Studio 2008’e dönün. Result metin kutusunda sıfır değeri belirir. case 2 : return “February”. int rightHandSide) { int result = 0.HasValue && addition. Aağıdaki örnekte gösterildiği gibi. Aslında. “Sınıflar ve Nesneleri Yaratmak ve Yönetmek” başlıklı Bölüm 7’de ayrıntılı olarak ele alınmıştır. case 12 : return “December”. doCalculation yöntemi aşağıdaki gibidir: private int doCalculation(int leftHandSide.IsChecked. Kendi özel durumunuzu oluşturun 1. } } throw ifadesinin. Nesne. throw ifadesini kullanarak özel durum oluşturabilirsiniz: public static string monthName(int month) { switch (month) { case 1 : return “January”.NET Framework ArgumentOutOfRangeException (BagimsizDegiskenLimitDisindaÖzelDurumu) sınıfı uygundur.IsChecked. default : throw new ArgumentOutOfRangeException(“Bad month”).Value) result = addValues(leftHandSide. bir kurucu kullanarak Message özelliğini yerleştirecek olan bir dize ile başlatılır. yeni bir ArgumentOutOfRangeException nesnesi yaratan deyim kullanır. . Right Operand metin kutusuna 36 yazın ve Calculate’i tıklayın. Bu nesne. var olan . Debug menüde Start Without Debugging’i tıklayın. Left Operand metin kutusuna 24. 4. if (addition. bir hata iletisi de dahil olmak üzere. Result metin kutusunda bir tanılama iletisi görüntülemek daha iyi olacaktır.xaml. Buradaki örnek.. hiçbir işleci seçmediğiniz hemen anlaşılmamaktadır. 3. . Visual Studio 2008 programlama ortamına dönmek için Quit’i tıklayın. ortaya çıkaracağı bir özel durum nesnesine ihtiyacı vardır.) Bu durumda. 5.cs’i gösteren Code and Text Editor penceresinde doCalculation (hesaplamaYap) yöntemini bulun. Kurucular.. Window1. rightHandSide).

Value) result = multiplyValues(leftHandSide.116 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş else if (subtraction. 6. Close Program’ı tıklayın.HasValue && subtraction.) Hiçbir düğme seçili değilse. kullanıcının o seçeneği seçip seçmediğini gösteren IsChecked (Secildi) adı verilen bir özelliğe sahiptir. else if (remainder.Value) result = remainderValues(leftHandSide. rightHandSide). Form üzerindeki result metin kutusuna ileti yazmak için. Uygulama bir özel durum oluşturmuştur fakat kodunuz bunu yakalamaz.IsChecked.Value özelliği de durumun ne olduğunu gösterir. 9. (Seçenek düğmeleri birbirini dışlayan özelliktedir. .IsChecked.IsChecked. belirli bir değer içerebilir ya da tanımlanmamış durumda olabilir.HasValue && division. rightHandSide).HasValue && remainder. multiplication (çarpma). subtraction (çıkarma). Hatayı bulma ve uyarma ile hatayı yakalama ve işlemeyi ayırmak daha iyidir. hiçbir if ifadesi true olmayacaktır ve result değişkeni başlangıç değerinde (sıfır) kalacaktır. (“Değerleri ve Başvuruları Anlamak” başlıklı Bölüm 8’de nullable değerler ile ilgili daha çok şey göreceksiniz. yani kullanıcı sadece bir seçenek düğmesi seçebilir. IsChecked. Left Operand metin kutusuna 24. seçenek düğmesinin tanımlanmış durumda olup olmadığını gösterir ve tanımlanmışsa. seçilmemişse false değerindedir. } addition (toplama). else if (multiplication. Basamaklanmış if ifadesi hangi seçenek düğmesinin seçilmiş olduğunu bulur.Value özelliği Boolean türündedir ve düğme seçilmiş ise true. bu çözüm iyi bir fikir değildir çünkü ileti yazmak bu yöntemin gerçek amacı değildir.HasValue && multiplication. IsChecked. if-else ifadelerinin sonuna (return ifadesinden hemen önce) başka bir else ifadesi ekleyin ve aşağıdaki gibi InvalidOperationException (GeçersizIslemOzelDurumu) özel durumunu yaratın: else throw new InvalidOperationException(“no operator selected”). rightHandSide). Bununla birlikte. 8. 7.IsChecked. Right Operand metin kutusuna 36 yazın ve Calculate’i tıklayın.IsChecked.HasValue özelliği. else if (division. division (bölme) ve remainder (kalan) alanları form üzerindeki seçenek düğmeleridir.IsChecked. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. rightHandSide). return result. Her biri.Value) result = subtractValues(leftHandSide. if-else basamaklanmış ifadesine bir tane daha else ekleyerek problemi çözmeye çalışabilirsiniz. IsChecked özelliği nullable (boş olabilir) değer özelliğine bir örnektir. Uygulama sonlanır ve Visual Studio 2008’e dönersiniz. Bu değişken yöntem tarafından döndürülen değeri tutar.IsChecked.IsChecked.) IsChecked.Value) result = divideValues(leftHandSide. Özel durum iletişim kutusu açılır.

Kendi yarattığınız özel durumu yakalayın 1. throw ifadesi yazdınız ve bir özel durum oluşturduğunu doğruladınız. Ama hala yakalanmayacak olan ve uygulamanın çökmesine neden olabilecek özel durumlar var. 3. Result metin kutusunda “no operator selected” (hiçbir işleç seçilmedi) iletisi görünür. Bazı durumlarda. hiçbir seçenek düğmesi seçilmediğinde oluşturulan InvalidOperationException özel durumunu yakalar.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 117 Şimdiye kadar. Quit’i tıklayın. Debug menüsünde Start Without Debugging’i tıklayın. kayan noktayı sıfıra bölmekten farklı olarak bir özel durum oluşturur. tüm işlenmemiş özel durumları yakalayacaktır. Fakat daha iyi bir çözümü catch işleyicilerinin sonuna Exception’ı yakalayan genel catch işleyici eklemektir. sıfıra bölmeye çalışırsanız. özel durumun yöntemin çağrıldığı noktaya yayılmasına izin vermek daha yararlıdır. işlenmeyen bir DivideByZeroException’ı (SifiraBolunmeOzelDurumu) oluşur. Window1.cs’yi gösteren Code and Text Editor penceresinde calculateClick yöntemini bulun. İşlenmemiş özel durumları yakalayın 1. 4. oluşturduğunuz uygulamanın doğasına bağlıdır. Uygulama şimdi eskisinden daha sağlam. } Bu kod. Left Operand metin kutusuna 24.xaml.Message. özel durumları oluşur oluşmaz yakalamak önemlidir. . Bu. İpucu İşlenmemiş tüm özel durumların açık bir şekilde bir yöntemde yakalanıp yakalanmama kararı. Örneğin. Window1. 2. (Tamsayıyı sıfıra bölmek. calculateClick yöntemindeki mevcut iki catch işleyicinin hemen altına ekleyin: catch (InvalidOperationException ioEx) { result. Bazı durumlarda ise.Text = ioEx.xaml.) Bunu çözmenin bir yolu calculateClick yönteminin içine daha fazla sayıda catch işleyici yazmaktır.cs’yi gösteren Code and Text Editor penceresinde calculateClick yöntemini bulun. Şimdi bu özel durumu işlemek için catch işleyici yazacaksınız. 5. Right Operand metin kutusuna 36 yazın ve Calculate’i tıklayın. Aşağıdaki catch işleyiciyi.

Şimdi. reader. string line.Message. Ne de olsa kodun içindedir: TextReader reader = src. Result metin kutusunda hala “no operator selected” (hiçbir işleç seçilmedi) iletisi olduğunu doğrulayın. } reader. Aşağıdaki örneğe bakın. 4. Left Operand metin kutusuna John yazın ve daha sonra Calculate’i tıklayın. Bu ileti FormatException işleyicisi tarafından üretilmişti. özel durumlar oluşmasına neden olacağını bildiğiniz bazı hesaplamalar yapmaya ve tüm özel durumların doğru olarak işlendiğini doğrulamaya çalışacaksınız.Text += line + “\n”. Result metin kutusunda “Input string was not in a correct format” (Giriş metni doğru biçimde değil) hata iletisinin göründüğünü doğrulayın. Yani. Debug menüsünde Start Without Debugging’i tıklayın. tüm işlenmemiş özel durumları yakalayacaktır. Bu ileti genel Exception işleyici tarafından üretilmişti. while ((line = reader.Close (okuyucu. hangi türde olursa olsun.Kapat) çağrısının her zaman oluşacağını varsaymak çok kolaydır. Quit’i tıklayın. Bu ileti. 5. 6. Right Operand metin kutusuna 0 yazın. Bir finally Bloğu Kullanmak Bir özel durum oluşturulduğunda. Right Operand metin kutusuna 36 yazın ve Calculate’i tıklayın. Divide seçenek düğmesini seçin ve Calculate’i tıklayın. . programın akışını değiştireceğini unutmamak önemlidir. çünkü önceki ifade bir özel durum oluşturabilir. Mevcut catch işleyicilerinin sonuna aşağıdaki catch işleyiciyi ekleyin: catch (Exception ex) { result.ReadLine()) != null) { source. } Bu catch işleyici. Left Operand metin kutusuna 24. Left Operand metin kutusuna 24. bir ifadenin her zaman bir önceki ifade bittiğinde çalışacağını garanti edemezsiniz.Text = ex. InvalidOperationException işleyici tarafından üretilmiştir.OpenText(). 3.Close().118 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 2. 7. Result metin kutusunda “Attempted to divide by zero” (sıfıra bölmeye çalışıldı) hata iletisinin göründüğünü doğrulayın.

bir işleyici bulmak için çağrılan yöntemleri araştırması gerekirse).Close yöntemi çağrılmazsa. Her durumda. ilk olarak finally bloğundan sonraki özel durum işleyici çalışır. finally bloğu. } } finally { if (reader != null) { reader.OpenText().Close yöntemini çağırdığınızdan emin olmalısınız. } } Bir özel durum oluşturulsa da. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. bir de veritabanı bağlantılarını düşünün.Close ifadesinin her zaman çalışacağını garanti eder. bir try bloğundan hemen sonra ya da try bloğundan sonraki son catch işleyiciden hemen sonra ortaya çıkar. Bir ifade. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 7’e geçin.Text += line + “\n”. string line. Özel durum yerel olarak yakalanmazsa (çalışma zamanının.OpenText yönteminin çağrılması başarıyla sonuçlanırsa. bu ifadenin uygulanmaması kaynağın alıkonması olarak sonuçlanır. reader. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. “Çöp Toplama ve Kaynak Yönetimini Kullanmak” başlıklı Bölüm 4’te bu problemi çözmenin başka bir yolunu göreceksiniz. finally bloğu. Bir özel durum oluşturulur ve yerel olarak yakalanırsa. ifadeyi bir finally bloğunun içine yazmaktır. Program finally bloğu ile ilişkili try bloğuna girdiği sürece finally bloğu her zaman çalışacaktır (bir özel durum meydana gelse bile). belirli bir ifadenin çalışmaması sorun değildir. er ya da geç dosya işleyici çalışmayacaktır ve daha fazla dosya açamayacaksınız demektir. reader. Save iletişim kutusu görünürse.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 119 Bazen. finally bloğu çalışır.) Bir özel durum oluşturulsa da oluşturulmasa da. ilk olarak finally bloğu çalışır. ifadenin her zaman çalıştığından emin olmanın yolu. (Dosya işleyiciyi önemsiz bulduysanız. try { reader = src. while ((line = reader. bir kaynağı tutar (bir dosya işleyici) ve kaynağı serbest bırakmak için reader. fakat birçok durumda bu büyük bir problem olabilir. Bu örnek tam da şu durumu gösterir: src. reader.Close(). bir önceki ifadede tutulan kaynağı serbest bırakırsa.ReadLine()) != null) { source.Close probleminin çözümü aşağıdaki gibidir: TextReader reader = null. n .

.. Örneğin: try { . } Bazı kodların....MaxValue. } catch (Exception ex) { . } Belirli bir özel durumu yakalamak Belirli özel durum sınıfını yakalayan bir catch işleyici yazın...120 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Bölüm 6 Hızlı Başvuru Bunun İçin Bir özel durum yaratmak Tamsayı aritmetiğinin her zaman taşma için denetlendiğinden emin olmak Şunu Yapın Bir throw ifadesi kullanın. } finally { // her zaman çalışır } . } Bütün özel durumları bir catch işleyicisi ile yakalamak Exception sınıfını yakalayan bir catch işleyicisi yazın. Örneğin: try { . Örneğin: throw new FormatException(source). Örneğin: int number = Int32. checked anahtar sözcüğü kullanın... Örneğin: try { . özel durum oluşsa dahi her zaman çalıştıklarından emin olmak Kodu bir finally bloğunun içine yazın. } catch (FormatException fEx) { . checked { number++..

. . . . . . . . . . . . . . . . . . . . . . . . . . Bölüm 12 . . Çöp Toplama ve Kaynak Yönetimini Kullanmak . . . . . Numaralandırma ve Yapılar ile Değer Türleri Yaratmak . . . . . . . . . . . . . . . Bölüm 14 . . . . . . . . . . . . Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak . . . . . . . . . . . . . Bölüm 11 . . . . . . Bölüm 8 . . . . . Parametre Dizilerini Anlamak . Sınıflar ve Nesneleri Yaratmak ve Yönetmek . . . Bölüm 13 . . . . . . . . . . . . . . . . . . . . . . . . Değerleri ve Başvuruları Anlamak . . . . . . . . . . . . . . . . . . . . . Bölüm 9 . . . . . . . . . . . . . . . Kalıtım ile Çalışmak . . . . . . . . . . . Dizileri ve Koleksiyonları Kullanmak . . . . . 123 145 167 185 207 217 239 257 Kısım II 121 . . Bölüm 10 . . . . . . . . . . . . . . . . . . . . . . . . . .Adım Adım Microsoft Visual C# 2008 C# Dilini Anlamak Bu kısımdaki konular: Bölüm 7 . . . . . . . . . .

.

Konsol ve Özel Durum sınıfları da dahil olmak üzere bunların bir çoğunu kullandınız.) ve ortak öznitelikleri (bir direksiyonları. Bir varlık (entity). durdurulabilir. Kendi kurucularınızı yazmak ve çağırmak. Sınıflar uygulamalar tarafından ayarlanmış varlıkları modellemek için uygun mekanizma sağlar. Sınıflandırmayı Anlamak Sınıf (class). Microsoft . “Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş” başlıklı Kısım 1’de değişkenlerin bildirimini. Artık yöntemleri ve verileri kendi sınıflarınızda birleştirme aşamasına geçmek için yeterli bilgiye sahipsiniz. binlerce sınıf içerir. Bu. bir motorları vs.) vardır. hızlandırılabilir. Bir sınıf tasarladığınızda. bilgileri sistematik olarak anlamlı bir şekilde düzenlemiş olursunuz.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n İlişkili yöntemler ve veri öğeleri kümesi içeren bir sınıf tanımlamak. Örneğin. Herhangi bir sistemin tasarım süreci kısmı. karmaşık 123 . “C# Dilini Anlamak” başlıklı Kısım II’deki bölümler. vs. Bir sözcük. müşteri gibi özel bir öğeyi ya da işlem gibi daha soyut bir şeyi gösterebilir. yöntemleri çağırmayı ve bir yöntem oluştururken gereken ifadeleri yazmayı öğrendiniz. sınıflandırma adımlarından birisidir ve yalnızca programcıların değil herkesin yaptığı bir şeydir. Bu ortak davranışlara ve özniteliklere sahip bütün nesneleri anlatmak için araba sözcüğünü kullanırsınız. sınıflandırma (classification) teriminin kök kelimesidir. ne anlama geldiği konusunda herkes fikir birliğine vardığında tümüyle doğru iş görür.NET Framework. Bir kurucu çağırmak için new anahtar sözcüğünü kullanarak nesneler yaratmak. önemli varlıkları belirlemek ve daha sonra da hangi bilgilerin gerekli olduğunu ve hangi işlevlerin gerçekleştirilmesi gerektiğini bulmakla ilgilidir. Bir sınıfın tuttuğu bilgiyi alanlar olarak saklarsınız ve sınıfın gerçekleştirebileceği işlemleri uygulamak için yöntemleri kullanırsınız. değerler yaratmak için işleçlerin kullanımını. bütün arabaların ortak davranışları (yönlendirilebilir. public ve private anahtar sözcüklerini kullanarak üyelerin erişilebilirliğini denetlemek. static anahtar sözcüğünü kullanarak aynı sınıfa ait tüm örnekler tarafından paylaşılabilecek yöntemler ve veri yaratmak. kendi sınıflarınızı yaratmak için gerekli bilgileri sağlar.

Sınıfın. çeşitli yöntemleri gerçekleştirmek için her tür dahili aşamanın bilgisine ihtiyacı olabilir.124 Kısım II C# Dilini Anlamak ama kesin fikirleri kısa bir biçimde ifade edebilirsiniz. Sınıflandırmanın. bir yöntem (dairenin alanını hesaplamak için) ve bir parça veri (dairenin yarıçapı) içeren Circle (Daire) adlı bir C# sınıfı görebilirsiniz: class Circle { double Area() { return Math. sadece sınıfın bir örneğini yaratır ve o sınıfın yöntemini çağırır. kapsülleme bazen bilgi gizleme olarak adlandırılır. } int radius. } . diğer bir deyişle sınıfın kullanımını denetlemek. n Bir Sınıfı Tanımlamak ve Kullanmak C#’da. Console sınıfının. küme parantez arasında sınıfın gövdesinde yer alır. Console. diğer bir deyişle sınıflandırmayı desteklemek. Sınıfın veri ve yöntemleri. önemli bir sınıf tanımlama ilkesidir. Bu nedenle. Örneğin. Kapsüllemenin iki önemli kullanımı vardır: n Yöntem ve verileri bir sınıf içinde birleştirmek. Yöntemler yapmaları söylenen şeyleri yaptığı sürece. Aşağıda. Kapsüllemenin Amacı Kapsülleme.PI * radius * radius. bir sorunun ve çözümünün doğasında bulunan farklı kavramları sınıflandırarak ve daha sonra da bu sınıfları bir programlama dili ile modelleyerek program yazmaya çalışmak anlamlı olur. ekrana yazmak için veri üzerinde nasıl düzenlemeler yaptığıyla ilgili karışık ayrıntıları bilmek istemezsiniz. sınıfı kullanan programdan gizlenir. program yöntemlerin nasıl çalıştığı ile ilgilenmez. Bu tam da Microsoft Visual C# gibi modern nesne yönelimli programlama dillerinin yaptığı şeydir. düşünme ve iletişim kurma şeklimize ne kadar köklü biçimde etkisi olduğunu anladığımıza göre.WriteLine yöntemini çağırdığınızda. Yöntem ve verilerin erişilebilirliklerini denetlemek. Sınıflandırma olmadan. Ana fikir şudur: Sınıf kullanan bir program o sınıfın nasıl çalıştığını bilmek durumunda değildir. Bu aşama bilgisi ve işlemler. yeni bir sınıf tanımlamak için class anahtar sözcüğünü kullanırsınız. insanların düşünebileceklerine ya da iletişim kurabileceklerine inanmak güçtür.

Bunun bir nedeni. pi sayısı değerini (3. Şimdilik. Bununla birlikte. doğrudan aynı türde başka bir değişkene atayabilirsiniz: Circle c. Bunu sınıf türünde değişkenlerle yapamazsınız. bir sınıfın yeni bir örneğini (daha çok nesne olarak adlandırılır) yarattığını bilmeniz yeterlidir. C#’da değişkenlere sabit sınıf değerleri atamak için bir sözdizimi yoktur. aslında burada hemen hemen yeni bir sözdizimi yok. çalışma zamanı tarafından değişkenler ve sınıf türleri için ayrılan ve yönetilen bellek ile ilgilidir (Bu konu. olağan yöntemler (Area gibi) ve alanlar (radius gibi) içerir. // Bir Circle değişkeni yarat // Başlat new anahtar sözcüğünün kullanımına dikkat edin. daha önce gördüğünüz diğer türlerin kullanımı ile aynıdır. i = 42. aşağıdaki gibi sınıfın bir örneğini. matematik sabitleri içeren alanlar ve matematik hesaplamaları gerçekleştirmek için yöntemler içerir. Örneğin: Circle c. Math. Circle sınıfının kullanımı. o türün program çalıştığında yaratılan bir örneğidir.14159265358979323846) içerir.PI alanı. c = new Circle().Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 125 Not Math (Matematik) sınıfı. Nesne ise. Daha önce. Önemli sınıf ve nesne terimlerini karıştırmayın. Bölüm 2’de değişkenleri nasıl bildireceğinizi ve Bölüm 3’te de yöntemlerin nasıl yazıldığını görmüştünüz. Sınıf gövdesi. Bununla birlikte. c = new Circle(). (42‘nin Circle eşdeğeri nedir?) Bir diğer neden ise. Sınıf bir türün tanımıdır. basit olarak bir değer atardınız: int i. Türünü Circle olarak belirttiğiniz bir değişken yaratırsınız ve daha sonra da değişkene geçerli bir başlangıç verisi atarsınız. . sadece new anahtar sözcüğünün. d = c. Circle d. “Değerler ve Başvuruları Anlamak” başlıklı Bölüm 8’de ayrıntılarıyla incelenmiştir). Bölüm 8’de ele alınan nedenlerden dolayı. int ya da float türünde bir değişkeni başlatırken. bir sınıf içindeki değişkenlere alan adı verildiğini hatırlayın. bu göründüğü kadar kolay değildir.

Yöntemlerinizi ve verilerinizi bir sınıf içinde kapsüllediğinizde. Bu nedenle. Area yöntemi Circle sınıfı içinde olduğundan radius alanına erişebilir. Bu. bildiriminden önce private anahtar sözcüğünü kullanın. sınıf dışından erişilemez. program içinde bir Circle nesnesi yaratabilseniz bile. fakat karışıklıktan kaçınmak için açık bir şekilde yöntemin ya da alanın private olduğunu belirtmek iyi bir uygulamadır. } private int radius. radius alanının private olarak bildirildiğine dikkat edin. n İşte yine Circle sınıfı. Varsayılan ayar olarak yöntem ve alanlar private’dır. Yani.126 Kısım II C# Dilini Anlamak Erişilebilirliği Denetlemek Ne yazık ki. Circle sınıfı içinden erişilebilir. Circle sınıfının pratik bir kullanımı yoktur. O yöntem ya da alanın public olduğunu bildirmek için. o yöntem ya da alan public (genel) olarak değerlendirilir. Bu defa. false ya da null başlangıç değeri otomatik olarak atanır. Bunun anlamı. Area bir public yöntem ve radius da bir private alan olarak bildirilmiştir: class Circle { public double Area() { return Math. İpucu Bir sınıftaki alanlara türlerine bağlı olarak 0. sınıf hala sınırlı değerdedir çünkü radius alanını başlatmanın bir yolu yoktur. bildiriminden önce public anahtar sözcüğünü kullanın.PI * radius * radius. sınıfın neden çok fazla kullanılmadığını gösterir-henüz! Bununla birlikte. Her bildirimde anahtar sözcüğünü yinelemelisiniz. sınıf dış dünyaya karşı bir sınır oluşturur. bir alan ya da yönteme sınır dışından erişilebileceklerini ya da erişilemeyeceklerini public ve private anahtar sözcükleri ile denetleyebilirsiniz: n Bir yöntem ya da alana sadece bir sınıfın içinden erişilebiliyorsa. Bunu çözmek için bir kurucu kullanabilirsiniz. Bununla birlikte. bu nesnenin radius alanına ya da Area yöntemi çağrısına ulaşamazsınız. Yöntem ya da alanın private olduğunu bildirmek için. } Not C++ ile program geliştirenler. sınıf içindeki diğer yöntemler tarafından görülebilir fakat sınır dışındaki dünya tarafından görülemez. alanlara başlangıç değeri verilmesini açık bir şekilde belirtmek yine de iyi bir uygulamadır. Sınıf içinde tanımlanan alanlar (radius gibi) ve yöntemler (Area gibi). Bir yöntem ya da alana hem içerden hem de dışarıdan erişilebiliyorsa. . public ve private anahtar sözcüklerinden sonra iki nokta üst üste olmadığını farketmişlerdir. o yöntem ya da alan private (özel) olarak değerlendirilir. Bununla birlikte.

Kurucularla Çalışmak Bir nesne yaratmak için new anahtar sözcüğü kullandığınızda. (İlk olarak Pascal dilinde kullanılmıştır. Aşağıdaki örnek Circle sınıfının varsayılan kurucu ile radius alanını 0 değeri ile başlatmasını göstermektedir: class Circle { public Circle() { radius = 0. bu bellek alanını sınıf tarafından tanımlanmış alanlar ile doldurması ve daha sonra herhangi bir başlatma gerektiğinde bunu gerçekleştirmek için bir kurucuya başvurması gerekir. Siz bir kurucu yazmazsanız. Kurucu (constructor). radius. Önemli Adlarının arasındaki tek fark küçük/büyük harf kullanımı olan. sadece.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 127 Adlandırma ve Erişilebilirlik Alanlar ve yöntemler için aşağıdaki adlandırma kuralları. private olduğundan “r” ile (“R” değil) başlar. camelCase adlandırma kuralı olarak bilinir. bir değer döndürmeyen public bir yöntem ekleyin. Çalışma zamanının. sınıf ile aynı adda. Bu sistem. } // varsayılan kurucu . derleyicinin ürettiği varsayılan kurucu gerçekte hiçbir şey yapmaz. sınıf tanımlamasını kullanarak nesneyi kurmak zorundadır. işletim sisteminden bir parça bellek alanı alması. sınıf üyelerinin erişilebilirliğine dayanır: n public tanımlayıcılar büyük harfle başlamalıdır. iki public sınıf üyesi bildirmeyin. Örneğin. Bildirirseniz. derleyici sizin için otomatik olarak varsayılan kurucu üretir.) Kendi varsayılan kurucunuzu kolayca yazabilirsiniz. bir kurucuya sahip olmak zorundadır. Bu nedenle private bir kurucu adı da büyük harfle başlamalıdır. çalışma zamanı. Area. public olduğundan “A” ile (“a” değil) başlar. (Bununla birlikte. bir sınıfın örneğini yarattığınızda otomatik olarak çalışan özel bir yöntemdir. Örneğin. n Bu kurala tek bir istisna vardır: sınıf adları büyük harfle başlamalıdır ve kurucuların adları kendi sınıf adları ile eşleşmelidir. Her sınıf. Bu sistem. Sınıf ile aynı ada sahiptir ve parametreler alabilir fakat bir değer döndürmez (void bile). PascalCase adlandırma kuralı olarak bilinir. Microsoft Visual Basic gibi küçük/büyük harfe duyarlı olmayan programlama dillerinde sınıfınız kullanılamaz.) private tanımlayıcılar küçük harfle başlamalıdır.

PI * radius * radius. Bütün Circle nesnelerinin alanları her zaman 0 olacaktır. Bu. yarıçapı 0 olarak atar ve 0 olarak kalır. Private kurucular da kullanışlıdır fakat şu an konu dışındadır. “Kurucuları Aşırı Yüklemek” başlıklı bir sonraki bölümde de göreceğiniz gibi. herhangi bir parametre almayan kurucudur.Area(). kurucu private olacaktır (diğer yöntemler ve alanlar gibi). Console. Bununla birlikte. Kurucuları Aşırı Yüklemek Sona yaklaştınız fakat henüz bitmedi. radius alanı private’dır ve başlangıç değeri atandıktan sonra değiştirilemez. Bu nedenle private kurucuların değerli olmadığını düşünebilirsiniz. onu yeni yaratılmış bir Circle nesnesine ayarlayabilir ve daha sonra Area yöntemini çağırabilirsiniz. Aşağıdaki gibi. Bu problemi çözmenin bir yolu.128 Kısım II C# Dilini Anlamak public double Area() { return Math. } // varsayılan kurucu . Kurucu private ise. c = new Circle(). double areaOfCircle = c. her iki durumda da varsayılan kurucudur. Çünkü varsayılan kurucu. Circle sınıfına radius parametresi ile bir kurucu ekleyebilirsiniz: class Circle { public Circle() { radius = 0. Circle sınıfını kullanabilir ve Area yöntemini test edebiliriz. Bu anahtar sözcük yazılmazsa. Derleyici de yaratmış olsa siz de yazmış olsanız farketmez. varsayılan olmayan kurucular da (parametreler alan kurucular) yazabilirsiniz. Şimdi. Şimdi bir Circle değişkeni bildirebilir. } Not C# terminolojisinde. } private int radius. Circle sınıfının parçası olmayan yöntemlerden Circle nesneleri yaratabilmenizi engeller. Kurucunun public olarak işaretlendiğine dikkat edin. kurucuların yalnızca özel bir tür yöntem olduklarını ve bütün yöntemler gibi aşırı yüklenebileceklerini anlamaktır. default (varsayılan) kurucu. bir kurucunun da farklı sürümlerini yazabilirsiniz. sınıf dışında kullanılamaz. Bir Circle nesnesinde Area yöntemine başvurmak için nokta işaretini nasıl kullanacağınıza dikkat edin: Circle c. hala son bir problem var.WriteLine yönteminin her biri farklı parametreler alan birkaç sürümü olduğu gibi.

C# dilinin garipliğinin farkında olmalısınız: bir sınıf için kendi kurucunuzu yazarsanız. İstediğiniz sırada tanımlayabilirsiniz.PI * radius * radius. program geliştiricinin düzenleyebileceği kaynak kodun form düzenlemesi değiştiğinde. Bu nedenle. bir ya daha fazla parametre alan bir kurucu yazdıysanız ve yine de bir varsayılan kurucu istiyorsanız. böylece geniş bir sınıfın tanımını küçük ve daha kolay yönetilebilir parçalar halinde düzenleyebilirsiniz. derleyici new (yeni) işlecinde belirlediğiniz parametrelere dayanarak. Bu örnekte. Kısmi Sınıflar Bir sınıf.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 129 public Circle(int initialRadius) // aşırı yüklenmiş kurucu { radius = initialRadius. bunu kendiniz yazmak zorunda kalırsınız. alan ve kurucuların yanı sıra. Yüksek derecede işlevsel olan bir sınıf oldukça geniş olabilir. sonraki bölümlerde incelenecek olan diğer öğeleri içerir. Windows Presentation Foundation (WPF) uygulamaları için kullanılır. derleyici varsayılan kurucuyu oluşturmaz. yeni bir Circle nesnesi yaratırken bu kurucuyu kullanabilirsiniz: Circle c. bu nedenle derleyici int parametre alan kurucuya başvuran bir kod üretir. } Not Bir sınıftaki kurucuların sırası önemsizdir. int türü parametre geçirdiniz. . çok sayıda yöntem. } private int radius. Visual Studio tarafından üretilen koddan ayrı bir dosyada saklandığı. Bu özellik. Microsoft Visual Studio 2008 tarafından. } public double Area() { return Math. c = new Circle(45). Daha sonra. hangi kurucunun çağrılacağını bulur. kaynak kodu bir sınıf için ayrı ayrı dosyalara ayırabilir. Uygulama oluşturduğunuzda. C# ile.

ve y. iki boyutlu alanda nokta modelleyen bir sınıf bildireceksiniz. } Ayrı ayrı dosyalara ayrılmış olan bir sınıfı derlediğinizde.cs içeriği de şu şekildedir: partial class Circle { public double Area() { return Math.PI * radius * radius. circ1. new anahtar sözcüğünü kullanarak ve kurucuları çağırarak sınıfın oluşumlarını yaratacaksınız. } private int radius.cs dosyasını çift tıklayarak. Sınıf.cs içeriği aşağıdaki gibi olur: partial class Circle { public Circle() // varsayılan kurucu { radius = 0. } } circ2. circ1. 3.130 Kısım II C# Dilini Anlamak Bir sınıfı birçok dosyaya ayırdığınızda. 2.koordinat değerlerini tutan iki private alan içerecek ve bu alanlara başlangıç değeri vermek için kurucular sağlayacak.cs (kurucuları içeren) ve circ2. her bir dosyada partial anahtar sözcüğünü kullanarak sınıfın kısımlarını tanımlarsınız. dosyayı Code and Text Editor penceresinde görüntüleyin. . Circle sınıfı. } public Circle(int initialRadius) // aşırı yüklenmiş kurucu { radius = initialRadius. noktanın x. Örneğin. Aşağıdaki alıştırmada. Kurucular yazın ve nesneler yaratın 1. Visual Studio 2008’i başlatın.cs (yöntemleri ve alanları içeren) adı verilen iki dosyaya ayrılırsa. derleyiciye tüm dosyaları sağlamanız gerekir. Program. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 7\Classes klasöründe bulunan Classes projesini açın. Solution Explorer’da.

Bu try/catch bloğunun herhangi bir özel durumu yakalayacağını ve işleyeceğini bilerek. 8. 9.ve y-koordinat değerleri ile tanımlanan noktanın konumunu göstermek için bu sınıfı kullanacaksınız. Bununla birlikte. program çalıştığında {0} yerine x değeri ve {1} yerine de y değeri gelecektir. x. Build menüsünde Build Solution’ı tıklayın. Point. bir try bloğunda bulunan ve bir catch işleyici tarafından izlenen bir çağrı ile Entrance (Giriş) yöntemini çağırır. Program. Code and Text Editor penceresinde Point. Entrance yönteminin gövdesindeki // to do yorum satırı yerine aşağıdaki kodu yazın: Point origin = new Point().Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 131 4. Yukardaki ifadede. bu kurucu için C# kodu göremezsiniz. Bu dosya. Build menüsünde Build Solution’ı tıklayın. y:{1}”. Derleyici Point sınıfı için varsayılan kurucuyu yazdığından.Point’ does not contain a constructor that takes ‘0 ‘ arguments . x ve y adında iki int bağımsız değişken alan ve bu bağımsız değişkenlerin değerlerini konsolda görüntülemek için Console. // to do yorum satırını.cs dosyasını görüntüleyin.cs dosyasında Point sınıfına dönün. Point (Nokta) adında bir sınıf tanımlar.WriteLine(“x:{0}. Program sınıfındaki Main (Ana) yöntemini bulun. Main yöntemi. Derleyici şu hatayı verir: ‘Classes. y). } } Not Console. int y) { Console. x.cs dosyasına dönün ve Program sınıfının Entrance yöntemini bulun. Point sınıfı aşağıdaki gibi görünmelidir: class Point { public Point(int x. normalde Main içine yazılan kodu Entrance yöntemi içine yazabilirsiniz. Point sınıfı şu anda boştur. 5. 6.WriteLine yöntemini çağıran bir public kurucu ile değiştirin. 7. kod sorunsuzca çalışır. çünkü derleyici herhangi bir kaynak dil ifadesi üretmez.WriteLine yönteminin yer tutucu olarak {0} ve {1} kullandığını hatırlayın.

Build menüsünde Build Solution’ı tıklayın. y:{1}”.132 Kısım II C# Dilini Anlamak Entrance’da varsayılan kurucuya yapılan çağrı daha fazla çalışmayacaktır. Şimdi. Konsolda aşağıdaki iletiyi görüntüleyen program oluşur ve çalışır: default constructor called x:1024. int y) { Console. 12. Debug menüsünde Start Without Debugging’i tıklayın. 1024 × 1280 çözünürlükteki bir ekranın sağ alt köşesinin koordinatlarını gösteren 1024 ve 1280 değerlerini uygulayın. Point sınıfı şimdi şu şekilde görünmelidir: class Point { public Point() { Console. Entrance yöntemi şimdi şu şekilde görünmelidir: static void Entrance() { Point origin = new Point(). x. Program şimdi başarılı olarak oluşmalıdır. konsola “default constructor called” (varsayılan kurucu çağrıldı) yazmak için Console. . Point sınıfına. } public Point(int x. 1280). Program. yeni Point nesnesine ilk atamayı yapan bir ifade içerecek biçimde değiştirin. Entrance yönteminin gövdesini.WriteLine(“x:{0}. Point sınıfı için kendi kurucunuzu yazdınız. Point bottomRight = new Point(1024.WriteLine(“default constructor called”).cs dosyasında. bu nedenle derleyici otomatik olarak bir kurucu oluşturmamıştır. } } 11.ve y-koordinatlarını göstermek için Point sınıfına iki int alanı ekleyecek ve bu alanların ilk atamalarını yapmak için kurucuları düzenleyeceksiniz. } 13. y). Programı sonlandırmak ve Visual Studio 2008’e dönmek için Enter tuşuna basın. 10. çünkü artık varsayılan kurucu yoktur. bottomRight (altSağ) adında Point türünde bir değişken bildiren ve iki bağımsız değişken alan kurucu kullanarak. y:1280 14. noktanın x.WriteLine yöntemini çağıran bir public varsayılan kurucu ekleyin. Şimdi bu sorunu kendi varsayılan kurucunuzu yazarak çözeceksiniz.

} Şimdi. } . y. Bir değişkene this ön ekini eklemek. ifadesinde derleyici ilk x’in alan ikincisinin parametre olduğunu nasıl bilecek? Alan ile aynı ada sahip yöntem parametresi. int y) { this. Point sınıfı şimdi şu şekilde görünmelidir: class Point { public Point() { Console. Tüm bu kurucuların gerçekte yaptığı şey. kurucu şu şekilde olacaktır: public Point(int x. alanı yöntemdeki tüm ifadelerden gizler. Point. “bu nesnedeki alan” demek anlamına gelir. Dikkatli olmazsanız. alanları düzenlemek değil. } public Point(int x. kendilerine parametreler atamaktır. x. int y) // Don’t type this! { x = x. Point kurucusunu. } Bu kod derlenecek olmakla birlikte.cs dosyasında Point sınıfını düzenleyin ve x ve y adında int türünde iki private örnek alan ekleyin. y:{1}”. Bunu yaparken tuzak bir durum vardır.WriteLine ifadesi yerine aşağıdaki kod olacak şekilde değiştirin: public Point(int x. this.x = x. int y) { Console. y). x ve y alanlarına başlangıç değeri olarak x ve y parametrelerinin değerlerini atayan ikinci bir Point kurucu düzenleyeceksiniz. Bu problemin çözümü. } private int x. y = y. hangi değişkenlerin parametre olduğunu ve hangilerinin alanlar olduğunu belirlemek için this anahtar sözcüğünü kullanmaktır.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 133 15. ifadeler belirsizdir. Bu kesinlikle istediğiniz şey değil. x = x. 16.y = y.WriteLine(“default constructor called”).WriteLine(“x:{0}. iki parametre alacak ve Console.

x ve y alanlarına başlangıç değeri olarak -1 atamak için Point kurucusunu aşağıdaki gibi düzenleyin.. public double DistanceTo(Point other) { } . this.) Aşağıdaki alıştırmada. Karışıklığa neden olacak herhangi bir parametre olmasa da.x.y = -1.x – other. Kodun hatasız ve uyarısız derlendiğinden emin olun. Örnek yöntemlerini yazın ve çağırın 1. Build menüsünde Build Solution’ı tıklayın. (Bu bölümde daha sonra göreceğiniz başka yöntem türleri de vardır.) Bir sınıfa ait olan ve bir sınıfın belirli bir örneğine ait veri üzerinde çalışan yöntemler instance methods (örnek yöntemler) olarak adlandırılır. other adında tek bir Point bağımsız değişkeni alır ve double değer döndürür. alan başvurularını this ile belirtmek iyi bir uygulamadır: public Point() { this. arasındaki başlangıç değeri olarak farkı atayın. Bunun için. Yöntem. Point sınıfı için DistanceTo (Uzaklık) adında iki nokta arasındaki uzaklığı hesaplayan bir örnek yöntemi yazacaksınız.x.. } Aşağıdaki basamaklarda. Visual Studio 2008’de Classes projesinde.x = -1. } 18. Point sınıfında kurucular ve private değişkenler arasına aşağıda gösterilen DistanceTo adındaki public örnek yöntemini ekleyin. DistanceTo örnek yöntemi gövdesine çağrı yapmak için kullanılan Point nesnesi ile parametre olarak geçirilen Point nesnesi arasındaki uzaklığı hesaplayan ve sonucu döndüren kodu ekleyeceksiniz.134 Kısım II C# Dilini Anlamak 17. Aşağıda koyu harflerle gösterilmiştir: public double DistanceTo(Point other) { int xDiff = this. DistanceTo yönteminde. (Kodu çalıştırabilirsiniz ancak henüz bir sonuç vermez. 2.. } .x ve other. xDiff adında bir yerel int değişkeni bildirin ve this. x-koordinatı ve y-koordinatı arasındaki farkı bulmanız gerekir. DistanceTo yöntemi tam olarak aşağıdaki gibi görünmelidir: class Point { ..

y .x. origin ve bottomRight Point değişkenlerinin bildirilip atamalarının yapıldığı ifadelerden hemen sonra distance adında bir double değişken bildirin. 6.Math sınıfı. IntelliSense DistanceTo yöntemini göstermelidir. Entrance yöntemine.x . 5. Bu double değişkene. Entrance yöntemi şimdi şu şekilde görünmelidir: static void Entrance() { Point origin = new Point(). 1280). aşağıda gösterilen return ifadesini ekleyin: public double DistanceTo(Point other) { int xDiff = this. } Şimdi DistanceTo yöntemini test edeceksiniz.DistanceTo(bottomRight).y . int yDiff = this. . System. } Uzaklığı hesaplamak için.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 135 3. } Not origin değişkeninden sonra nokta karakteri yazdığınızda. origin nesnesi üzerinde DistanceTo yöntemini çağırdığınızda ve bottomRight nesnesini bağımsız değişken olarak geçirdiğinizde ulaştığınız sonucu atayın.y ve other. DistanceTo yönteminin sonuna. return Math. karekök hesaplamak için kullanabileceğiniz Sqrt yöntemini sağlar. int yDiff = this. Point bottomRight = new Point(1024.Sqrt((xDiff * xDiff) + (yDiff * yDiff)). Pitagor teoremini kullanabilirsiniz. Console. Program sınıfının Entrance yöntemini bulun. 4.x – other. Point bottomRight = new Point(1024.other.WriteLine yöntemini kullanarak konsola distance değişkeninin değerini yazan başka bir ifade ekleyin.other. Tamamlanmış Entrance yöntemi şu şekilde görünmelidir: static void Entrance() { Point origin = new Point().y.other. xDiff ve yDiff değerlerinin karelerinin toplamının karekökünü bulun.y. double distance = origin. 1280). yDiff adında başka bir int değişkeni bildirin ve this.x.y arasındaki farkı başlangıç değeri olarak atayın: public double DistanceTo(Point other) { int xDiff = this.

Bu çok hantal olurdu. sınıf için tanımlanmış herhangi bir oluşum alanına erişime sahip değildir.Sqrt(42.136 Kısım II C# Dilini Anlamak double distance = origin.. Bu. Bu.DistanceTo yerine Point. Sqrt yöntemi sadece bir örnektir. double d = m. Burada nesneler gerçekten gerekli değildir. Sin. benzer şekilde Circle sınıfına bakarken Math sınıfının PI alanını okudunuz. bir önceki alıştırmada eklediğiniz kodda origin. Düşündüğünüzde. Cos. sınıfın adını kullanarak yöntemi çağırabilir ya da alana erişebilirsiniz. Sqrt yöntemi için gerekli tüm giriş verileri parametre listesinde sağlanmıştır ve yöntemin dönüş değeri kullanılarak. } Bir static (statik) yöntem tanımladığınızda. bu nedenle Sqrt yöntemini nesne yönelimli yapıya zorlamak iyi bir fikir değildir. Math sınıfının Sqrt yöntemini kullandınız. Sadece static olarak işaretlenmiş alanları kullanabilir. Bunlar.DistanceTo(bottomRight). . bir yöntem ya da alanı static olarak bildirirseniz. sınıfın kendisindeki yönteme başvurdunuz. Sqrt yöntemini çağırmak ya da PI alanını okumak yöntemi biraz garipti. Tan ve Log gibi diğer yararlı matematiksel yöntemler içerir. 9. static Yöntemleri ve Verileri Anlamak Önceki örnekte. Math nesnesindeki değil. Console. tüm yöntemler bir sınıf içinde bildirilmek zorundadır. Bundan başka. Math nesnesinin karekökü bulmakta hiçbir rolü yoktur. C#’da. Herhangi bir oluşum gerekmez. herhangi bir özel sınıf örneğinden bağımsız olan kullanışlı işlevler sağlayan yararlı yöntemlerdir.60537607311 değerinin yazıldığını doğrulayın. Sqrt yöntemini çağırmak için bir Math nesnesi yaratmak zorunda olurdunuz: Math m = new Math(). Bununla birlikte. distance). 8.. Konsol penceresine 1640.WriteLine(“Distance is: {0}”. Neler meydana gelir ve nasıl çalışır? Sık sık yöntemlerin tümünün doğal olarak bir sınıfın bir örneğine ait olmadığını göreceksiniz. gerçek Math sınıfının Sqrt yöntemini bildiriş şeklidir: class Math { public static double Sqrt(double d) { .. } .. } 7. Debug menüsünde Start Without Debugging’i tıklayın. sonuç yöntemi çağırana geçirilir. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. Math sınıfı Sqrt yöntemi ve PI alanı dışında.24). Sqrt yöntemi Math sınıfının bir örnek yöntemi olsaydı.DistanceTo yazmaya çalışmak gibidir.

public static int NumCircles = 0. } public Circle(int initialRadius) // aşırı yüklenmiş kurucu { radius = initialRadius. Paylaşılan Bir Alan Yaratmak Bir önceki bölümde bahsedildiği gibi.) Aşağıdaki örnekte.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 137 sınıf içinde static olarak işaretlenmiş diğer yöntemlere doğrudan başvurabilirsiniz. static alanlar genellikle class alanları olarak adlandırılmazlar. int ya da double gibi sayısal bir tür ya . sadece static alanlar olarak adlandırılır. NumCircles++. (ya da bazen static değişkenler olarak adlandırılır). her yeni Circle nesnesi yaratıldığında Circle kurucu tarafından 1 artırılır: class Circle { public Circle() // varsayılan kurucu { radius = 0. Circle nesnesi yerine Circle sınıfını belirterek NumCircles alanına erişirsiniz. bir alanı sadece. Bununla birlikte. Örneğin: Console. alan tanımlarken de static anahtar sözcüğünü kullanabilirsiniz. Circle sınıfındaki NumCircles (DaireSayısı) adındaki static alan.. statik olmayan (örnek) yöntemlerde ise ilk önce yöntemi çağırmak için bir nesne yaratmanız gerekir. } .WriteLine(“Number of Circle objects: {0}”. NumCircles++. Bununla birlikte. İpucu static yöntemler aynı zamanda class yöntemler olarak da adlandırılır. bu kitabın kapsamı dışındaki nedenlerden dolayı. bildiriminde static anahtar sözcüğünü kullanmaz ama yine de static’dir. ifadesi. bu nedenle NumCircles++. numaralandırma.. private int radius. tek bir sınıftan yaratılmış olan tüm nesneler tarafından paylaşılan bir alan yaratabilirsiniz. Bir const alanı.NumCircles). Circle. } Tüm Circle nesneleri aynı NumCircles alanını paylaşır. (Statik olmayan alanlar her bir nesne oluşumu için yereldir. her yeni örnek yaratıldığında aynı veriyi bir artırır. const Anahtar Sözcüğünü Kullanarak bir static Alan Yaratmak Bir alanın static olduğunu ve değerinin hiçbir zaman değişmeyeceğini bildiriminin önünde const anahtar sözcüğünü kullanarak belirtebilirsiniz. Bu özellik ile.

} static Sınıflar C#’ dilinin bir başka özelliği.14159265358979323846. Bir static sınıf sadece static üyeler içerebilir (sınıfı kullanarak yarattığınız tüm nesneler bu üyelerin tek bir kopyasını paylaşır). Bir static sınıfın amacı. Bu alanla. (Yaratmaya çalışırsanız derleyici hata verecektir. Bu sayacı her iki kurucu içinde de artıracaksınız.. Math sınıfının sadece static üyeleri içeren kendi sürümünüzü tanımlayacaksanız. isteseniz de new işlecini kullanarak static sınıftan bir nesne oluşumu yaratamazsınız.. Point sınıfına bir tane private static alan ekleyecek ve değerini 0 olarak atayacaksınız.. static sınıf varsayılan bir kurucuya sahip olabilir ancak kurucunun da static olarak bildirilmiş olması gerekir.} public static double Sqrt(double x) {. bir sınıfın static olarak bildirilebilmesidir. public const double PI = 3. herhangi bir oluşum verisi ya da yöntemleri içeremez ve new işlecini kullanarak bir static sınıftan nesne yaratmaya çalışmak anlamsızdır.. kaç tane Point nesnesi yaratıldığını bulabileceksiniz.138 Kısım II C# Dilini Anlamak da bir dize olduğunda const olarak bildirebilirsiniz.) Bir başlangıç değeri atamanız gerekiyorsa. Code and Text Editor penceresinde Point sınıfını görüntüleyin. static üyeler yazın ve static yöntemler çağırın 1. yalnızca yararlı yöntemler ve alanların yer tutucusu olarak görev yapmaktır. (“Numaralandırma ve Yapılarla Veri Türleri Yaratmak” başlıklı Bölüm 9’da numaralandırmayı öğreneceksiniz. Son olarak. .) Örneğin. bu private static yöntemin değerini döndürmek için bir public static yöntem yazacaksınız. Çünkü gerçekten bazı örnek yöntemlerine sahiptir. Aslında. Diğer türde kurucular geçerli değildir ve derleyici tarafından geçerli olmadığı bildirilir.. gerçek Math sınıfının bu şekilde tanımlanmadığına dikkat edin. şu şekilde görünebilir: public static class Math { public static double Sin(double x) {. } Bununla birlikte... Visual Studio 2008’i kullanarak.} . Bu bölümdeki son alıştırmada. aşağıda gerçek Math sınıfının PI’yı nasıl const alan olarak bildirdiğini görebilirsiniz: class Math { .} public static double Cos(double x) {.. Bir static sınıf...

. objectCount yaratılan bütün nesnelerin sayısını tutacaktır. int y) { this.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 139 2. this. Bu. Kötü bir çözüm. } Not private ve static anahtar sözcüklerini istediğiniz sırada yazabilirsiniz. İlk önce private. Aşağıdaki gibi..) Şimdiki soru şudur: Point sınıfının kullanıcıları kaç tane Point nesnesi yaratıldığını nasıl bulacaklar? Şu anda. her nesnenin bire ayarlanmış kendi objectCount alanı olacaktı. } public Point(int x. objectCount++. objectCount alanını artırmak için her iki Point kurucusuna da aşağıda gösterildiği gibi bir ifade ekleyin. (Aslında hiçbir oluşuma ait değillerdir. objectCount’ı bütün kurucularda (varsayılan kurucu da dahil) artırdığınız sürece. Point sınıfı aşağıdaki gibi görünmelidir: class Point { public Point() { this. daha sonra static yazmak tercih edilen sıradır. Bir oluşum alanı olsaydı. objectCount alanı private’dır ve sınıf dışından erişilmez. objectCount alanını her yerden erişilebilecek biçime dönüştürmek olabilir. this. objectCount++. private static int objectCount = 0. private static int objectCount = 0. Her nesne yaratıldığında kurucusu çağrılır.y = -1. Point sınıfının sonuna objectCount (nesneSayacı) adında int türü bir private static alan ekleyin. . y. bildirirken başlangıç değerini olarak 0 atayın: class Point { . 3. Bu yalnızca objectCount paylaşılmış bir static alan olduğu için çalışır.y = y. } Sınıfın geçerli oluşumuna ait olmadıklarından static alanlar ve yöntemlerin önüne this önekini ekleyemezsiniz.x = x. } private int x..x = -1.

Point sınıfının ObjectCount yönteminden dönen değeri konsola yazmak için bir ifade ekleyin. Başarılı bir şekilde bir sınıf yarattınız ve sınıftaki alanlara başlangıç değeri atamak için kurucuları kullandınız. örnek ve static alanlarını da uyguladınız.140 Kısım II C# Dilini Anlamak sınıfın kapsüllenmesini bozar. Çok daha iyi bir fikir. Point. 7. bir int döndüren ve hiçbir parametre almayan ObjectCount adında public static bir yöntem ekleyin. objectCount alanının değerini döndürecek biçimde oluşturun. 800). Point bottomRight = new Point(600. Bu yöntemi. } 5. Entrance yöntemine. (origin ya da bottomRight gibi) bir Point değişkeni ile değil sınıfın adı olan Point kullanılarak çağrılır. } ObjectCount.WriteLine(“Distance is: {0}”. 6. Debug menüsünde Start Without Debugging’i tıklayın. Konsola 2 değerinin yazıldığından emin olun (distance değişkeninin değerini görüntüleyen iletiden sonra) . Örnek ve static yöntemleri yarattınız ve her iki türdeki yöntemleri çağırdınız. Point sınıfına..distanceTo(bottomRight).WriteLine(“No of Point objects: {0}”. distance). Entrance yöntemi şimdi aşağıdaki gibi görünmelidir: static void Entrance() { Point origin = new Point(). Console. public anahtar sözcüğünü . 8. Programı sonlandırmak ve Visual Studio 2008’e dönmek için Enter’a basın.. Code and Text Editor penceresinde Program sınıfını görüntüleyin ve Entrance yöntemini bulun..ObjectCount()). double distance = origin. Tebrikler. } .. Ayrıca. Point sınıfı tam olarak aşağıdaki gibi görünmelidir: class Point { . ObjectCount çağrıldığında iki Point nesnesi yaratıldığından 2 değerini döndürmesi gerekir. o zaman değerinin doğru olduğundan emin olamazsınız çünkü herkes onu azaltabilir ya da artırabilir. objectCount alanının değerini döndüren public static bir yöntem oluşturmaktır. public static int ObjectCount() { return objectCount. Console. 4. Şimdi bunu yapacaksınız.

sadece kullanışlı olduklarını bilin. derleyicinin başlangıç değeri atamak için kullanılan deyimdeki ile aynı türde değişken yaratmasına neden olduğunu hatırlayın. (“Sorgu Deyimleri Kullanarak Bellek Verisinde Sorgulama Yapmak” başlıklı Bölüm 20’de sorgu deyimlerini öğreneceksiniz. myAnonymousObject nesnesini var anahtar sözcüğünü kullanarak açık şekilde yazarak bildirebilirsiniz: var myAnonymousObject = new { Name = “John”. deyimin türü derleyicinin anonim sınıf için ürettiği ad olur. Anonim Sınıflar Anonim sınıf (anonymous class). Age = 42 }. Bu kulağa garip geliyor belki ama kitabın sonraki bölümlerinde göreceğiniz bazı durumlarda. Age = 42 }. myAnonymousObject. Farklı değerlerle aynı anonim sınıfının diğer örneklerini de yaratabilirsiniz: var anotherAnonymousObject = new { Name = “Diana”. Nesnedeki alanlara. myAnonymousObject. new anahtar sözcüğünü kullanarak.Name. sınıfın içinde olmasını istediğiniz küme parantezi içinde tanımlanmış alanlar ve değerlerle basitçe bir anonim sınıf yaratırsınız: myAnonymousObject = new { Name = “John”.Age}. Bu nedenle anonim sınıflar ilginç bir muammaya neden olur: Sınıfın adını bilmiyorsanız. adı olmayan bir sınıftır. Bu durumda.) Şimdilik. alana verdiğiniz başlangıç değeri türünden alanların türünü ortaya çıkarır.WriteLine(“Name: {0} Age: {1}”. Derleyici. var anahtar sözcüğünün. Name (Ad) adında (Başlangıç değeri olarak “John” atanmıştır) ve Age (Yaş) adında (42 başlangıç değeri atanmıştır) iki public alan içerir. . Age = 43 }.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 141 kullanarak alanları ve yöntemleri nasıl erişilebilir yapacağınızı ve private anahtar sözcüğünü kullanarak bunları nasıl gizleyeceğinizi gördünüz. özellikle de sorgu deyimleri kullandığınızda gerçekten oldukça kullanışlıdır. myAnonymousObject (benimAnonimNesnem) değişkeninin türü ne olmalıdır? Yanıtı siz bilmezsiniz. Bir anonim sınıf tanımladığınızda. Bu sınıf. aşağıdaki gibi noktalama işaretleri kullanarak erişebilirsiniz: Console. uygun türün bir nesnesini nasıl yaratabilir ve sınıfın oluşumunu nasıl atayabilirsiniz? Daha önce gösterilen kod örneğinde. derleyici sınıf için kendi adını üretir fakat bunu siz bilmezsiniz. anonim sınıfların önemi budur! Bununla birlikte.

Bu durumda. “Değerler ve Başvuruları Anlamak” başlıklı Bölüm 8’de nesne değişkenlerini atamak hakkında daha çok şey öğreneceksiniz.. aynı adda ve aynı sırada alanlara sahiptir.. iki anonim sınıf örneğinin aynı türde olup olmadığını bulmak için adları.142 Kısım II C# Dilini Anlamak C# derleyicisi. sayıları ve alanların sırasını kullanır. myAnonymousObject ve anotherAnonymousObject değişkenleri aynı sayıda. Sınıfın yöntemleri ve alanları bu parantezler içinde bildirilir. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. static olamazlar ve herhangi bir yöntem belirleyemezsiniz. beklediğiniz şeyi yapmayabilir. sonra da açılan ve kapanan parantezleri ekleyin. Örneğin: class Point { . Anonim sınıflar sadece public alanlar içerebilir. türleri. ardından sınıfın adını. bu nedenle her iki değişken de aynı anonim sınıfın örnekleridir. Anonim sınıfın içeriğinde oldukça fazla kısıtlama vardır. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. } . public alanların tümüne başlangıç değeri atanmak zorundadır. Bu. Save iletişim kutusu görünürse. n Bölüm 7 Hızlı Başvuru Bunun İçin Bir sınıf bildirmek Şunu Yapın class anahtar sözcüğünü yazın. Not Bu atama ifadesi. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 7’ye geçin. aşağıdaki gibi bir atama ifadesi uygulayabilirsiniz anlamına gelir: anotherAnonymousObject = myAnonymousObject.

} Bir static alana erişmek Sınıfın adını yazın.. 0).. Örneğin: class Point { public static int ObjectCount() { . private static int objectCount. ardından bir nokta koyup yöntemin adını yazın.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 143 Bir kurucu bildirmek Adı sınıfın adı ile aynı olan ve bir dönüş türü (void bile) olmayan bir yöntem yazın. } } Bir kurucu çağırmak new anahtar sözcüğünü kullanın ve uygun parametrelerle kurucuyu belirtin.. ardından bir nokta koyup static alanın adını yazın.PI * radius * radius. static anahtar sözcüğünü yoksayın. . Bir static yöntem bildirmek Yöntemin bildiriminden önce static anahtar sözcüğünü yazın.. int y) { .. public const double PI = .. Örneğin: class Math { .. } Bir const alan bildirmek Alanın bildiriminden önce const anahtar sözcüğünü yazın... Örneğin: int pointsCreatedSoFar = Point. Örneğin: Point origin = new Point(0. Örneğin: double area = Math. } } Bir static yöntemi çağırmak Bir static alan bildirmek Sınıfın adını yazın.Örneğin: class Point { . Alanın bildiriminden önce static anahtar sözcüğünü yazın.ObjectCount().. Örneğin: class Point { public Point(int x..

.

Veri Türü Değişkenleri ve Sınıfları Kopyalamak Genel olarak. değerin bu bellek bloğuna kopyalanmasına neden olur. Başvuru türleri. Bu bölümdeki sınıflar gibi başvuru türleri tanımları. float. derleyici uygun değeri tutması için yeterli bellek alanı ayıran kodu üretir. Bir değişkeni değer türü olarak bildirdiğinizde. C# dilinin birçok temel türü değer türüdür. 145 . sadece Circle değerini içeren başka bir bellek bloğunun adresini (öğenin bellekteki konumunu belirten adres) ya da bloğa başvuru adresini tutabilecek kadar küçük bir parça bellek parçası ayırır. bellek bloklarına başvuruları tutar. n n “Sınıflar ve Nesneleri Yaratmak ve Yönetmek” başlıklı Bölüm 7’de.String sınıfı için bir takma addır. double ve char gibi türler değer türleri olarak adlandırılır. Aslında. Not Başvuru türü olan string dışında. derleyici Circle değerini tutmak için gerekli bellek alanını ayırmaz. C#’daki string anahtar sözcüğü sadece System. int. 42). Bu bölümde.Bölüm 8 Değerleri ve Başvuruları Anlamak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n Değer türü ve başvuru türü arasındaki farkları açıklamak. kendi sınıfınızı bildirmeyi ve bir sınıf kurucusunu new anahtar sözcüğüyle çağırarak sınıfınızın örneklerini yaratmayı (yani nesne yaratmayı) öğrendiniz. Ayrıca. int değişkeninin bildirilmesi. Bir Circle değişkeni bildirdiğinizde. bir başvuru türü örneğidir. Gerçek Circle nesnesi için sadece new anahtar sözcüğü kullanılarak yaratıldığında adres ayrılır. int değişkenine bir değer atanması (örneğin. Sınıf. object türünde bir değişken atayarak değere kutulama uygulamak. bir kurucu kullanarak nesneye nasıl başlangıç değeri atayacağınızı gördünüz. string türüne sorunsuzca uygulanır. Yöntem parametrelerinin bağımsız değişkenlerine erişebilmek için ref ve out anahtar sözcüklerini kullanmak. double ve char gibi temel türlerin karakteristik özelliklerinin sınıf türlerinden farkını öğreneceksiniz. Bölüm 7’de tanımlanmış olan Circle gibi sınıf türleri farklı olarak işlenir. derleyici tarafından 4 bayt (32 bit) bellek alanı ayrılmasına neden olur. Kutulanmış değere başvuran nesne başvurusunu kaldırarak değerin kutulamasını kaldırmak. int. Örneğin.

c değişkenini Circle olarak bildirdiğinizde. Peki derleyici. Buna kod içinde bakalım: int i = 42. // i’deki verinin kopyasını içerir i++.146 Kısım II C# Dilini Anlamak Değer türleri ve başvuru türleri arasındaki farkı tam olarak anlamanız gerekir. . // i’yi artırmanın copyi üzerinde etkisi olmaz c değişkenini Circle (sınıf adı) olarak bildirmek oldukça farklıdır. i değerini değiştirirseniz. refc adında başka bir Circle bildirirseniz. Özellikle. refc ve c değişkeninin her ikisi de ona başvurur. c değişkeni Circle nesnesine başvurabilir. // i’yi bildirin ve başlatın int copyi = i. copyi değeri değişmez. yine de 42 değerini içeren iki bellek bloğu vardır: biri i değişkeni için. Circle refc = c. i adında int türü değişken tanımladığınız ve 42 değeri atadığınız zamanki durumu düşünün. Sadece bir Circle nesnesi vardır. Circle nesnesindeki @ işareti bellekteki adrese başvuruyu gösterir: Burada açıklanan fark oldukça önemlidir. yöntem parametrelerinin davranışının değer türü ya da başvuru türü olup olmamalarına bağlı olması anlamına gelir. i değişkeni ile aynı değeri (42) tutacaktır. copyi ve i aynı değeri taşıyor olsa da. bu değişken de Circle nesnesine başvurabilir. Aşağıdaki alıştırmada bu farkı inceleyeceksiniz. Bununla birlikte. c değişkenini refc’ye atarsanız. copyi adında bir başka int değişkeni bildirirseniz. refc değişkeni c değişkeni ile aynı Circle nesnesine başvuracaktır. diğeri copyi değişkeni için. fakat her bloktaki adres gerçek Circle nesnesini saklayan aynı bellek konumunu işaret ederse ne olur? Buna kod içinde bakalım: Circle c = new Circle(42). Aşağıdaki grafik her iki örneği de gösterir. biri c değişkeni için diğeri de refc değişkeni için olmak üzere iki bellek bloğu ayırırsa.

3.cs dosyasını görüntüleyin ve daha sonra Program sınıfının Entrance yöntemini bulun. c değişkeninin içeriğini refc değişkenine gerçekten kopyalamak isterseniz.Value yöntemini çağırmak. i değişkeninin değerini tekrar konsola yazmak. namespace Parameters { class Pass { public static void Value(int param) { param = 42. 5. i değişkenini bağımsız değişken olarak alan Pass. Code and Text Editor penceresinde Program. Circle sınıfının herhangi bir üyesi private ise (radius alanı gibi).cs ve WrappedInt.radius = c.Bölüm 8 Değerleri ve Başvuruları Anlamak 147 Not Sadece başvuruyu kopyalamak yerine. // Bunu denemeyin Bununla birlikte. private alanları özellikler olarak duyurarak.radius. Proje. Pass.cs. private alanlardaki veriyi erişilebilir yapmalısınız.cs olarak adlandırılmış üç C# kod dosyası içerir. .Writeline yöntemini kullanarak i değişkeninin değerini konsola yazmak. “Alanlara Erişmek için Özellikleri Uygulamak” başlıklı Bölüm 15’te öğreneceksiniz. Microsoft Visual Studio 2008’i başlatın.cs dosyasını görüntüleyin. Bunu nasıl yapacağınızı. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 8\ Parameters klasöründekiParameters projesini açın. Aşağıdaki kod örneğinde koyu harflerle gösterildiği gibi. Program çalışmaya başladığında Main yöntemi tarafından Entrance yöntemi çağrılır. // to do yorum satırını kaldırın ve Pass sınıfına Value adında bir public static yöntem ekleyin. Value yönteminin gövdesi. Değer parametreleri ve başvuru parametrelerini kullanın 1. } } } 4. bu veriyi kopyalayamazsınız. Aşağıdaki görevleri yapmak için Entrance yöntemine dört ifade ekleyin: n n n n i adında yerel int değişkeni bildirmek ve başlangıç değerini 0’a atamak. param değişkenine 42 değeri atamalıdır. Bu yöntem param adında tek bir int parametre (bir değer türü) almalı ve dönüş türü void olmalıdır. refc. yöntem çağrısı bir try bloğu içine alınmıştır ve arkasından da bir catch işleyici gelir. 2. Console. Bunun yerine. refc’nin Circle sınıfının yeni bir oluşumuna başvurmasını sağlamanız ve daha sonra da aşağıdaki gibi veriyi alan alan c’den refc’ye kopyalamanız gerekir: Circle refc = new Circle(). Bölüm 7’de açıklandığı gibi. Program. Code and Text Editor penceresinde Pass.

} } 10.WriteLine yöntemine çağrı ile. } 6. Bu yöntem param adında tek bir WrappedInt parametresi almalı ve dönüş türü void olmalıdır. Code and Text Editor penceresinde Pass. Pass.Reference yöntemini çağırın.Value yöntemi içindeki atama ifadesi. Parametreleri güncelleyen Pass. Konsola iki defa 0 yazıldığından emin olun. Aşağıdaki görevleri gerçekleştirmek için Entrance yöntemine dört ifade daha ekleyin: n wi adında yerel bir WrappedInt değişkeni bildirin ve başlangıç değerine varsayılan kurucuyu çağırarak yeni bir WrappedInt nesnesi atayın. Pass.WriteLine(i). geçirilen bağımsız değişkenin kopyasını kullanır ve orijinal bağımsız değişken hiçbir şekilde etkilenmez. Reference yönteminin gövdesi.Value(i). bağımsız değişken olarak wi geçirin.WriteLine(i). 7. Console. 9. Şimdi sınıf içine alınmış int parametresi geçirdiğinizde neler olduğunu göreceksiniz.cs dosyasını görüntüleyin.Value yönteminin çağrılmasının gerçekten i değişkeni değerini değiştirip değiştirmediğini görebilirsiniz. Programı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Tamamlanmış Entrance yöntemi şu şekilde görünmelidir: static void Entrance() { int i = 0. Code and Text Editor penceresinde Program. Uygulamayı kapatmak için Enter tuşuna basın. Pass. Code and Text Editor penceresinde WrappedInt. 8.cs dosyasını görüntüleyin. WrappedInt sınıfına Number adında ve int türünde bir public oluşum alanı ekleyin: namespace Parameters { class WrappedInt { public int Number. Console. param değişkenine 42 değerini atamalıdır: public static void Reference(WrappedInt param) { param. n n . } 11.cs dosyasını görüntüleyin.Number değerini yazın. Pass sınıfına Reference adında bir public static yöntem ekleyin.148 Kısım II C# Dilini Anlamak Pass. Konsola wi.Number = 42.Value yöntemine çağrıdan önce ve sonra Console.

Console. yeni yaratılmış olan.Number).Value(i). Console. konsol penceresine yazılan ilk iki değer 0 ve 0’dır. Console.WriteLine yöntemini çağırarak. Pass. Daha önceki gibi.Reference yöntemindeki param değişkeni üzerinden yapılan değişiklikler. WrappedInt bir sınıf (başvuru türü) olduğundan. Pass. } 12.WriteLine(wi. int değer içeren WrappedInt nesnesine bir başvuru içerir.Reference yönteminin çağrılmasının wi. wi ve param değişkenlerinin her ikisi de aynı WrappedInt nesnesine sahiptir. Pass. wi değişkeni daha sonra Pass.WriteLine(i).): static void Entrance() { int i = 0. WrappedInt nesnesi Pass.Reference yöntemine bağımsız değişken olarak kopyalanır.Reference yöntemi çağrılmadan önce ve sonraki wi. sonraki iki değer. Console. yöntem tamamlandığında wi değişkeni tarafından izlenebilir. Daha önceki gibi. Console.Number’ın başlangıç değeri derleyicinin ürettiği varsayılan kurucu tarafından 0 olarak atanmıştı.Reference yöntemine bağımsız değişken olarak geçirildiğinde neler olduğunu gösterir: . Aşağıdaki şekil.Number değerini yazın.Reference(wi). wi değişkeni.Number). 13. wi. Nesne içeriğine Pass.Number değerini değiştirip değiştirmediğini görebilirsiniz. Konsol penceresine 0 ve 42 değerlerinin yazıldığını görmelisiniz.Value yöntemi çağrılmadan önce ve sonra.WriteLine(i). Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.Bölüm 8 n Değerleri ve Başvuruları Anlamak 149 Konsola tekrar wi.Number değerine uyar. Bununla birlikte. Pass. Uygulamayı kapatmak ve Visual Studio 2008’e geri dönmek için Enter’a basın. Önceki alıştırmada. Şimdi Entrance yöntemi tam olarak şu şekilde görünmelidir (yeni ifadeler koyu harflerle gösterilmiştir. WrappedInt wi = new WrappedInt().WriteLine(wi. Pass.

Bu durumda.0. ..150 Kısım II C# Dilini Anlamak Null Değerleri ve Null Türlerini Anlamak Bir değişken bildirdiğinizde. Örneğin... double d = 0. Aşağıdaki kod örneğinde. Şimdilik. sınıfın yeni bir oluşumunu yaratabileceğinizi ve yeni nesneye başvuru değişkeni atayabileceğinizi hatırlayın: Circle c = new Circle(42). Fakat bu iyi bir programlama uygulaması değildir ve kodunuzda problemlere neden olabilir. Kod genelde aşağıdaki gibi görünür: int i = 0. // Başlatılmamış !!! . // copy ve c aynı nesneye başvurur Buradaki if ifadesinin amacı. // Copy’yi başlatmak için rastgele değer // copy ve c aynı nesneye başvurur c değerini copy değişkenine atadıktan sonra. programda bir noktada başka bir nesneye başvuru olarak atanacaksa. copy değişkenine başlangıç değeri atanıp atanmadığını görmektir fakat bu değişkenle hangi değeri karşılaştırmalısınız? Bu sorunun cevabı null adı verilen özel bir değerdir. başka bir yerde değişkene başlangıç değeri de atanabilir. her zaman başlangıç değeri atamak iyi bir fikirdir. Bir değişken. Circle türü copy (kopya) değişkenine başlangıç değeri atanır fakat daha sonra Circle sınıfının başka bir oluşumuna başvuru atanır: Circle c = new Circle(42). bir nesneye başvurmasını isteyeceğiniz bir durumla mutlaka karşılaşacaksınız: Circle c = new Circle(42). çalışma zamanı çöp toplama olarak bilinen işlemi gerçekleştirerek belleği geri kazanabilir. “Çöp Toplama ve Kaynak Yönetimini Kullanmak” başlıklı Bölüm 14’te çöp toplamayı ayrıntılı olarak öğreneceksiniz. var olan bir nesneye bir başvuru sağlamaktır. Circle copy = new Circle(99). Bu çok iyidir fakat ya gerçekten yeni bir nesne yaratmak istemezseniz? Belki değişkenin amacı. değişken bir başvuruya sahip değilse.. Sınıf gibi bir başvuru değişkenine başlangıç değeri atamak için. çöp toplamanın pahalı bir işlem olduğunu bilmeniz önemlidir. . copy değişkenine başlangıç değeri atamak için kullandığınız 99 radius değerindeki orijinal Circle nesnesine ne olur? Artık ona başvuran yoktur. Circle copy. copy = c. if (copy == // what goes here?) copy = c.

Önceki alıştırmadaki sıradan int parametresi alan Pass.. Circle copy = null. // Değer türü değişkenini boş olabilen türe kopyalar Bunun tersinin geçerli olmadığına dikkat etmelisiniz. C#’da geçerli bir ifade değildir: int i = null.Bölüm 8 Değerleri ve Başvuruları Anlamak 151 C#’da. C# bir değişkeni boş olabilen (nullable) değer türü olarak bildirmek için kullanabileceğiniz bir değiştirici tanımlar.. null değeri. Bu nedenle. Uygun veri türü ifadesini doğrudan boş olabilen değişkene atayabilirsiniz.. bir önceki örnekteki i ve j değişkenlerine göre aşağıdaki ifade geçerli değildir: j = i. orijinal değer türü ile benzer şekilde davranır fakat null değeri atayabilirsiniz. Boş olabilen bir değeri. if (copy == null) copy = c.Value yöntemini yeniden çağırırsanız. // geçerli değil Bununla birlikte. Pass. aşağıdaki ifade derlenmeyecektir: int? i = 99. Şu şekilde kullanabilirsiniz: Circle c = new Circle(42). i = 100. // Başlatılmış // copy ve c aynı nesneye başvurur Boş Olabilen Türleri Kullanmak null değeri. değişkenin bellekte hiçbir nesneye başvurmadığı anlamına gelir. int j = 99. Aşağıdaki gibi.Value(i). Bu nedenle aşağıdaki ifade. başvuru türlerine başlangıç değeri vermek için kullanışlıdır fakat null değerinin kendisi bir başvurudur ve bir değer türüne atayamazsınız. Aşağıdaki örnekler geçerli ifadelerdir: int? i = null. sıradan değer türü bekleyen yönteme parametre olarak boş olabilen değişken kullanamayacağınız anlamına gelir.. sıradan değer türü değişkenine atayamazsınız. // Değer türü sabitini boş olabilen türe kopyalar i = j. herhangi bir başvuru değişkenine null değer atayabilirsiniz. // Geçerli değil Aynı zamanda bu. değer türünün boş olabileceğini göstermek için soru işareti (?) kullanırsınız: int? i = null. . // Derleme hatası . Boş olabilen değer türü. // geçerli Başvuru türünü test ettiğiniz yöntemle boş olabilen değişkenin null değer içerip içermediğini bulabilirsiniz: if (i == null) .

orijinal bağımsız değişkenin (arg) değil bağımsız değişkenin kopyası olan copy değişkeninin değerini artırır: static void DoWork(int param) { param++. Bununla birlikte. Örneğin. } . . “Numaralandırma ve Yapılarla Değer Türleri Yaratmak” başlıklı Bölüm 9’da bazı örnekler göreceksiniz. parametrenin bağımsız değişkenin kopyası olarak atandığını gördünüz. Bu örnekte. Boş olabilen değişkeni güncellemek için sıradan atama ifadesini kullanın. değişkenin içeriğini okumanın uzun bir yoludur. if (!i. aşağıdaki kodda. parametredeki herhangi bir değişikliğin. Fakat değişken değerinde değişiklik yapamazsınız.. geçirilen bağımsız değişkenin değerini etkilemeyeceği anlamına gelir. HasValue (DeğereSahipOl) özelliği boş olabilen bir türün bir değere mi sahip olduğunu yoksa null mu olduğunu gösterir. Bu düzenleme. Value (Değer) özelliğini okuyarak bir değer içeren boş olabilen türün değerini elde edebilirsiniz: int? i = null. else Console. Bölüm 6’da gördüğünüz özelliklere sahiptir. ref ve out Parametrelerini Kullanmak Her zaman olduğu gibi.HasValue) i = 99. Bölüm 4’ten NOT işlecinin (!) bir Boolean değer kabul etmediğini hatırlayın. Value özelliğini okumak. Daha karmaşık değer türleri yaratabilir ve HasValue ve Value özelliklerinin avantajlarını kullanmak gerektiğinde boş olabilen değişkenler bildirmek için bu değer türlerini kullanabilirsiniz.152 Kısım II C# Dilini Anlamak Boş Olabilen Türlerin Özelliklerini Anlamak Boş olabilen türler. bir yönteme bir bağımsız değişken geçirdiğinizde. bu görünen eksiklikler int? değişkeninin basit boş olabilen tür olmasından kaynaklanır. 99 değeri atar. Bir değişkenin değerini okumak için bu özelliği kullanabilirsiniz. değişkenin değerini görüntüler. DoWork yöntemi.. Ek olarak. Aşağıdaki gibi. HasValue özelliği bir null değeri test etmek açısından bir yarar sağlamaz. değer türü (int gibi). Not Boş olabilen bir türün Value özelliği salt okunurdur. boş olabilen tür (int? gibi) ya da başvuru türü (WrappedInt gibi) olsa da bu doğrudur. Parametre.WriteLine(i. boş olabilen i değişkenini test eder ve bir değere sahip değilse (null-boş ise). konsola yazılan sonuç 43 değil 42’dir. Bu kod parçası. aksi takdirde.Value).

Bu sözdizimi. Bu nedenle konsolda 43 görünmektedir. not 43 } Değerleri ve Başvuruları Anlamak 153 Bir önceki alıştırmada. Bir bağımsız değişkeni bir ref parametresine geçirdiğinizde. Çoğu zaman. bu garanti oldukça yararlıdır ve programdaki hataları azaltmanıza yardımcı olabilir. bağımsız değişkenin kendisini değiştirmek mümkün değildir (örneğin. o parametre kullanılarak yapılan herhangi bir değişikliğin. önceki örneğin ref anahtar sözcüğü kullanılarak yazılmış biçimini görebilirsiniz: static void DoWork(ref int param) // ref kullanır { param++. bağımsız değişkenin önüne de ref yazmalısınız. } // ref kullanır // 43 yazar Bu defa.WriteLine(arg). // writes 42. ref Parametreleri Yaratmak Bir parametrenin adının önüne ref yazarsanız. DoWork(ref arg). çünkü parametre bağımsız değişkenin diğer adıdır. bağımsız değişkenin değişebileceğine dair görsel bir ipucu verir. parametre. bazen bir bağımsız değişkeni değiştirmek için gerçekten yöntem yazmanız gerekebilir. } static void Main() { int arg = 42. aşağıdaki örnekte. parametrenin kendisinin değişmemesidir (hala aynı nesneye başvurur). DoWork yöntemine orijinal bağımsız değişkenin kopyası yerine orijinal değişkene bir başvuru geçirirsiniz. Bunu yapmanız için C#. Bu. Console. DoWork(arg). Bununla birlikte.Bölüm 8 static void Main() { int arg = 42. Console. bir yöntemin parametresi başvuru türü ise. Buradaki önemli nokta. Standart kesin atama kuralı (kullanmadan önce bir değişkene bir değer atamalısınız). bağımsız değişkenin kopyası olmak yerine onun diğer adı olur.WriteLine(arg). başvurulan veri değişse bile. parametreye ne yaparsanız aynı şeyi otomatik olarak bağımsız değişkene de yapmış olacağınız anlamına gelir. arg değişkenine . tümüyle farklı bir nesneye başvuracak şekilde ayarlamak). bağımsız değişkenin başvurduğu nesneyi parametre üzerinden değiştirmek mümkündür. Örneğin. ref bağımsız değişkenleri için de geçerlidir. ref ve out anahtar sözcüklerini sağlar. Aşağıda. yönteme geçen bağımsız değişkenin başvurduğu veriyi değiştirdiğini gördünüz. Böylece yöntemin bu başvuruyu kullanarak yaptığı her değişiklik orijinal bağımsız değişkeni de değiştirir. Diğer bir deyişle.

DoWork içindeki param++ gerçekte arg++’dır ve arg++ yalnızca arg tanımlanmış değere sahip olduğunda kullanılabilir: static void DoWork(ref int param) { param++. . // başlatılmamış DoWork(ref arg). yöntemin parametreye başlangıç değeri atamasını istediğiniz zamanlar olabilir. Örneğin. } out Parametreleri Yaratmak Derleyici. Bir parametrenin önüne out anahtar sözcüğünü ekleyebilirsiniz. yöntemi çağırmadan önce bir ref parametresine değer atanıp atanmadığını kontrol eder. out anahtar sözcüğü output (çıktı) kelimesinin kısaltmasıdır. out anahtar sözcüğü.WriteLine(arg). ref anahtar sözcüğüne benzer. bağımsız değişkenin diğer adı olur. bağımsız değişkenine başlangıç değeri atanmadan yöntemi çağırmanıza izin verilir. } static void Main() { int arg. Bunu out anahtar sözcüğü ile yapabilirsiniz. Bir yönteme out parametresi geçirdiğinizde. çünkü DoWork yöntemi param değişkenine bir değer atamaz: static void DoWork(out int param) { // Bir şey olmaz } Fakat aşağıdaki örnek derlenir. aynı zamanda bağımsız değişkenin önüne de out anahtar sözcüğünü yazmak zorundasınız. static void DoWork(out int param) { param = 42. daha sonra konsolda görüntülenen arg değişkenine başlangıç değeri atamak için DoWork yöntemini çağırır: static void DoWork(out int param) { param = 42. Aşağıdaki örnek derlenmeyecektir. parametreye yaptığınız herhangi bir değişiklik. Bununla birlikte. orijinal bağımsız değişkene de yapılır. } out parametresine yöntem tarafından bir değer atanması gerektiğinden. yöntem bu parametreye bir değer atamak zorundadır. ref anahtar sözcüğünü kullandığınızda olduğu gibi. böylece parametre.154 Kısım II C# Dilini Anlamak başlangıç değeri verilmediğinden kod derlenmeyecektir. Console. Bir out parametresine bir bağımsız değişken geçirdiğinizde. çünkü DoWork yöntemi param değişkenine bir değer atar. Bunun nedeni.

3. Value yöntemi aşağıdaki gibi görünmelidir: class Pass { public static void Value(ref int param) { param = 42. Console.. // 42 yazar } Değerleri ve Başvuruları Anlamak 155 Bir sonraki alıştırmada ref parametrelerini inceleyeceksiniz. Programı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.Value yöntemine yapılan çağrının i bağımsız değişkenini değiştirdiğini gösterir. 5. } } 6. } 4. Visual Studio 2008’de Parameters projesini açın. 2.. Console.cs dosyasını görüntüleyin. .WriteLine(arg). . Code and Text Editor penceresinde Pass. Console.Bölüm 8 } static void Main() { int arg. Code and Text Editor penceresinde Program.WriteLine(i). Pass.cs dosyasını görüntüleyin.WriteLine(i).. Bu kez. Entrance yönteminin üçüncü ifadesini. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın.Value(ref i).Value yöntem çağrısı bağımsız değişkenini ref olarak geçirecek biçimde düzenleyin. } . Bu Pass. // başlatılmamış DoWork(out arg). Entrance yöntemi şimdi şu şekilde görünmelidir: class Application { static void Entrance() { int i = 0.. Value yöntemini. 7. int parametresi bir ref parametresini kabul edecek biçimde düzenleyin. ref parametrelerini kullanın 1. konsol penceresine yazılan ilk iki değer 0 ve 42’dir. Pass.

nesne tarafından kullanılan bellek. new anahtar sözcüğünü kullanarak bir nesne (sınıfın oluşumu) yarattığınızda. Bilgisayar Belleği Nasıl Düzenlenir? Bilgisayarlar.156 Kısım II C# Dilini Anlamak Not ref ve out değiştiricilerini değer türlerinde olduğu gibi başvuru türlerinde de kullanabilirsiniz. yöntemin tüm kutuları yığından kaldırılır. İşletim sistemleri ve çalışma zamanları sık sık veriyi tutmak için kullanılan belleği her biri ayrı olarak yönetilen iki büyük parçaya ayırır. Parametreyi yeni oluşturulmuş bir nesneye yeniden atarsanız. yeniden kullanıma uygun hale gelir (hemen yeniden kullanılabilir). parametreler ve yerel değişkenler için alınan bellek otomatik olarak yığına geri verilir. Bir yöntem çağrıldığında. bağımsız değişkeni de yeni oluşturulmuş nesneye atamış olursunuz. Bir yöntem bittiğinde. Değer ve başvuru türleri arasındaki farkları anlamak için. Bölüm 14’te öbek belleğinin nasıl yeniden kullanıldığı ayrıntılı olarak incelenmiştir. . Her yerel değişken. bir kutu atamak gibidir ve yığın üzerindeki kutuların en üstüne yerleştirilirler. Boş olabilen türler aslında başvuru türleridir ve öbek üzerinde yaratılırlar. nesneyi oluşturmak için gerekli bellek her zaman öbekten alınır. Belleğin iki büyük parçasına yığın (stack) ve öbek (heap) adı verilir. üst üste yığılan kutular gibi düzenlenir. o yöntemin parametreleri ve yerel değişkenleri için gerekli bellek her zaman yığından alınır. Başvuru değişkenlerini kullanarak birkaç yerden aynı nesneye başvurulduğunu gördünüz. bağımsız değişkenin diğer adına dönüşür. Yığın ve öbek adları. Parametre. İkisinde de aynı etkiyi gösterir. Yöntem bittiğinde (değerini döndürdüğünde ya da bir özel durum oluşturduğunda). Bir nesneye son başvuru yok olduğunda. her parametre yığının en üstünde bulunan kutuya yerleştirilir. Tüm başvuru türleri (nesneler) ise öbek üzerinde yaratılır (başvurunun kendisi de yığın üzerinde olduğu halde). uygulanan programları ve bu programların kullandığı veriyi tutar. bellekte verinin nasıl düzenlendiğini anlamak yararlı olacaktır. çalışma zamanının belleği yönetme biçiminden gelir: n Yığın belleği. n Not Tüm değer türleri yığın üzerinde yaratılır. Yığın ve öbek çok farklı amaçlara hizmet eder: n Bir yöntemi çağırdığınızda.

aşağıdaki Method yöntemi çağrıldığında ne olduğunu inceleyelim: void Method(int param) { Circle c. n . öbekten bir Circle nesnesi için yetecek kadar başka bir parça bellek ayrılır. new işleci OutOfMemoryException özel durumu oluşturur ve nesne yaratılmaz. çalışma zamanı boş kutu arar ve bulduğu boş kutuyu nesneye tahsis eder. new anahtar sözcüğünün yaptığı iştir. Bu.Bölüm 8 n Değerleri ve Başvuruları Anlamak 157 Öbek belleği. } param değişkenine geçirilecek değerin 42 olduğunu varsayın. c değişkeninde saklanır. Yöntemin içine girilince. nesneye başvuru (c değişkeni). Her kutunun üzerinde kullanımda olup olmadığını gösteren bir etiket vardır. Öbek belleği tükenirse. Yöntem çağrıldığında. çalışma zamanı kutuyu kullanımda değil olarak işaretler ve daha sonraki bir zamanda kutuyu boş olarak işaretleyerek yeniden kullanıma hazır hale getirir. iki şeye dikkat etmelisiniz: n Nesne. Yeni bir nesne yaratıldığında. Nesneye başvuru yığın üzerindeki bir yerel değişkende saklanır. başvuruyu tutmak için yetecek kadar başka bir bellek bloğu (bellek adresi) ayrılır fakat başlangıç değeri atanmaz (Circle değişkeni c için). üst üste yığılmış kutulardan çok bir odaya saçılmış kutulara benzer. Çalışma zamanı her kutuya başvuru numarasını izler (iki değişkenin aynı nesneye başvurabileceğini hatırlayın).. Son başvuru yok olduğunda. Circle kurucusu. Yığın ve Öbek Kullanmak Şimdi. Aşağıdaki şekil bu durumu göstermektedir: Bu noktada.. yığın üzerinde depolanır. Bu Circle nesnesine başvuru. öbek üzerinde depolanıyor olmakla birlikte. bu ham öbek belleği bir Circle nesnesine dönüştürmek için çalışır. . c = new Circle(param). Öbek belleği sonsuz değildir. yığından küçük bir parça (bir int için yetecek kadar) bellek ayrılır ve 42 başlangıç değeri atanır. Daha sonra.

Object için takma ad) olması aslında aynı öğenin bellekteki iki farklı görünüşünü sağlar: Circle c.NET Framework’deki en önemli başvuru türlerinden biri. Circle nesnesi için ayrılmış bellek yeniden kullanılabilir hale getirilir ve kurucudan dönen değer null olur . ikisi de aynı şeydir.Object Sınıfı Microsoft . System ad alanındaki Object sınıfıdır. System. o = c.Object önemli bir sınıftır. Yöntem sona erdiğinde.158 Kısım II C# Dilini Anlamak Not Circle kurucusu da bir özel durum oluşturabilir. parametreler ve yerel değişkenler kapsam dışına çıkar. object o. System.Object yerine object anahtar sözcüğünü kullanmayı tercih edin. İpucu System. c değişkeninin türünün Circle olması ve o değişkeninin türünün object (System.Object sınıfının özel bir türü olarak ve herhangi bir başvuru türüne başvurabileceğiniz bir değişken yaratmak için System. Circle nesnesine artık başvurulmayacağını dikkate alır ve gelecek bir zamanda öbek tarafından ayrılan belleğin serbest bırakılması için bir düzenleme yapar (Bölüm 14’te bakın).Object yazabilirsiniz. c ve o değişkeninin her ikisi de aynı Circle nesnesine başvurur.Object sınıfının önemini tam olarak anlamak için. System. Çalışma zamanı.String sınıfı için string ya da Bölüm 9’da göreceğiniz diğer anahtar sözcükler gibi) kullanmak için tutarlıdır. “Kalıtım ile Çalışmak” başlıklı Bölüm 12’de tanımlanan kalıtım kavramını anlamanız gerekir. System. c = new Circle(42). Oluşturursa. Aşağıdaki örnekte.Object sınıfını kullanabileceğinizi kabul edin. C#. object anahtar sözcüğünü kullanabilir ya da System.Object sınıfının takma adı olarak object anahtar sözcüğünü sağlar. tüm sınıfları System. c için ve param için ayrılmış olan bellek otomatik olarak yığına geri verilir. Daha kestirmedir ve sınıflar için eşanlamlı diğer anahtar sözcüklerle (System. Şimdilik. Kodunuzda. .

değişkenin orijinal değeri değişmez. o değişkeninin aşağıdaki ifadeyi kullanarak başvurduğu kutulanmış int değerine erişmeyi bekliyor olabilirsiniz: int i = o. Ancak.Bölüm 8 Değerleri ve Başvuruları Anlamak 159 Kutulamak Az önce de gördüğünüz gibi. . tüm başvurular öbek üzerindeki nesnelere başvurmalıdır. Örneğin. başvuru yığına olacaktır. Bununla birlikte. bu değere yalnızca değişken içinden ulaşmanızı sağlamak uygundur. Benzer şekilde. i değişkenine 42 başlangıç değerini atar ve daha sonra o değişkenine (object türünün. öbek üzerindeki değer değişmez. Öğenin yığından öbeğe otomatik kopyalanmasına kutulama (boxing) adı verilir. Kutulamayı Kaldırmak object türündeki bir değişken bir değerin kutulanmış kopyasına başvurabildiği için. İkinci ifadede tam olarak neler olduğunu anlamak için biraz açıklama gerekir. yığın üzerindeki öğelere başvurular yaratmak. Bu nedenle. i içindeki değerin bir kopyası öbek üzerinde oluşturulur ve o içindeki başvuru bu kopyaya olur. doğrudan i değişkenine başvuruyorsa. object türündeki değişkenler her başvuru türündeki her nesneye başvurabilir. object o = i. buna izin verilmez. başvuru türü) başlangıç değeri olarak i atar: int i = 42. programın sağlamlılığını çok ciddi biçimde tehlikeye atacağından ve bir güvenlik açığı yaratacağından. i değişkeninin değer türünde olduğunu ve yığında bulunduğunu hatırlayın. öbek üzerindeki değeri değiştirirseniz. aşağıdaki iki ifade. o değişkeni içindeki başvuru. object türündeki değişkenler bir değer türüne de başvurabilirler. Aşağıdaki şekil sonucu gösterir: Önemli Bir değişkenin orijinal değerini değiştirirseniz.

derleyici o’nun çalışma zamanında tam olarak neye başvurduğunu denetler. int i = 42. Herhangi bir şey olabilir. (Bu örnekte. o gerçekten kutulanmış int’e başvuruyorsa ve herşey uygunsa cast işlemi başarıyla tamamlanır ve derleyicinin ürettiği kod kutulanmış int’den değeri çıkarıp alır. sözdizimini kullanmanız gerçekten mantıklıdır.160 Kısım II C# Dilini Anlamak Bununla birlikte. object o = c. Derleyici. dönüştürmenin başarısız olmasına neden olan bir tür uyuşmazlığı vardır. // circle başvuru değişkeni olduğundan kutulanmaz int i = (int)o.) Bu işlem kutulamayı kaldırma (unboxing) olarak adlandırılır. i = o. çalışma zamanında bir InvalidCastException (GeçersizDönüştürmeÖzelDurumu) özel durumu oluşturur. Bu konuda düşünürseniz. İşte başarısız olan bir kutulama kaldırma dönüştürme işlemi: Circle c = new Circle(42). // derlenir ancak çalışma zamanında bir özel durum oluşturur . int i = o. o değişkeni sadece int türüne değil herhangi bir şeye başvurabilir. Sonuçta. bu sözdizimini denerseniz. derleme zamanı hatası alırsınız. o = c. i = (int)o. object değişkeninin önüne parantez içinde türün adını yazarsınız. kutulanmış değer daha sonra i değişkeninde depolanır. o kutulanmış bir int’e başvurmuyorsa. Derleyici tarafından üretilen kod. object o = i. object o. Daha sonra. cast içinde int türünü belirttiğinizi fark eder. cast olarak bilinen ve bir türü diğerine dönüştüren işlemi kullanırsınız. Cast işleminiz o’nun bir int’e başvurduğunu söyledi diye bu gerçekten başvurduğu anlamına gelmez. Aşağıdaki kodda neler olacağını düşünün: Circle c = new Circle(). Örneğin: int i = 42. // o circle’a başvurur // i’de ne tutulur? Kutulanmış kopyanın değerini elde etmek için. // kutulama // derlenir Bu dönüştürme işlemi güç anlaşılır bir işlemdir. Aşağıdaki şekil neler olduğunu gösterir: Bununla birlikte.

Verileri Güvenli Olarak Dönüştürmek Dönüştürme işlemini kullanarak. bir nesne tarafından başvurulan verinin özel bir türe sahip olduğunu ve bu türü kullanarak nesneye başvurmanın güvenli olduğunu belirtebilirsiniz. C# dönüştürme işlemini gerçekleştirmenize yardımcı olabilecek oldukça kullanışlı iki işleç daha sunar: is ve as işleçleri. Buradaki kilit nokta. özel bir durumu yakalamak ve nesne türünün istediğiniz türde olmadığını bilerek bu özel durumu işlemek daha ziyade elverişsiz bir yaklaşımdır. sizin fikrinize göre. Bu özel durumu yakalamalı ve işlemelisiniz. dönüştürme ile eşleşmiyorsa. object o = wi. Bununla birlikte. uygulamanızı oluştururken size güvenir fakat çalışma zamanı daha şüphecidir ve uygulamanızın çalışma koşulu olup olmadığını denetler. “Generics’e Giriş” başlıklı Bölüm 18’de kutulamaya alternatif işlemleri göreceksiniz. Bellekteki nesne türü.Bölüm 8 Değerleri ve Başvuruları Anlamak 161 Daha sonraki örneklerde kutulama ve kutulamayı kaldırmayı kullanacaksınız.. çalışma zamanı bir önceki bölümde tanımlandığı gibi InvalidCastException özel durumunu oluşturur. if (o is WrappedInt) . Denetleme için gereken miktar nedeniyle ekstra öbek belleği ayırmak gerektiğinden. Kutulama kullanışlıdır fakat bilinçsiz kullanımı programın performansını ciddi olarak bozabilir. “sizin fikrinize göre” tümcesidir. C# derleyici.. kutulama ve kutulamayı kaldırma işlemlerinin pahalı işlemler olduğunu unutmayın. . is İşleci Nesne türünün istediğiniz türde olduğunu doğrulamak için is işlecini kullanabilirsiniz: WrappedInt wi = new WrappedInt().

Çalışma zamanı nesneyi belirtilen türe dönüştürmeye çalışır. as işleci de işlenen olarak bir nesne ve bir tür alır. . Bir işaretçi (pointer) bellekteki (öbek ya da yığın üzerinde) bir öğenin adresini ya da bu öğeye bir başvuruyu tutan bir değişkendir. is ve as işleçlerini “Kalıtımla Çalışmak” başlıklı Bölüm 12’de tekrar ele alacaksınız. aksi takdirde. is işleci true sonucu verir. WrappedInt değişkeni temp’e (geçici) atanmıştır. Önceki kod. // Dönüştürme başarılı is işleci gibi. Dönüştürme başarılı olursa.. bu bölümü atlayabilirsiniz! Daha önce C ya da C++ gibi programlama dillerinde programlar yazdıysanız. önceki bölümde nesne başvurusuyla ilgili anlatılanların çoğu tanıdık gelmiştir. sadece dönüştürmenin başarılı olacağını biliyorsa. if (temp != null) . İşaretçiler ve Güvensiz Kod Bu bölüm yalnızca bilgilendirme amaçlı olup C ya da C++ dillerini bilen yazılım geliştiricilere yöneliktir.162 Kısım II { C# Dilini Anlamak // Güvenli. object o = wi. } is işleci iki işlenen alır: sol tarafta nesneye başvuru ve sağ tarafta da tür adı.. WrappedInt temp = o as WrappedInt. sonuç döndürülür. as işlecini aşağıdaki gibi kullanırsınız: WrappedInt wi = new WrappedInt(). Örneğin. false verir.. Bir değişkeni işaretçi olarak tanımlamak için özel bir sözdizimi kullanılır. as İşleci as işleci is ile aynı görevi yerine getirir fakat biraz kısaltılmış olarak.. Ne C. .. Programlamaya yeniyseniz. object türündeki o değişkeninine başvuruyu dönüştürme işlemini yapar. as işleci temp değişkenine null değeri atar. ne de C++ dillerinin açık türleri olmasa da her iki dil de benzer işlerlik sunan bir yapıya sahiptir: işaretçiler. o WrappedInt’tir WrappedInt temp = (WrappedInt)o. Bu örnekte. Dönüştürme başarılı değilse.. Öbek üzerindeki başvurulan nesne türü özel bir türe sahipse. aşağıdaki ifade pi değişkenini bir tamsayıya işaretçi olarak bildirir: int *pi. .

birçok var olan sistemlerde. i değişkeni ile aynı bellek konumuna işaret etmektedir. . C ve C++ dillerini öğrenen programcıların karşılaştıkları önemli sorunlardan biri işaretçilerin kullandığı sözdizimini anlamakla ilgilidir. aşağıdaki ifadeleri ve & işlecini kullanabilirsiniz: int *pi. unsafe anahtar sözcüğü bir kod bloğunu ya da tüm bir yöntemi işaretlemek için kullanılabilir: public static void Main(string [] args) { int x = 99. pi = &i. int i = 99. Bazı ortamlar (Microsoft Windows olmayan).. Gerçekten istiyorsanız. işaretçinin başka bir işleme ait olan belleğe başvurup başvurmadığını denetlemekte başarısızdır. y = 100. * işlecinin aritmetikteki çarpma işleminin yanı sıra en az iki anlamı vardır ve ne zaman *. Aşağıda gösterildiği gibi. x. &y). Örneğin. işaretçilerin kötü yönetimiyle sonuçlanan güvenlik çatlakları da vardır. y).Bölüm 8 Değerleri ve Başvuruları Anlamak 163 pi değişkeni bir işaretçi olarak bildirilse de siz ona bir başlangıç değeri atayana kadar hiçbir yere işaret etmez. } Console. pi işaretçisini kullanarak i tamsayı değişkenini işaret etmek için. gizli kalması gereken veriyi tehlikeye atabilme riski meydana getirir. unsafe { swap (&x. y is now {1}”. Tüm bu problemlerden kaçınmak için C#’a başvuru değişkenleri eklenmiştir. pi işaretçi değişkeninden i değişkeninde tutulan değere erişebilir ve bu değeri değiştirebilirsiniz: *pi = 100. } . Ayrıca. C#’da işaretçileri kullanmaya devam edebilirsiniz.WriteLine(“x is now {0}. ne zaman & kullanılacağı oldukça kafa karıştırmaktadır. Bu kod i değişkeninin değerini 100 olarak güncelleştirir çünkü pi. geçersiz bir yere işaret etmenin ya da işaret etmeyi tamamen unutmanın ve ardından işaret edilen veriye başvurmanın çok kolay olmasıdır.. Sonuç ya çöp oluşması ya da programın hata verip başarısız olmasıdır çünkü işletim sistemi bunu bellekteki yasak bir adrese erişim denemesi olarak algılar. İşaretçilerle ilgili diğer bir konu. ancak kodu güvensiz (unsafe) olarak işaretlemeniz gerekir.

int copyi = i. Circle refc = c. int *b) { int temp. değerlerini doğrudan yığın üzerinde tutan değer türleriyle öbek üzerindeki nesnelerine dolaylı olarak başvuran başvuru türleri arasındaki bazı önemli farkları öğrendiniz. *a = *b. Bir başvuru türü değişkeni kopyalamak Yalnızca kopyayı oluşturun.164 Kısım II C# Dilini Anlamak public static unsafe void swap(int *a. *b = temp. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Güvensiz kod ayrıca belleğin yönetimini etkiler ve güvensiz kod kullanarak oluşturulan nesnelerin yönetilmediği olduğu söylenir. Bu bölümde. temp = *a. Değişken başvuru türü olduğundan aynı nesneye başvuran iki başvuru elde edersiniz. Örneğin: int i = 42. System. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 9’a geçin. . değişkenin değerinin öbek üzerinde oluşturulan kutulanmış bir kopyasına başvurmasına nasıl neden olduğunu gördünüz. n Bölüm 8 Hızlı Başvuru Bunun İçin Bir değer türü değişkeni kopyalamak Şunu Yapın Yalnızca kopyayı oluşturun. Ayrıca. Bu konu Bölüm 14’te ayrıntılı olarak anlatılmaktadır. } Güvensiz kod içeren programları derlerken /unsafe seçeneğini belirtmeniz gerekir. Save iletişim kutusu görünürse. Değişken değer türü olduğundan. Örneğin: Circle c = new Circle(42). aynı değerin iki kopyasını elde edersiniz. bağımsız değişkenlerine erişmek için bir yöntem üzerinde ref ve out anahtar sözcüklerini nasıl kullanacağınızı da öğrendiniz.Object sınıfının bir değişkeninin değere (42 gibi) atanmasının. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.

WriteLine(arg). ... DoWork(ref arg).WriteLine(arg). Bu. } Alternatif olarak.. } Bir out parametresine bir bağımsız değişken geçirmek Bağımsız değişkenin önüne out anahtar sözcüğünü yazın.. WrappedInt temp = o as WrappedInt.. parametreyi bağımsız değişkenin kopyası değil diğer adı yapar. DoWork(out arg). } Bir değeri kutulamak Bir değerin kutulamasını kaldırmak Object türünde bir değişkeni değere atayın. Örneğin: int i = (int)o. if (o is WrappedInt) { WrappedInt temp = (WrappedInt)o. dönüşüm işlemini gerçekleştirmek için as işleci kullanın ve sonucun null olup olmadığını test edin. Bu. Örneğin: static void Main() { int arg = 42. parametreyi bağımsız değişkenin kopyası değil diğer adı yapar. Örneğin: WrappedInt wi = new WrappedInt(). Kutulanmış değere başvuran nesne başvurusunu değerin türüne dönüştürün.Bölüm 8 Değerleri ve Başvuruları Anlamak 165 Bir değer türü ya da null değer tutabilen bir değişken bildirmek Bir ref parametresine bir değişken geçirmek ? düzenleyiciyi kullanarak değişken bildirin. if (temp != null) .. object o = wi. object o = wi.. Bir nesneyi güvenli bir şekilde dönüştürmek Dönüşümün geçerli olup olmadığını test etmek için is işleci kullanın. . Bağımsız değişkenin önüne ref anahtar sözcüğünü yazın. . Console. .. Console. Örneğin: static void Main() { int arg = 42. Örneğin: int? i = null. Örneğin: Object o = 42. Örneğin: WrappedInt wi = new WrappedInt().

.

Fall (Sonbahar) ve Winter (Kış) 167 . sonbahar ve kışı sunmak için 0. C#. Aşağıda. Microsoft Visual C#’da bulunan iki temel türü öğrendiniz: değer türleri ve başvuru türleri. C# daha iyi bir çözüm sunar. Bu sistem çalışacaktır fakat fazla sezgisel değildir. 2 ve 3 tamsayı değerlerini kullanabilirsiniz.Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n Bir numaralandırma türü bildirmek. değerini doğrudan yığın üzerinde tutarken bir başvuru türü değişken öbek üzerindeki bir nesneye başvuruyu tutar. Numaralandırmalarla Çalışmak Programınızda yılın mevsimlerini sunmak istediğinizi varsayalım. 1. kalıp değerleri Spring (İlkbahar). Bir değer türü değişken. iki değer türünü destekler: numaralandırma (enumeration) ve yapı (structure). İlkbahar. kendi değer türlerinizi nasıl yaratacağınızı öğreneceksiniz. Kodda 0 tamsayı değerini kullandıysanız. Bir Numaralandırma Türü Bildirmek Bir enum anahtar sözcüğü ve arkasından küme parantezleri içinde türün sahip olabileceği geçerli değerleri tanımlayan semboller kullanarak numaralandırma türünü bildirirsiniz. Bir numaralandırma türü yaratmak ve kullanmak. Bölüm 7’de. Değerlerin bir grup sembolik adla sınırlandırıldığı bir numaralandırma türü (enum türü olarak da adlandırılır) yaratmak için enum anahtar sözcüğünü kullanabilirsiniz. bu 0 değerinin ilkbaharı gösterdiği çok açık olmayacaktır. Her ikisine de sırayla bakacağız. 0. Bu bölümde. Örneğin. Bir yapı türü bildirmek Bir yapı türü yaratmak ve kullanmak Bölüm 8’de. Summer (Yaz). 1. season (mevsim) adında bir int değişken bildirirseniz. 2 ve 3 dışında tamsayılar atayabilirsiniz. yaz. sınıflar tanımlayarak kendi başvuru türlerinizi nasıl yaratacağınızı öğrendiniz. Ayrıca çok sağlam bir çözüm de değildir.

alanlar ve parametreler yaratabilirsiniz: enum Season { Spring.WriteLine yöntemini kullanarak numaralandırma değişkenini görüntülediğinizde. Winter } Numaralandırma Kullanmak Bir numaralandırma bildirdikten sonra. Gerekirse. değişkene açık olarak bir değer atanmış olmalıdır. derleyici değişkenin değerine karşılık gelen geçerli değerin adını yazan kodu üretir. Console. Tüm geçerli numaralandırma adları.WriteLine(colorful). Console.Fall yazmanız gerektiğine dikkat edin. Örneğin: Season colorful = Season. Numaralandırma türlerinin tesadüfen aynı adı taşıyan hazır bilgileri içerebilmesine olanak tanıdığı için bu durum yararlıdır. kendi numaralandırma türlerinin etkinlik alanındadırlar. } Bir numaralandırma değişkeninin değerini kullanmadan önce. numaralandırmanın adını diğer bütün türler gibi bir tür adı olarak kullanabilirsiniz. değişkene. Ayrıca. Winter } class Example { public void Method(Season parameter) { Season localVariable. Season türünde değişkenler.Fall. ? düzenleyici kullanarak numaralandırma değişkeninin boş olabilir bir sürümünü yaratabilirsiniz.. bir numaralandırma değişkenini kendi geçerli değerini yansıtan bir dizeye dönüştürebilirsiniz.. numaralandırma tarafından tanımlanmış değerleri atayabileceğiniz gibi. Bir numaralandırma değişkenine sadece numaralandırma tarafından tanımlanmış bir değer atayabilirsiniz. aşağıda gösterildiği gibi. Numaralandırma türünüzün adı Season ise. // ‘Fall’ yazar Not Tüm değer türleri gibi. } private Season currentSeason. Örneğin: . Bunu yapmak numaralandırmaları otomatik olarak içeren yerleşik ToString yöntemini kullanırsınız.168 Kısım II C# Dilini Anlamak sembolik adlarıyla sınırlandırılmış olan. Fall yerine Season. . null değer de atayabilirsiniz: Season? colorful = null. Fall. Daha sonra. Fall. Summer. Season (Mevsim) adlı bir numaralandırma türünün nasıl tanımlandığını görebilirsiniz: enum Season { Spring. Summer.

Fall. // ‘2’ yazar İsterseniz. Birden çok numaralandırma kalıbına aynı değeri verebilirsiniz. İngiltere’de sonbahar için Fall yerine Autumn kullanılır ve bunu koda aşağıdaki gibi yansıtabilirsiniz: enum Season { Spring.WriteLine(name). Summer 1. Summer. Summer. Örneğin. 2 değerini yazacaktır (Spring 0. Fall. 1. Winter } . Autumn = Fall. 2 ve 3’tür. Örneğin. aşağıdaki kod örneği Fall kelimesini değil. Fall 2 ve Winter 3): enum Season { Spring. eşitlik işlecini (==) kullanarak. Örneğin. Fall.Fall. Bir önceki örnekte. Bölüm 8’deki kutulamayı kaldırmak konusundan hatırlarsanız. Winter } Önemli Bir numaralandırma kalıbına atadığınız tamsayı değer derleme anında sabit olan bir değer (1 gibi) olmalıdır. Console. Numaralandırma değişkeninin altında yatan tamsayı değerini elde etmek mümkündür. Varsayılan ayar olarak. Console. bir numaralandırma kelimesi (Spring gibi) ile ilişkilendirebilirsiniz: enum Season { Spring = 1... // ‘Fall’ da yazar Tamsayı değişkenler üzerinde kullanabileceğiniz standart işleçlerin birçoğu.WriteLine((int)colorful). derleyici. her bir elemanı ile bir tamsayı değerini ilişkilendirir. Fall ve Winter’ın değerleri 0. bir veri türünden diğerine dönüştürme ancak tersi geçerli ve anlamlı olduğu sürece yapılabilir. bir önceki değerinin karşılığından bir fazlasını verecektir. sıfır değerini vereceği ilk öğe hariç. Numaralandırma Kalıp Değerlerini Seçmek Bir numaralandırma. Summer. Summer. Winter } .ToString(). Season colorful = Season. numaralandırma ilk elemanı için 0 ile başlar ve 1 basamak artarak yükselir. aşağıdaki örnekte olduğu gibi. belirli bir tamsayı sabitini (1 gibi). Bir numaralandırma kalıbına açık bir şekilde bir tamsayı değer vermediyseniz. Spring. iki numaralandırma değişkeninin eşit olup olmadığını karşılaştırabilir ve bir numaralandırma değişkeni üzerinde aritmetik işlem bile yapabilirsiniz (sonuç her zaman mantıklı olmasa bile!).Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 169 string name = colorful. numaralandırma değişkenleri üzerinde de kullanılabilir (“Dizinleyicileri Kullanmak” başlıklı Bölüm 16’da ele alınan bitwise ve shift işleçleri dışında).

Aşağıdaki alıştırmada. 3. yılın aylarını göstermek için StructsAndEnums ad alanına Month adlı bir numaralandırma türü ekleyin. Summer. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 9\ StructsAndEnums klasöründe yer alan StructsAndEnums projesini açın. Kaynak dosya. Month. maksimum (0’dan başlayarak) 256 adet hazır bilgiye sahip olabilirsiniz. sbyte.170 Kısım II C# Dilini Anlamak Bir Numaralandırmanın Arka Plandaki Türünü Belirlemek Bir numaralandırma türü bildirdiğinizde. yılın aylarını gösteren numaralandırma bildiren ve kullanan bir Console uygulaması ile çalışacaksınız. Aşağıda gösterildiği gibi. 4. short. September. numaralandırma hazır bilgilerine int türünde değerler verilir. numaralandırmanızı farklı bir tamsayı türde tanımlayabilirsiniz. August. sıra onu kullanmaya geldi. 2. ushort. November. May. July. Fall. Numaralandırma hazır bilgilerinin tüm değerleri seçilen türün aralığına uygun olmalıdır. December } } . Bir numaralandırma yaratın ve kullanın 1. April. numaralandırma türünü. October. namespace StructsAndEnums { enum Month { January. March. June. Season’un arka plan türünü int yerine short olarak tanımlamak isterseniz aşağıdaki gibi yazabilirsiniz: enum Season : short { Spring. uint. Artık bir numaralandırma türünü nasıl yaratacağınızı öğrendiğinize göre. byte veri türü olarak seçerseniz. Month için 12 adet numaralandırma hazır bilgisi Ocak’tan (January) Aralık’a (December) kadardır. StructsAndEnums adında boş bir ad alanı içerir. Microsoft Visual Studio 2008’i başlatın.cs dosyasını görüntüleyin. int. long ya da ulong. İsterseniz. Örneğin. Örneğin. Winter } Bunu yapmanın başlıca nedeni bellekten tasarruf etmektir. Code and Text Editor penceresinde. Numaralandırmanızı sekiz tamsayı türünden birine dayandırabilirsiniz: byte. February. int türü short türünden daha fazla bellek alanı tutar ve int türü aralığının tümüne ihtiyacınız yoksa daha küçük veri türü kullanmak daha mantıklıdır.

Programı kapatmak ve Visual Studio 2008 programlama ortamına dönmek için Enter’a basın. Visual Studio 2008. Visual Studio 2008. Bir numaralandırma değişkeni üzerinde matematiksel işlem (artırma işlemi gibi) gerçekleştirdiğinizde değişkenin içindeki tamsayı değerin değiştiğine dikkat edin. Debug menüsünde Start Without Debugging’i tıklayın. Console. 9. . first adlı Month türünde bir değişken bildiren ve Month.Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 171 5.January. 11. Programı kapatmak ve Visual Studio 2008 programlama ortamına dönmek için Enter’a basın.WriteLine(first). Console. Debug menüsünde Start Without Debugging’i tıklayın.).January’a eşitleyen bir ifade ekleyin. Entrance yöntemine. } Not Month’dan sonra nokta yazdığınızda (Month.January. first değişkenini artırmak ve yeni değeri konsolda görüntülemek için iki ifade daha ekleyin: static void Entrance() { Month first = Month. Konsolda January ve February yazdığını doğrulayın. Console. 7. Entrance yöntemi tam olarak şu şekilde görünmelidir: static void Entrance() { Month first = Month. uygun numaralandırma değeri görüntülenir.WriteLine(first). Değişken konsola yazıldığında.cs dosyasını görüntüleyin. Entrance yöntemine. first++. Code and Text Editor penceresinde. programı oluşturur ve çalıştırır. IntelliSense otomatik olarak Month numaralandırmasındaki tüm değerleri görüntüler. Önceki bölümlerdeki alıştırmalarda olduğu gibi. } 10. Code and Text Editor penceresinde Program.WriteLine(first). 6. İlk değişkenin adını konsola yazan başka bir ifade daha ekleyin. 8. programı oluşturur ve çalıştırır. Main yöntemi Entrance yöntemini çağırır ve oluşan özel durumları yakalar. Konsola January yazıldığından emin olun.

işlemin sonucu numaralandırma için tanımlanmış değer aralığının dışında olursa. başvuru türlerini tanımlayan sınıfların her zaman öbek üzerinde yaratıldığını görmüştünüz. bir değer türüdür. sırasıyla System. 14. Console. yöntemleri ve kurucuları olabilir. en iyisi türü yapı olarak tanımlamaktır. önceki alıştırmalarda zaten yapıları kullandınız. bir sınıfın olduğu gibi (ve numaralandırmadan farklı olarak) kendi alanları. Aşağıdaki ifadelerin tümü C#’da geçerli ifadelerdir: int i = 99. bu yapıların tümü.765F. Console. Sık Kullanılan Yapı Türleri Belki farkında değilsiniz ama. Bu durumlarda. Visual Studio 2008. alanlar ve yöntemlere sahiptir ve bu türlerin değişkenleri ve hazır bilgileri üzerinde yöntemler çağırabilirsiniz. Bazı durumlarda. Console. float f = 98. Bir numaralandırma üzerinde aritmetik işlem gerçekleştirilebilmekle birlikte. Yapılar yığın üzerinde depolandığından. . int. bir sınıfta.WriteLine(first).December değerini atamak için Entrance yöntemindeki ilk ifadeyi aşağıdaki gibi değiştirin: static void Entrance() { Month first = Month. Start Without Debugging’i tıklayın.ToString()). sayısal değeri. değişkene uygun tamsayı değerindeymiş gibi davranmaktır. Bu defa. konsola December (Aralık) kelimesi arkasından da 12 sayısı yazılır.ToString()).December. öbek yönetimini aşırı yük haline getirecek kadar az veri bulunabilir. first++. Yapı.Single yapılarının takma adlarıdır. Örneğin.172 Kısım II C# Dilini Anlamak 12. Bu yapılar. first değişkenine Month.WriteLine(i.Int32. Yapılarla Çalışmak Bölüm 8’de. Bir yapının. Debug menüsünde.WriteLine(first). C#’da. yapı küçük olduğu sürece bellek yönetimi yükü de azalmış olacaktır. long ve float temel sayısal türleri. Programı kapatmak ve Visual Studio 2008 programlama ortamına dönmek için Enter’a basın. dizesel gösterimine çeviren ToString yöntemini sağlar. Console. programı oluşturur ve çalıştırır.Int64 ve System. System. } 13. çalışma zamanının yapabileceği tüm şey.WriteLine(55.

Double System. Örneğin.Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 173 Console. string ve object türlerinin yapılar değil. sınıflar (başvuru türleri) olduğuna dikkat edin. Console.Byte System.WriteLine(98.UInt64 System. çünkü Console. Aşağıdaki tablo.MinValue de minimum değerdir. Gerçekte yaptığınız şey.UInt16 Sınıf ya da Yapı Yapı Yapı Yapı Yapı Yapı Yapı Yapı Sınıf Yapı Yapı Sınıf Yapı Yapı Yapı . // Int32.WriteLine yöntemi gerektiğinde otomatik olarak çağırır.Decimal System.MaxValue.Boolean System. Int32.WriteLine(f.UInt32 System. Örneğin. Anahtar Sözcük bool byte decimal double float int long object sbyte short string uint ulong ushort Eşdeğer Tür System.Int16 System.String System. int türünün tutabildiği maksimum değer. int i = int.765F. ToString yönteminin kullanımını çok sık göremezsiniz.Parse(s). Bu yapılar tarafından ortaya çıkarılmış statik yöntemlerin kullanımı daha yaygındır.Single System.Parse yöntemini kullandınız.SByte System. C#’daki temel türleri ve Microsoft .NET Framework’deki eşdeğer türlerini gösterir. daha önceki bölümlerde bir dizeyi uygun tamsayı değerine dönüştürmek için statik int. Int32 yapısının Parse yöntemini çağırmaktır: string s = “42”.ToString()).Parse ile tamamen aynı Bu yapılar ayrıca bazı kullanışlı statik alanları da içerir. Int32.Int64 System.Int32 System.ToString()).Object System.

aşağıda adı Time (zaman) olan ve hours (saatler). Örneğin. yaygın işleçlerin birçoğunu kendi yapı türlerinizde kullanamazsınız. Bunun için sözdizimi. bir yapının alanlarını public yapmak birçok durumda önerilmez. “İşleç Aşırı Yüklenmesi” başlıklı Bölüm 21’de ele alınmıştır. bir başvuru türü değişkeni kopyaladığınızda. Örneğin: struct Time { public Time(int hh. seconds = ss % 60. minutes = mm % 60. int mm. minutes. Örneğin. Bununla birlikte. minutes. seconds. Örneğin. Alanları private tanımlamak ve yapınıza kurucular ve yöntemler eklemek daha iyi bir fikirdir. Örneğin. } . Bir değer türü değişkenini kopyaladığınızda. private int hours. minutes (dakikalar) ve seconds (saniyeler) adlı üç public int alan içeren bir yapı görebilirsiniz: struct Time { public int hours. biri diğeri kadar iyidir.174 Kısım II C# Dilini Anlamak Bir Yapı Bildirmek Kendi yapı değer türünüzü bildirmek için. int bir değer türüdür çünkü başlıca özelliği değeridir. Basit kavramları uygulamak için başlıca özelliği değerleri olan yapıları kullanın. } public int Hours() { return hours. } Sınıflardaki gibi. Bunun aksine. } Not Varsayılan ayar olarak. herhangi biri minutes ya da seconds’ın değerini 60’dan büyük bir değere atayabilir. bir adres kopyalamak gibi . kendi yapı türlerinizi açık bir şekilde bildirebilir ve işleçleri uygulayabilirsiniz. struct anahtar sözcüğü. eşitlik işleci (==) ve eşitsizlik işleci (!=) gibi işleçleri kendi yapı türü değişkenleriniz üzerinde kullanamazsınız. onun arkasından da açılan ve kapanan küme parantezleri arasında yapının gövdesini yazarsınız. int ss) { hours = hh % 24. seconds.. arkasından tür adı. Özetle. aynı nesneye iki başvuru elde edersiniz. public alanların geçerli değerler içerdiğinden emin olmanın bir yolu yoktur. Aynı değere sahip (42 gibi) iki int değişkenine sahipseniz. değerin iki kopyasını elde edersiniz..

. } . minutes = mm. varsayılan kurucu tarafından yaratılmış bir yapı değerinin mantıklı davrandığından ve bu varsayılan değerlerle bir anlam ifade ettiğinden emin olun. Örneğin. varsayılan olmayan bir kurucu sağlayarak alanlara farklı değerler atayabilirsiniz. aksi takdirde derleme hatası alırsınız.. derleyici sizin için değer atamaz. Bu varsayılan değerleri kullanmak istemiyorsanız.. Daha karmaşık veriler için sınıfları kullanın. derleyici ancak siz kendi kurucunuzu yazmazsanız varsayılan bir kurucu yazar. derleyicinin her zaman bir tane üretmesidir. minutes.Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 175 değeri kopyalamaya yeterli olacak kadar küçük değerler için yapıları kullanın. Bir sınıfta. Bununla birlikte. private int hours. varsayılan olmayan yapı kurucunuzda alana başlangıç değeri atamazsanız. böylece kodunuzun verimliliğini artırmak istediğinizde sadece gerçek değerin adresini kopyalama seçeneğine sahip olursunuz. } // derleme zamanı hatası: seconds başlatılmamış . Yapı ve Sınıf Farklarını Anlamak Bir yapı ve bir sınıf. } // derleme zamanı hatası . Bu nedenle.. false ya da null atar –tıpkı sınıflarda olduğu gibi.. Bu farklılıkların bazılarına bakalım: n Bir yapı için varsayılan bir kurucu (parametreleri olmayan bir kurucu) bildiremezsiniz. Yani.. seconds. Bir yapı için derleyici tarafından üretilmiş varsayılan kurucu her zaman alanlara 0. } Bir yapı için kendi varsayılan kurucunuzu bildirememenizin nedeni. Örneğin. aşağıda Time sınıf olsaydı derlenecekti ama bir yapı olduğundan derlenmeyecektir: struct Time { public Time() { . sözdizimi açısından benzerdir fakat birkaç önemli farklılık vardır. varsayılan olmayan tüm yapı kurucularınızdaki tüm alanlara açık bir şekilde değer atamalısınız. int mm) { hours = hh. Time bir sınıf olsaydı aşağıdaki örnek derlenecek ve seconds’ı sessizce 0 olarak başlatacaktı ama Time bir yapı olduğundan derlenmeyecektir: struct Time { public Time(int hh.

. seconds. private int hours = 0. } Aşağıdaki tablo. alanlar ve parametreler yaratabilirsiniz: struct Time { . yapının adını diğer türler gibi bir türün adı olarak kullanabilirsiniz. Artık yapıların nasıl bildirildiğini bildiğinize göre bir sonraki adım değerler yaratmak için onları kullanmak olacaktır. // derleme zamanı hatası private int minutes. } . Hayır Evet Sınıf Sınıflar başvuru türüdür. private int seconds. aşağıdaki gibi. bunu yapamazsınız. Time bir sınıf olsaydı aşağıdaki örnek derlenecekti ama Time bir yapı olduğundan. Yapı örnekleri değerler olarak adlandırılır ve yığında bulunurlar. private int hours.. Yapı Değişkenleri Bildirmek Bir yapı türü bildirdikten sonra.. bir derleme hatasına neden olur: struct Time { . Time türünde değişkenler. Örneğin. Soru Bir başvuru türü mü. derleyici sizin için otomatik olarak başlatır mı? Örnek alanlarını bildirildikleri noktada başlatmanıza izin verilir mi? Hayır Evet Hayır Evet Sınıflarla yapılar arasında kalıtımla ilgili başka farklılıklar da vardır. oluşum alanlarını bildirildikleri noktada başlatabilirsiniz.. derleyici varsayılan bir kurucu üretir mi? Kendi kurucunuzdaki bir alanı başlatmazsanız. Time yapı türünüzün adıysa. Bu farklılıklar. Evet Hayır Bir varsayılan kurucu bildirebilir misiniz? Kendi kurucunuzu bildirirseniz. “Kalıtımla Çalışmak” başlıklı Bölüm 12’de ele alınmıştır. yoksa değer türü müdür? Örnekleri yığında mı öbekte mi bulunur? Yapı Yapılar değer türüdür. Sınıf örnekleri nesneler olarak adlandırılır ve öbekte bulunurlar. Örneğin.176 Kısım II n C# Dilini Anlamak Bir sınıfta. Bir yapıda. bir yapı ve bir sınıf arasındaki başlıca farklılıkları özetler. minutes.

Aşağıdaki şekil now (şimdi) değişkenindeki alanların durumunu göstermektedir: Bir kurucu çağırırsanız. Daha sonra. Bununla birlikte. değişkene null değeri atayabilirsiniz: Time? currentTime = null. Bu alanlardaki değerlere erişmeye çalışılması derleme hatası verecektir.. } private Time currentTime. . bir kurucu çağırmadan yapı değişkenleri yaratabilirsiniz: Time now.. aşağıdaki örnekte gösterildiği gibi. yapıdaki tüm alanların başlatılacağını garanti eder: Time now = new Time().Bölüm 9 class Example { public void Method(Time parameter) { Time localVariable. değişken yaratılmış fakat alanlarına değer atanmamıştır. bir kurucu kullanılarak bir yapıdaki alanların nasıl başlatıldığını gördünüz. daha önce tanımlanmış çeşitli yapı kurucuları kuralları. . yapılar değer türleri olduğundan. Bu örnekte. Yapı Başlatmayı Anlamak Bu bölümde daha önce. } Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 177 Not ? düzenleyicisini kullanarak bir yapı değişkeninin boş olabilen sürümünü yaratabilirsiniz.

. } . kullanıcı tarafından tanımlanmış kurucuyu çağırarak now değişkenine başlangıç değeri atar: Time now = new Time(12. seconds. 30). private int hours.. varsayılan kurucu yapıdaki alanları başlatır: Her iki durumda da. minutes. aşağıdaki şekilde gösterildiği gibi. Time değişkeninin yığın üzerinde yaratıldığına dikkat edin. minutes = mm. int mm) { hours = hh. seconds = 0. yapı değişkenine başlangıç değeri atamak için onu da kullanabilirsiniz. Aşağıdaki şekil. bir yapı kurucusu her zaman açık bir şekilde tüm alanlarına başlangıç değeri atamak zorundadır. Örneğin: struct Time { public Time(int hh. Kendi yapı kurucunuzu yazdıysanız. } Aşağıdaki örnek.178 Kısım II C# Dilini Anlamak Bu defa. Bu bölümde daha önce açıklandığı gibi. bu örneğin etkisini gösterir: .

Şimdi. tüm yapının içeriğini kopyalayan hızlı. bir tarihi yansıtması için bir yapı türü yaratacak ve kullanacaksınız. Örneğin. Time bir sınıf olduğunda gerçekleşen kopyalama işlemini karşılaştırın. Not C++ programcıları. 30). aşağıdaki örnek derlenecektir çünkü now tümüyle başlatılmıştır. . tek bir işlemdir ve özel bir durum oluşturmaz.) Time now = new Time(12. Bu kopyalama. (Şekilde atama işleminin sonuçları görünmektedir. her iki değişken de (now ve copy ). bu kopyalama davranışını değiştiremeyeceklerine dikkat etmelidir. sol taraftaki bütün alanlar doğrudan sağ taraftaki uygun alandan kopyalanır. öbek üzerinde aynı nesneye başvururdu. çünkü now tam olarak başlatılmamıştır: Time now. // derleme zamanı hatası: now atanmamış Bir yapı değişkenini kopyaladığınızda. Time copy = now. Aşağıdaki örnek derlenmeyecektir.Bölüm 9 Numaralandırma ve Yapılar ile Değer Türleri Yaratmak 179 Yapı Değişkenlerini Kopyalamak Bir yapı değişkenini diğer bir yapı değişkenine eşitleyebilir ya da atayabilirsiniz. Bu kopyalama işlemiyle. bu bilgiyi uygulamaya koymanın zamanı geldi. Time copy = now. Aşağıdaki alıştırmada. Time bir sınıf olsaydı. tüm alanlarına başlangıç değeri atanmışsa) yapabilirsiniz. fakat bunu yalnızca sağdaki yapı değişkeni tam olarak başlatılmışsa (yani.

180

Kısım II

C# Dilini Anlamak

Bir yapı türü yaratın ve kullanın
1. StructsAndEnums projesinde, Code and Text Editor penceresinde Date.cs dosyasını görüntüleyin. 2. StructsAndEnums ad alanı içine Date adında bir yapı ekleyin. Bu yapı, üç private alan içermelidir: Biri int türünde year adlı, biri Month (bir önceki alıştırmada numaralandırma kullanarak yarattığınız) türünde month adlı ve diğeri de int türünde day adlı üç alan. Date yapısı tam olarak şu şekilde görünmelidir:
struct Date { private int year; private Month month; private int day; }

Derleyicinin Date için üreteceği varsayılan kurucuyu düşünün. Bu kurucu year’ı 0’a, month’u 0’a (January değeri) ve day’i de 0’a eşitleyecektir. Yıl için 0 değeri geçersizdir (0 yılı yoktur) ve aynı zamanda gün için de 0 değeri geçersizdir (her ay 1. günden başlar). Bu sorunu düzeltmenin bir yolu, year ve day değerlerini çevirmektir. Böylece, Date yapısı, year alanı Y değeri aldığında Y+1900 değerini (isterseniz başka bir yüzyılı da alabilirsiniz) ve day alanı D değerini aldığında, D+1 değerini gösterecektir. Varsayılan kurucu, üç alana 1 January 1900 değerini gösteren değerler atar. 3. Date yapısına, bir public kurucu ekleyin. Bu kurucu üç parametre almalıdır: year için ccyy adlı bir int, month için mm adlı bir Month ve day için dd adlı bir int. Bu üç parametreyi uygun alanları başlatmak için kullanın. Y olan bir year alanı Y+1900’ü ifade ettiğinden, year alanını ccyy-1900 olarak başlatmalısınız. D olan bir day alanı D+1’i ifade ettiğinden, day alanını dd-1 olarak başlatmalısınız. Date yapısı şimdi şöyle görünmelidir (kurucu koyu harflerle gösterilmiştir):
struct Date { public Date(int ccyy, Month mm, int dd) { this.year = ccyy - 1900; this.month = mm; this.day = dd - 1; } private int year; private Month month; private int day; }

Bölüm 9

Numaralandırma ve Yapılar ile Değer Türleri Yaratmak

181

4. Date yapısına, kurucudan sonra ToString adında bir public yöntem ekleyin. Bu yöntem herhangi bir bağımsız değişken almaz, tarihin dize gösterimini döndürür. year alanının değerinin year + 1900 gösterdiğini ve day alanının day + 1 gösterdiğini hatırlayın. Not ToString yöntemi, şimdiye kadar gördüğünüz yöntemlerden biraz farklıdır. Tanımladığınız yapılar ve sınıflar da dahil olmak üzere, her tür, siz isteseniz de istemeseniz de otomatik olarak bir ToString yöntemine sahiptir. Varsayılan davranışı, bir değişkendeki değeri dize gösterimine çevirmektir. Bazen, varsayılan davranış anlamlıdır; bazen de yetersizdir. Örneğin, Date sınıfı için üretilmiş olan ToString yönteminin varsayılan davranışı, basitçe “StructsAndEnums.Date” dizesini oluşturacaktır. override anahtar sözcüğünü kullanarak, bu yöntemin varsayılan davranışını geçersiz kılan yeni bir sürümünü tanımlamanız gerekir. Yöntemleri geçersiz kılmak Bölüm 12’de ayrıntılarıyla incelenmiştir. ToString yöntemi şöyle görünmelidir:
public override string ToString() { return this.month + “ “ + (this.day + 1) + “ “ + (this.year + 1900); }

Not Parentezler içindeki + işaretleri aritmetik toplama işlecidir. Diğerleri dize birleştirme işlecidir. Parantezler olmadan, tüm + işaretleri dize birleştirme işleci olarak ele alınır. Tek bir ifadede farklı işleçler için aynı semboller olduğunda, bu biraz kafa karıştırıcı olabilir! 5. Code and Text Editor penceresinde Program.cs dosyasını görüntüleyin. 6. Entrance yönteminin sonuna, defaultDate adında bir yerel değişken bildiren ve onu varsayılan Date kurucusu kullanılarak yapılan bir Date değerine atayan bir ifade ekleyin. Entrance yöntemine, Console.WriteLine yöntemini çağırarak konsola defaultDate değişkenini yazan bir başka ifade ekleyin. Not Console.WriteLine yöntemi otomatik olarak, bağımsız değişkenini dize biçimine çevirmek için ToString yöntemini çağırır.

182

Kısım II

C# Dilini Anlamak

Entrance yöntemi şöyle görünmelidir:
static void Entrance() { ... Date defaultDate = new Date(); Console.WriteLine(defaultDate); }

7. Programı oluşturmak ve çalıştırmak için Debug menüsünde, Start Without Debugging’i tıklayın. Konsola January 1 1900 yazıldığını doğrulayın. (İlk olarak, Entrance yönteminin orijinal sonucu görüntülenir.) 8. Visual Studio 2008 programlama ortamına dönmek için Enter’a basın. 9. Code and Text Editor penceresinde, Entrance yöntemine dönün ve iki ifade daha ekleyin. İlk ifade, halloween adında yerel bir değişken bildirip değerini October 31 2008’e atamalıdır. İkinci ifade de halloween değerini konsola yazmalıdır. Entrance yöntemi şimdi şöyle görünmelidir:
static void Entrance() { ... Date halloween = new Date(2008, Month.October, 31); Console.WriteLine(halloween); }

Not new anahtar sözcüğünü yazdığınızda, IntelliSense otomatik olarak, Date türü için iki kurucunun var olduğunu bulacaktır. 10. Debug menüsünde, Start Without Debugging’i tıklayın. Konsolda önceki bilginin altına October 31 2008 yazıldığını doğrulayın. 11. Programı kapatmak için Enter’a basın. Başarılı bir şekilde, enum ve struct anahtar sözcüklerini kullanarak kendi değer türlerinizi tanımladınız ve sonra da bu türleri kod içinde kullandınız.

n

Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 10’a geçin. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Save iletişim kutusu görünürse, Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.

n

Bölüm 9

Numaralandırma ve Yapılar ile Değer Türleri Yaratmak

183

Bölüm 9 Hızlı Başvuru
Bunun İçin
Bir numaralandırma türü bildirmek

Şunu Yapın
enum anahtar sözcüğünü yazın, ardından türün adını ve sonra da iki kuşak imi arasında numaralandırma hazır bilgilerini virgülle ayrılmış olarak listeleyin. Örneğin:
enum Season { Spring, Summer, Fall, Winter }

Bir numaralandırma değişkeni bildirmek Bir numaralandırma değişkenini bir değere atamak

Numaralandırma türünün adını sola yazın ardından değişkenin adını ve noktalı virgül ekleyin. Örneğin:
Season currentSeason;

Numaralandırma hazır bilgisinin adını ait olduğu numaralandırma türü ile birlikte yazın. Örneğin:
currentSeason = Spring; // hata currentSeason = Season.Spring; // doğru

Bir yapı türü bildirmek

struct anahtar sözcüğünü yazın, ardından yapı türünün adını ve sonra da yapının gövdesini (kurucular, yöntemler ve alanlar) ekleyin. Örneğin:
struct Time { public Time(int hh, int mm, int ss) { ... } ... private int hours, minutes, seconds; }

Bir yapı değişkeni bildirmek

Yapı türünün adını yazın, ardından değişkenin adını ve noktalı virgül ekleyin. Örneğin:
Time now;

Bir yapı değişkenini bir değere atamak

Bir yapı kurucusu çağrılarak yaratılmış bir yapı değerini değişkene başlangıç değeri olarak atayın. Örneğin:
Time lunch = new Time(12, 30, 0);

Bölüm 10

Dizileri ve Koleksiyonları Kullanmak
Bu bölümü tamamladıktan sonra öğrenecekleriniz:
n n

Dizi değişkenlerini bildirmek, başlatmak, kopyalamak ve kullanmak. Çeşitli koleksiyon türlerini bildirmek, başlatmak, kopyalamak ve kullanmak.

Birçok farklı türlerin değişkenlerini nasıl yaratacağınızı ve kullanacağınızı gördünüz. Bununla birlikte, şimdiye kadar gördüğünüz değişken örneklerinin tümünde ortak olan bir şey vardır; tek bir öğe ile ilgili bilgiyi tutarlar (bir int, bir float, bir Circle, bir Time ve bunun gibi). Peki, bir öğeler kümesini işlemeniz gerektiğinde ne olacak? Bir çözüm, kümedeki her öğe için bir değişken yaratmak olabilir, fakat bu çözüm çok sayıda soru getirir: Kaç adet değişken gerekir? Bu değişkenlerin adları ne olmalıdır? Kümedeki her bir öğe üzerinde aynı işlemi gerçekleştirmeniz gerekiyorsa (tamsayılar kümesindeki her bir değişkeni artırmak gibi), çok sayıda kod tekrarından nasıl kaçınılabilir? Bu çözüm, programı yazarken kaç öğeye ihtiyacınız olacağını bildiğinizi varsayar, fakat bu ne kadar sıklıkla olan bir durumdur? Örneğin, bir veritabanındaki kayıtları okuyan ve işleyen bir uygulama yazıyorsanız, veritabanında kaç adet kayıt vardır ve bu sayının değişme ihtimali nedir? Diziler ve koleksiyonlar, bu sorularla ifade edilen problemleri çözen teknikler sağlar.

Dizi Nedir?
Bir dizi (array), sıralanmamış öğeler serisidir. Bir dizideki tüm öğeler aynı türdedir (bir yapıdaki ya da sınıftaki farklı türlerde olabilen alanların aksine). Bir dizinin öğeleri, bir bellek bloğunda bitişik olarak tutulur ve (adlarıyla erişilen, bir yapıdaki ya da sınıftaki alanların aksine) tamsayı dizinler kullanılarak erişilirler.

Dizi Değişkenleri Bildirmek
Bir dizi değişkenini, öğe türünün adını, ardından da bir çift köşeli parantez ve değişken adını yazarak bildirirsiniz. Köşeli parantezler değişkenin bir dizi olduğunu belirtir. Örneğin, pins (Kimlik Numaraları) adında bir int değişkenler dizisi bildirmek için, aşağıdaki kodu yazarsınız:
int[] pins; // Kişisel Kimlik Numaraları

Microsoft Visual Basic ile program geliştirenler, parantez değil de köşeli parantez kullanıldığına dikkat etmelidir. C ve C++ ile program geliştirenler, dizinin boyutunun bildirim

185

186

Kısım II

C# Dilini Anlamak

içinde belirtilmediğine dikkat etmelidir. Java ile program geliştirenler ise, köşeli parantezleri değişken adından önce yazmak gerektiğine dikkat etmelidir. Not Dizi öğeleri olarak, temel türlerle sınırlı değilsiniz. Ayrıca, yapılar, numaralandırmalar
ve sınıfların dizisini yaratabilirsiniz. Örneğin, aşağıdaki gibi Time yapılarının bir dizisini yaratabilirsiniz:
Time[] times;

İpucu Dizi değişkenlerine, (her öğe bir Place(yer) olduğunda) places (yerler), (her öğe bir

Person(kişi) olduğunda) people (insanlar) ya da (her öğe bir Time(zaman) olduğunda) times (zamanlar) gibi, çoğul adlar vermek çoğu zaman kullanışlıdır.

Bir Dizi Oluşumu Yaratmak
Diziler, öğelerin türü ne olursa olsun, başvuru türüdür. Yani, dizi değişkeni öbek üzerinde dizi öğelerini tutan bitişik bellek bloğuna başvurur (bir sınıf değişkeninin öbek üzerindeki bir nesneye başvurduğu gibi), dizi öğelerini doğrudan yığın üzerinde tutmaz (bir yapının yaptığı gibi). (Değerleri, başvuruları ve yığın ile öbek arasındaki farkları yeniden gözden geçirmek için, “Değerler ve Başvuruları Anlamak” başlıklı Bölüm 8’e bakın.) Bir sınıf değişkeni bildirdiğinizde, siz new anahtar sözcüğünü kullanarak bir oluşum yaratana kadar nesne için bellek ayrılmaz. Diziler de aynı kuralları izler; bir dizi değişken bildirdiğinizde, boyutunu bildirmezsiniz. Dizi boyutunu, gerçekten bir dizi oluşumu yarattığınızda belirtirsiniz. Bir dizi oluşumu yaratmak için, new anahtar sözcüğünü ardından da öğe türünün adını ve köşeli parantez içinde yarattığınız dizinin boyutunu yazarsınız. Bir dizi yaratmak, aynı zamanda öğelerine varsayılan değerleri de (öğenin türünün sayısal, başvuru ya da Boolean olmasına bağlı olarak sırasıyla 0, null ya da false) atar. Örneğin, önceden bildirilmiş pins değişkeni için yeni bir dört tamsayıdan oluşan dizi yaratmak ve pins değişkenine atamak için şunu yazarsınız:
pins = new int[4];

Aşağıdaki şekil bu ifadenin etkilerini gösterir:

Bölüm 10

Dizileri ve Koleksiyonları Kullanmak

187

Bir dizi oluşumunun boyutu sabit olmak zorunda değildir, aşağıdaki örnekte gösterildiği gibi çalışma zamanında hesaplanabilir:
int size = int.Parse(Console.ReadLine()); int[] pins = new int[size];

Boyutu 0 olan bir dizi yaratabilirsiniz. Bu biraz tuhaf gelebilir, fakat bir dizinin boyutu dinamik olarak belirlenebiliyorsa ve 0 olabiliyorsa, bu durum yararlıdır. 0 boyutundaki bir dizi null değildir. Ayrıca çok boyutlu diziler oluşturmak da mümkündür. Örneğin, iki boyutlu bir dizi oluşturmak için, iki tamsayı dizini olması gereken bir dizi yaratırsınız. Çok boyutlu dizilerin incelemesi bu kitabın kapsamı dışındadır fakat aşağıda bir örneğini görebilirsiniz:
int[,] table = new int[4,6];

Dizi Değişkenlerini Başlatmak
Bir dizi oluşumu yarattığınızda, dizi oluşumunun tüm öğeleri, türlerine bağlı olarak varsayılan bir değerle başlatılırlar. Bu davranışı değiştirebilir ve isterseniz bir dizinin öğelerini belirli değerlerle başlatabilirsiniz. Bu belirli değerleri, küme parantezi içinde virgülle ayırarak yazarsınız. Örneğin, pins’i, değerleri 9, 3, 7 ve 2 olan dört int değişken dizisi olarak başlatmak için şunu yazabilirsiniz:
int[] pins = new int[4]{ 9, 3, 7, 2 };

Küme parantezi arasındaki değerler sabit olmak zorunda değildir. Aşağıdaki örnekte gösterildiği gibi, çalışma zamanında hesaplanan değerler olabilirler:
Random r = new Random(); int[] pins = new int[4]{ r.Next() % 10, r.Next() % 10, r.Next() % 10, r.Next() % 10 };

Not System.Random sınıfı, bir rastgele sayı üreticisidir. Next yöntemi, varsayılan ayar olarak, 0 ile Int32.MaxValue arasında rastgele bir negatif olmayan sayı döndürür. Next yöntemi aşırı yüklenmiştir ve diğer sürümler sayı aralığının minimum ve maksimum değerlerini belirlemenize olanak tanır. Random sınıfı için varsayılan kurucu, zamana bağımlı tohum değer ile rastgele sayı üreticisini tohumlar. Böylece rastgele sayıları birden fazla kullanma olasılığını azaltır. Kurucunun aşırı yüklenmiş sürümü, kendi tohum değerinizi sağlamanıza imkan tanır. Bu yolla, test amacınız için tekrarlanabilir rastgele sayıların sırasını üretebilirsiniz.

188

Kısım II

C# Dilini Anlamak

Küme parantezi arasındaki değerlerin sayısı, tam olarak yaratılan dizi oluşumunun boyutuna eşit olmalıdır:
int[] pins = new int[3]{ 9, 3, 7, 2 }; // derleme zamanı hatası int[] pins = new int[4]{ 9, 3, 7 }; // derleme zamanı hatası int[] pins = new int[4]{ 9, 3, 7, 2 }; // tamam

Bir dizi değişkenini başlatırken, new deyimini ve dizinin boyutunu yazmayabilirsiniz. Derleyici, dizi boyutunu, başlatıcıdan itibaren hesaplar ve diziyi yaratmak için kodu üretir. Örneğin:
int[] pins = { 9, 3, 7, 2 };

Bir yapı dizisi yaratıyorsanız, dizideki her yapıyı yapı kurucusunu çağırarak başlatabilirsiniz. Örneğin:
Time[] schedule = { new Time(12,30), new Time(5,30) };

Örtülü Yazılmış Dizi Yaratmak
Bir dizi bildirirken öğe türü, dizi içinde saklayacağınız öğe türü ile eşleşmek zorundadır. Örneğin, önceki örnekte gösterildiği gibi, pins dizisini int türünde bildirirseniz, bu dizide double, string, struct ya da int dışında herhangi bir tür saklayamazsınız. Bir dizi bildirirken bir başlatıcı listesi belirtirseniz, C# derleyicisinin sizin için dizideki öğelerin gerçek türünü anlamasını sağlayabilirsiniz. Örneğin:
var names = new[]{“John”, “Diana”, “James”, “Francesca”};

Bu örnekte, C# derleyicisi names değişkeninin bir dize dizisi olup olmadığını hesaplar. Bu bildirimde sözdizimi ile ilgili birkaç nokta önemlidir. İlk olarak, tür küme parantezleri arasında yazılmamıştır; bu örnekte names değişkeni basitçe var olarak ya da var[] olmayan olarak bildirilmiştir. İkincisi, başlangıç değerleri listesinden önce köşeli parantez ve new anahtar sözcüğü kullanmanız gerekir. Bu sözdizimini kullanırsanız, tüm başlangıç değerlerinin aynı türde olduğundan emin olmanız gerekir. Aşağıdaki örnek, “No best type found for implicitly typed array” (Örtülü dizi için en iyi tür bulunamadı) derleme hatasına neden olur.
var bad = new[]{“John”, “Diana”, 99, 100};

Bununla birlikte, bazı durumlarda, mantıklıysa, derleyici öğeleri başka bir türe çevirir. Aşağıdaki kodda, 3.5 ve 99.999 değerlerinin her ikisi de double olduğundan numbers (sayılar), bir double dizidir ve C# derleyicisi, 1 ve 2 tamsayı değerlerini double değerlere çevirebilir:
var numbers = new[]{1, 2, 3.5, 99.999};

Bölüm 10

Dizileri ve Koleksiyonları Kullanmak

189

Genel olarak, karışık türlerden kaçınmak ve derleyicinin türleri sizin için çevirmesini beklemek en iyisidir. Örtülü olarak yazılmış diziler, “Sınıflar ve Nesneleri Yaratmak ve Yönetmek” başlıklı Bölüm 7’de tanımlanan anonim türlerle çalıştığınızda çok kullanışlıdır. Aşağıdaki kod, anonim nesnelerin bir dizisini yaratır.
var names = new[] { new new new new { { { { Name Name Name Name = = = = “John”, Age = 42 }, “Diana”, Age = 43 }, “James”, Age = 15 }, “Francesca”, Age = 13 } };

Anonim türlerdeki alanlar, dizinin tüm öğelerinde aynı olmalıdır.

Dizi Öğelerine Tek Tek Erişmek
Tek tek dizi öğesine erişmek için, istediğiniz öğenin hangisi olduğunu gösteren dizini yazmanız gerekir. Örneğin, aşağıdaki kodu kullanarak, pins dizisinin 2 öğesinin içeriğini bir int değişkene atayabilirsiniz:
int myPin; myPin = pins[2];

Benzer şekilde, dizinli bir öğeye bir değer atayarak bir dizinin içeriğini değiştirebilirsiniz:
myPin = 1645; pins[2] = myPin;

Dizi dizinleri sıfır tabanlıdır. Bir dizinin ilk öğesi 1 dizininde değil, 0 dizininde bulunur. 1 dizini kullanılarak ikinci öğeye erişilir. Bütün dizi öğesi erişimleri, sınır denetimlidir. 0’dan küçük ya da dizinin boyutuna eşit ya da büyük bir dizin belirtirseniz, derleyici aşağıdaki örnekte olduğu gibi IndexOutOfRangeException (DizinAralıkDışındaÖzelDurumu) özel durumunu oluşturur:
try { int[] pins = { 9, 3, 7, 2 }; Console.WriteLine(pins[4]); // hata, 4. ve son öğe dizin 3’te } catch (IndexOutOfRangeException ex) { ... }

190

Kısım II

C# Dilini Anlamak

Bir Dizi Boyunca Yineleme Yapmak
Diziler çok sayıda kullanışlı yerleşik özellikler ve yöntemlere sahiptir. (Tüm diziler, Microsoft .NET Framework’deki System.Array sınıfından yöntemleri ve özellikleri miras alır.) Bir dizinin kaç adet öğe içerdiğini bulmak için Length (Uzunluk) özelliğini sorgulayabilir ve bir for ifadesi kullanarak dizinin tüm öğeleri boyunca yineleme yapabilirsiniz. Aşağıdaki örnek kod, pins dizisinin dizi öğesi değerlerini konsola yazar:
int[] pins = { 9, 3, 7, 2 }; for (int index = 0; index < pins.Length; index++) { int pin = pins[index]; Console.WriteLine(pin); }

Not Length, yöntem değil bir özelliktir, bu nedenle parantez yazılmadan çağrılır. “Alanlara Erişmek için Özellikleri Kullanmak” başlıklı Bölüm 15’de özellikler hakkında daha fazlasını öğreneceksiniz. Dizilerin 0 öğesinde başladığı ve son öğenin de Length – 1 olarak numaralandırıldığı, programlamaya yeni başlayanlar tarafından genellikle unutulur. C#, bu konuyu düşünmeden dizinin öğeleri üzerinde yineleme yapabilmenize imkan tanıyan foreach ifadesini sağlar. Örneğin, önceki for ifadesi, foreach ifadesi olarak şu şekilde yazılır:
int[] pins = { 9, 3, 7, 2 }; foreach (int pin in pins) { Console.WriteLine(pin); }

foreach ifadesi, dizinin içindeki öğelerin değerlerini otomatik olarak sırayla alan bir yineleme değişkeni (bu örnekte, int pin) tanımlar. Bu değişkenin türü, dizideki öğelerin türü ile aynı olmalıdır. foreach ifadesi bir dizinin öğeleri boyunca yineleme yapmak üzere kullanılmak için tercih edilen yöntemdir; kodun ifade etmeye çalıştığı şeyi daha doğrudan belirtir ve tüm for döngüsü yapısını kaldırır. Bununla birlikte, bazı durumlarda, for ifadesine dönmek zorunda kalabilirsiniz. Bu durumlar şunlardır:
n

Bir foreach ifadesi her zaman, bir dizinin bütün öğelerini sonuna kadar yineler. Bir dizinin belirli bir bölümü boyunca yineleme yapmak istiyorsanız (örneğin ilk yarısında) ya da belirli öğeleri atlamak istiyorsanız (örneğin, her üç öğeden birini), for ifadesi kullanmak daha kolaydır. Bir foreach ifadesi her zaman, sıfır dizininden Length – 1 dizinine kadar yineleme yapar. Geriye doğru yineleme yapmak istiyorsanız, bir for ifadesi kullanmak daha kolay olur. Döngünün gövdesinin, öğenin değerindense öğenin dizinini bilmesi gerekiyorsa, for ifadesi kullanmalısınız.

n

n

Bölüm 10
n

Dizileri ve Koleksiyonları Kullanmak

191

Dizinin öğelerini değiştirmeniz gerekiyorsa, for ifadesi kullanmanız gerekir. Çünkü foreach ifadesinin değişkeni, dizinin her öğesinin salt okunur bir kopyasıdır.

Yineleme değişkenini bir var olarak bildirebilir ve C# derleyicisinin, değişkenin türünü dizinin öğelerinin türünden bulmasına izin verebilirsiniz. Bu, özellikle dizi anonim nesneler içerdiği zaman olduğu gibi, dizideki öğelerin türünü bilmiyorsanız kullanışlıdır. Aşağıdaki örnek, daha önce gösterilmiş anonim öğelere sahip bir dizi boyunca nasıl yineleme yapabileceğinizi gösterir:
var names = new[] { new { Name = “John”, Age = 42 }, new { Name = “Diana”, Age = 43 }, new { Name = “James”, Age = 15 }, new { Name = “Francesca”, Age = 13 } }; foreach (var familyMember in names) { Console.WriteLine(“Name: {0}, Age: {1}”, familyMember.Name, familyMember.Age); }

Dizileri Kopyalamak
Diziler başvuru türleridir. (Bir dizinin System.Array sınıfının bir oluşumu olduğunu hatırlayın.) Bir dizi değişkeni, bir dizi oluşumuna yapılan başvuruyu içerir. Bunun anlamı, bir dizi değişkenini kopyaladığınızda aynı dizi oluşumuna başvuru yapan iki başvuru elde edeceğinizdir. Örneğin:
int[] pins = { 9, 3, 7, 2 }; int[] alias = pins; // alias ve pins aynı dizi oluşumuna başvurur

Bu örnekte, pins[1] değerini değiştiriyorsanız, değişiklik aynı zamanda alias[1] değerinde de görünür. Bir dizi değişkeninin başvurduğu dizi oluşumunun bir kopyasını oluşturmak isterseniz, iki şey yapmanız gerekir. İlk olarak, kopyalayacağınız dizi ile aynı türde ve aynı uzunlukta yeni bir dizi oluşumu yaratmalısınız. Örneğin:
int[] pins = { 9, 3, 7, 2 }; int[] copy = new int[4];

Bu çalışır, ama orijinal dizinin uzunluğunu değiştirmek için kodu daha sonra düzenlerseniz, kopyanın da uzunluğunu değiştirmeyi unutmamalısınız. Bir dizinin uzunluğunu onun Length özelliğiyle belirtmek daha iyi olur. Örneğin:
int[] pins = { 9, 3, 7, 2 }; int[] copy = new int[pins.Length];

copy değişkeni içindeki değerler şimdi, varsayılan değerleri olan 0 (sıfır) ile (sıfırla) başlatılmıştır.

192

Kısım II

C# Dilini Anlamak

Yapmanız gereken ikinci şey ise, yeni dizinin içindeki değerleri orijinal dizinin içindekilere eşitlemektir. Aşağıdaki örnekte gösterildiği gibi, bunu bir for ifadesi kullanarak yapabilirsiniz:
int[] pins = { 9, 3, 7, 2 }; int[] copy = new int[pins.Length]; for (int i = 0; i < copy.Length; i++) { copy[i] = pins[i]; }

Bir diziyi kopyalamak, birçok uygulama için yaygın bir gereksinimdir; o kadar ki, System.Array sınıfı, kendi kodunuzu yazmak yerine, kullanabileceğiniz bazı kullanışlı yöntemler sağlar. Örneğin, CopyTo yöntemi, verilen bir başlangıç dizininden başlayarak bir dizinin içeriğini diğer bir diziye kopyalar.
int[] pins = { 9, 3, 7, 2 }; int[] copy = new int[pins.Length]; pins.CopyTo(copy, 0);

Değerleri kopyalamanın bir diğer yolu, Copy adlı System.Array statik yöntemini kullanmaktır. CopyTo yönteminde olduğu gibi, Copy yöntemini çağırmadan önce hedef diziyi başlatmanız gerekir.
int[] pins = { 9, 3, 7, 2 }; int[] copy = new int[pins.Length]; Array.Copy(pins, copy, copy.Length);

Diğer bir yol ise Clone adlı System.Array oluşum yöntemini kullanmaktır. Tümüyle bir dizi yaratmak ve bir hareketle kopyalamak için bu yöntemi çağırabilirsiniz:
int[] pins = { 9, 3, 7, 2 }; int[] copy = (int[])pins.Clone();

Not Clone yöntemi gerçekte bir object döndürür. Bu nedenle kullandığınızda uygun türün dizisine dönüştürmeniz gerekir. Üstelik, daha önce kopyalama için gösterilen tüm yöntemler, dizinin bir shallow (sığ) kopyasını yaratır; kopyalanan dizinin öğeleri başvurular içeriyorsa, for döngüsü ve önceki üç yöntem, başvurulan nesne yerine başvuruları kopyalar. Kopyalamadan sonra, her iki dizi de aynı nesneler kümesine başvurur. Bir dizi gibi, derin kopyalama gerekirse, bir for döngüsünde uygun kodu kullanmanız gerekir.

Koleksiyon Sınıfları Nedir?
Diziler, aynı türdeki öğeleri bir araya getirmek için iyi bir yöntemdir ama tek yöntem değildir. Microsoft .NET Framework, öğeleri özel yollardan bir araya toplayan birkaç sınıf sağlar. Bunlar koleksiyon sınıflarıdır ve System.Collections ad alanı ve alt ad alanlarında bulunurlar.

Bunun altında yatanları anlamak için. bir koleksiyona bir değer eklediğinizde. her zaman object (nesne) olmayan ve başvurular kadar değer türlerini de tutabilen koleksiyon sınıfları vardır. koleksiyon sınıfının öğe türü object’tir. otomatik olarak kutulanır ve dizi öğesi (bir nesne başvurusu) tamsayı değerin kutulanmış kopyasına başvurur (kutulama hakkında bilgileri hatırlamak için Bölüm 8’e bakın. int bir değer türü olduğundan. int değişkenlerden oluşan bir dizi. değer her zaman kutulanır.NET Framework Sınıf Kütüphanesi belgelerine başvurun. Her bir sınıf hakkında daha ayrıntılı bilgi için. doğrudan int değerler tutar: Şimdi. öğelerini nesne olarak tutar.) Bu durum.Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 193 Temel koleksiyon sınıfları. Bir tamsayı değer eklediğinizde. aşağıda gösterildiği gibi. dizi. fakat bunlar hakkında konuşmadan önce C#’da daha fazla bilgiye sahip olmalısınız. nesnelerden oluşan bir diziyi (nesne bir başvuru türüdür) karşılaştırmak yararlı olur. Aşağıdaki bölümler en önemli dört koleksiyon sınıfı hakkında genel bir bakış sunmaktadır. ona istediğiniz türde değerler ekleyebilirsiniz). . Not Öğe türü. int öğelerden oluşan bir diziyle (int bir değer türüdür). nesnelerden oluşan bir dizi olsaydı neler olacağını düşünün. Koleksiyondan bir değer çıkarırsanız bir dönüştürme kullanarak onun kutusunu açmalısınız. yani. alır ve döndürürler. Bu diziye de int değerler ekleyebilirsiniz (aslında. Bunun anlamı. Microsoft . Bu koleksiyon sınıfları ile “Genellemelere Giriş” başlıklı Bölüm 18’de tanışacaksınız. aşağıdaki resimde gösterilmiştir: Bu bölümde gösterilen tüm koleksiyon sınıflarının öğe türü nesnedir (object).

Bir ArrayList’in ortasına Insert yöntemini kullanarak bir öğe ekleyebilirsiniz. 7. 10. çünkü son öğenin iki kopyasıyla karşı karşıya kalırsınız. Bir diziye bir öğe eklemek isterseniz. 7. // ArrayList’i doldur foreach (int number in new int[12]{10. Köşeli parantez içinde dizi öğesinin dizinini yazarak. Bu tam olarak çalışmaz.Add(number). bir ArrayList’te yineleme yapmak için foreach ifadesini kullanırsanız. } .. o öğeden sonraki tüm öğeleri bir adım kaydırmalısınız. . Add ya da Insert yöntemini çağıramazsınız.. . 5.. boş bir yer yaratmak için bütün öğeleri bir adım kaydırmanız gerekir. öğeleri kopyalamanız (yeni dizi daha küçükse bazı öğeleri atlayarak) ve daha sonra dizi başvurularını güncelleştirmeniz gerekir. ArrayList numbers = new ArrayList(). ArrayList öğeleri kaydırma işini otomatik olarak halleder. ArrayList kendi uzunluğunu bilir ve gerekirse kendini yeniden boyutlandırır. ArrayList içeriğini değiştirmek için yineleme değişkeni kullanamazsınız. n n n Not Dizilerde olduğu gibi. 3. bir ArrayList nesnesindeki bir öğeye başvurabilirsiniz.194 Kısım II C# Dilini Anlamak ArrayList Koleksiyon Sınıfı ArrayList bir dizideki öğelerin sıralarını kaydırmak için yararlı bir sınıftır. 8. 4.Collections. Yine... 2. using System. bir ArrayList boyunca yinelenen bir foreach döngüsünde Remove. İşte ArrayList’i kullanarak konsola 10’dan 1’e kadar olan sayıları nasıl yazdıracağınıza bir örnek: using System. 1}) { numbers. Fakat son öğeyi kaybedersiniz! n n ArrayList sınıfının kısıtlamalarının üstesinden gelmek için aşağıdakileri yapabilirsiniz: n Bir ArrayList’den bir öğeyi Remove yöntemini kullanarak kaldırabilirsiniz. Bir ArrayList’in sonuna Add yöntemini kullanarak bir öğe ekleyebilirsiniz. Yalnızca eklenecek öğeyi sağlamanız yeterlidir. Ayrıca. Bir diziden bir öğeyi çıkarmak isterseniz. 6.. gerekirse kendini yeniden boyutlandırır. yeni bir dizi yaratmanız. . Sıradan bir dizinin oldukça sınırlayıcı olabildiği belirli olaylar vardır: n Bir diziyi yeniden boyutlandırmak isterseniz. 9.

dizin 6 (10) numbers. i < numbers.. // şimdi 7. Bir ArrayList kullandığınızda Count özelliğini. öğe. bir dizi kullandığınızda ise Length özelliğini sorgularsınız. // değerin kutulamasını kaldıran dönüştürmeyi gör Console.Count.Count-1.WriteLine(number). dizin 3) numbers. . // iterate remaining 10 using a foreach statement foreach (int number in numbers) // dönüştürme gerekmez { Console.Remove(7).Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 195 // listede sondan bir önceki sıraya bir öğe gir ve sondaki öğeyi yukarı taşı // (ilk parametre konum. .RemoveAt(6).. // ikinci parametre eklenen öğe) numbers. } Bu kodun çıktısı şöyledir: 10 9 8 7 6 5 4 3 2 99 1 10 9 8 7 6 5 4 3 2 99 1 Not Bir ArrayList’deki öğe sayısını hesaplama yolu.. bir dizideki öğelerin sayısını sorgulamaktan farklıdır. 99)..WriteLine(number). i++) { int number = (int)numbers[i]. // değeri 7 olan ilk öğeyi kaldır (4.Insert(numbers. öğe olan öğeyi kaldır. // bir for ifadesi kullanarak geri kalan 10 öğede yineleme yap for (int i = 0. } .

Dequeue(). İşte kuyruk ve işlemlerinin bir örneği: using System... 7. 2}) { numbers.Collections. // kuyruğu doldur foreach (int number in new int[4]{9.. Queue numbers = new Queue(). FIFO) mekanizmasını gerçekleştirir.WriteLine(number). .. Console. } .196 Kısım II C# Dilini Anlamak Queue Koleksiyon Sınıfı Queue (Kuyruk) sınıfı. } Bu kodun çıktısı şöyledir: 9 3 7 2 9 3 7 2 9 3 7 2 has has has has joined joined joined joined the the the the queue queue queue queue has has has has left left left left the the the the queue queue queue queue . // değerin kutulamasını kaldırmak için gerekli dönüştürme Console.. } .Count > 0) { int number = (int)numbers.WriteLine(number + “ has left the queue”). .WriteLine(number + “ has joined the queue”). // kuyruk boyunca yinele foreach (int number in numbers) { Console. using System. // kuyruğu boşalt while (numbers. klasik ilk giren ilk çıkar (first-in first-out.. 3.Enqueue(number)... Bir öğe sıraya arkadan katılır (enqueue işlemi) ve sırayı önden terk eder (dequeue işlemi).

. Console. Bunu gözünüzde canlandırabilmek için tabak yığınını düşünün: Yeni tabaklar üste konulur ve tabaklar yine üstten alınır.. . klasik son giren ilk çıkar (last-in first-out. // yığın boyunca yinele foreach (int number in numbers) { Console. (Alttaki tabaklar çok nadir kullanıldığından tozlanır ve bu nedenle tabağa bir yemek koymadan önce yıkamanız gerekir!) İşte bir örnek: using System. ....Pop(). 7. using System. // yığını doldur foreach (int number in new int[4]{9. // yığını boşalt while (numbers. 3. } . } Program çıktısı şu şekildedir: 9 3 7 2 2 7 3 9 2 7 3 9 has has has has been been been been pushed pushed pushed pushed on on on on the the the the stack stack stack stack has has has has been been been been popped popped popped popped off off off off the the the the stack stack stack stack .Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 197 Stack Koleksiyon Sınıfı Stack (yığın) sınıfı. } .WriteLine(number + “ has been popped off the stack”). Bir öğe yığına üstten katılır (push işlemi) ve yığını yine üstten terk eder (pop işlemi). Stack numbers = new Stack().Collections..Count > 0) { int number = (int)numbers. Console.Push(number). 2}) { numbers.. LIFO) mekanizmasını gerçekleştirir.WriteLine(number)..WriteLine(number + “ has been pushed on the stack”).

bir özel durum elde edersiniz.198 Kısım II C# Dilini Anlamak Hashtable Koleksiyon Sınıfı Dizi ve ArrayList türleri. Bellekteki Hashtable boyutu. ContainsKey (Anahtarİçerir) yöntemini kullanarak Hashtable’ın belirli bir anahtarı içerip içermediğini test edebilirsiniz. Bununla birlikte. DictionaryEntry sınıfı. int age = (int)element. Bir Hashtable. // foreach ifadesi boyunca yinele // Yineleyici key/value çiftini içeren DictionaryEntry nesnesini oluşturur foreach (DictionaryEntry element in ages) { string name = (string)element. // Hashtable’ı doldur ages[“John”] = 42. buna çoğu kez associative array (birleşim dizisi) adı verilir. age). Hashtable sınıfı tasarımının bazı önemli sonuçları vardır: n Hashtable. Key özelliği ve Value özellikleri ile her iki diziye de erişim sağlar. Anahtarlar dizisinde mevcut olan bir anahtar eklemek için Add yöntemini çağırırsanız. using System. bir anahtar/değer çiftini eklemek için köşeli parantez kullanırsanız (aşağıdaki örnekte gösterilmiştir). Age: {1}”.Value. } . bazen int türü dışında string. hangi anahtarın hangi değere ait olduğunu takip eder ve belirlenen anahtar ile ilişkilendirilmiş değeri hızlıca ve kolayca elde edebilmenizi sağlar. Bununla birlikte. Tamsayı bir dizini köşeli parantez içinde sağlarsınız (örneğin.. bir DictionaryEntry (SözlükGiriş) elde edersiniz. .. Hashtable (Karışık masa) sınıfı. name. Bir Hashtable boyunca yineleme yapmak için bir foreach ifadesi kullandığınızda. . Bir Hashtable’a bir anahtar/değer çifti eklediğinizde.Key. [4]) ve dizin 4’teki öğeyi elde edersiniz (aslında beşinci öğedir). n n Kişi adları ve yaşlarını ilişkilendiren ve daha sonra bilgiyi yazdıran bir örnek aşağıdadır: using System. biri bağladığınız anahtarları diğeri de bağlamakta olduğunuz değerleri içeren iki nesne dizisi sunarak bu işlevselliği sağlar.. oldukça hızlı büyüyebilir. ages[“Diana”] = 43.WriteLine(“Name: {0}.Collections.. ages[“James”] = 15. Diğer programlama dillerinde. Console.. . Hashtable ages = new Hashtable(). çalışmak için bol miktarda belleğe sahip olduğunda en iyi şekilde çalışan seyrek veri yapısıdır. özel durum ile karşılaşmazsınız. bir öğeye bir tamsayı dizini bağlamayı etkili bir biçimde başarırlar. ages[“Francesca”] = 13. double ya da Time türlerine bağlama yapmak istersiniz.. siz yeni öğeler ekledikçe. aynı anahtardan iki tane içeremez.

Hashtable sınıfına oldukça benzerdir. bir SortedList.Value.Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 199 Bu programın çıktısı şöyledir: Name: Name: Name: Name: James. SortedList sınıfı. değer de aynı dizinli değerler dizisine eklenir. . Bir SortedList boyunca yineleme yapmak için bir foreach ifadesi kullandığınızda. Başlıca farklılık anahtarlar dizisinin her zaman sıralanmış olmasıdır. Age: {1}”. anahtarlar dizisinin sıralamasını bozmamak için doğru dizine eklenir. aynı anahtardan iki tane içeremez. DictionaryEntry nesneleri Key özelliği tarafından sıralanmış olarak döner. ages[“James”] = 15.Collections. using System. Age: 43 SortedList Koleksiyon Sınıfı SortedList (SıralıListe) sınıfı. ages[“Francesca”] = 13. Bu da. name. Age: 42 Francesca. değerlerle ilişkilendirebilirsiniz. age). anahtar/değer çiftlerini SortedList’e istediğiniz sırada ekleyebileceğiniz anlamına gelir.. bir öğe eklediğinizde ya da bir öğeyi kaldırdığınızda. . // foreach ifadesi boyunca yinele // yineleyici key/value çiftini içeren DictionaryEntry nesnesini oluşturur foreach (DictionaryEntry element in ages) { string name = (string)element. Bir SortedList sınıfına bir anahtar/değer çifti eklediğinizde. Age: 15 John.. Console.. Age: 13 Diana. bu defa bir SortedList kullanılmıştır: using System..Key. anahtar. bir DictionaryEntry (SözlükGiriş) elde edersiniz..WriteLine(“Name: {0}. Daha sonra. // SortedList’i doldur ages[“John”] = 42. ages[“Diana”] = 43. otomatik olarak anahtarlar ve değerleri eş zamanlı hale getirir. int age = (int)element. Hashtable sınıfında olduğu gibi.. SortedList ages = new SortedList(). SortedList sınıfını kullanarak da anahtarları. . Bununla birlikte. her zaman anahtarlara göre sıralanırlar. } . Kişi adları ve yaşlarını ilişkilendiren ve daha sonra bilgiyi yazdıran örnek aşağıdadır.

Dizileri ve Koleksiyonları Karşılaştırmak Diziler ve koleksiyonlar arasındaki önemli farklar şunlardır: n Bir dizi. {“James”. ikincisi ise değerdir. Sonuç olarak. Örneğin. diziler tarafından desteklenen sözdizimine oldukça benzer bir sözdizimi kullanarak. 13}}. aşağıdaki ifade. Sürekli olarak Add yöntemi çağırmaya bir alternatiftir: ArrayList numbers = new ArrayList(){10. 15}. o koleksiyon için en uygun yöntemi (ArrayList için Add. Bir dizi çok boyutlu olabilir. 10. . aşağıdaki gibi. Age: 15 John. {“Diana”. bazı koleksiyon türlerini bildirirken aynı zamanda başlatabilirsiniz. 43}. Bir dizi oluşumunun boyutu sabittir ve ne büyüyebilir ne de küçülebilir. daha önce gösterilen numbers ArrayList dizisini yaratır ve başlatır. (Stack ve Queue sınıfları desteklemez. C# derleyicisi. Başka koleksiyonlar içeren bir koleksiyon biraz kafa karıştırmakla birlikte. 4. 5.) Hashtable gibi. aslında bu başlatmayı seri olarak Add yönteminin çağrılmasına dönüştürür. bir koleksiyona. 7. Bunun nedeni. diğer koleksiyonlarda olabilir. 1}. Age: 43 Francesca. Bir koleksiyon gerektiğinde kendini dinamik olarak yeniden boyutlandırabilir.200 Kısım II C# Dilini Anlamak Bu programın çıktısında adlar alfabetik olarak sıralanmıştır: Name: Name: Name: Name: Diana. 2. koleksiyonların öğelerini nesne olarak tutmalarıdır. Age: 42 Koleksiyon Başlatıcılarını Kullanmak Önceki alt bölümlerdeki örnekler. {“Francesca”. Age: 13 James. 7. tuttuğu öğenin türünü tanımlarken bir koleksiyon bunu yapmaz. 6. Her çiftteki ilk öğe anahtar. anahtar/değer çifti alan daha karmaşık koleksiyonlar için. 42}. Bir koleksiyon ise doğrusaldır. 3. Ayrıca. çok boyutlu bir diziyi taklit etmenize olanak tanır. Stack için Push ve bunun gibi) kullanarak tek tek öğeleri nasıl ekleyeceğinizi gösterir. Queue için Enqueue. bu sözdizimini sadece Add yöntemini destekleyen koleksiyonlar için kullanabilirsiniz. 8. n n Not Bir koleksiyondaki öğeler. 9. her anahtar/değer çiftini başlatıcı listesinde anonim tür olarak belirleyebilirsiniz: Hashtable ages = new Hashtable(){{“John”.

Kartlar destede olabilir ya da oyunculara dağıtılmış olabilir. Batı ve Doğu) görüntüler. 2. dizideki kaç aralığın bir PlayingCard (OyunKartı) tuttuğunu ve kaç tanesinin oyunculara dağıtıldığını kaydetmek zorunda kalırsınız. aşağıda gösterildiği gibi. dört oyuncunun elindeki kartları (Kuzey. Formdaki Deal düğmesini tıklayın. bir deste oyun kağıdını dört oyuncuya dağıtmayı gerçekleştiren bir Microsoft Windows Presentation Foundation (WPF) uygulamasını göstermektedir. kartları oyunculara dağıttığınızda. Debug menüsünde. Visual Studio 2008 programı oluşturur ve çalıştırır. daha sonra iki yöntem yazacaksınız: Biri bir deste kartı karıştıracak. Güney. Destedeki 52 kart. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 10\Cards klasöründeki Cards projesini açın. Ayrıca iki düğme vardır: biri kartları dağıtmak ve diğeri de kartları desteye döndürmek için. Kartları dağıtın 1. diğeri ise eldeki kartları desteye geri döndürecek. Önce kodu inceleyecek ve çalışacak. kartlar karışmamış. oyuncuların elindeki kartları desteye geri aldığınızda. Bir sonraki alıştırmada Shuffle yöntemini uygulayacaksınız. Kart destesi ve oyuncuların ellerindeki kartlar ArrayList nesneleri olarak oluşturulur. sonuçta. Bunların bir dizi olarak oluşturulması gerektiğini düşünebilirsiniz. Start Without Debugging’i tıklayın. Benzer şekilde. Microsoft Visual Studio 2008’i başlatın. 3. . Kart destesi için bir dizi kullanırsanız. 4.Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 201 Kart Oyunu Oynamak İçin Koleksiyon Sınıflarını Kullanmak Aşağıdaki alıştırma. her zaman bir destede 52 kart ve oyuncunun elinde 13 kart vardır. oyuncunun elini gösteren dizideki hangi aralıklarda PlayingCard olmadığını da kaydetmeniz gerekir. destede kart kalmayacaktır. Form. Bu doğru. ama genelde gözden kaçan. her oyuncuya 13 adet olacak biçimde dağıtılır: Gördüğünüz gibi.

Hiçbir değişiklik olmaz. Pack sınıfının. Yöntem henüz geliştirilmemiştir. Destede hiç kart olmadığından (kartları desteye döndüren yöntem henüz yazılmadı). Oyun kartı iki alana yayılmıştır: suit (grup) (numaralandırılmış türdür ve Clubs (Sinek). dağıtılacak kart yoktur.NET Framework şimdi rastgele tamsayılar üretmek için kullanacağınız Random (Rastgele) adlı bir sınıf içerir.cs dosyasında. her el sıfırlanır. Bir int türü i değişkeninin değerini 0’dan kartların ArrayList’inin öğe sayısına kadar ilerleten bir for ifadesi ekleyin: . PlayingCard. random adlı Random türünde bir yerel değişken tanımlayıp varsayılan Random kurucusunu kullanarak onu yeni yaratılmış bir Random nesnesine başlatın. Deal). Ayrıca. Hearts (Kupa) ya da Spades (Maça) grubundan biridir) ve pips (sayı) (kartın değerini gösterir). Şimdi bu uygulamada nelerin eksik olduğunu bildiğinize göre. Pack sınıfının Shuffle yöntemini bulun. Visual Studio 2008 programlama ortamına dönmek için formu kapatın.cs dosyasını görüntüleyin. Bir deste kartı karıştırma işlemini gerçekleştirecek birçok yöntem vardır. 2. Oyun kartları. Return to Pack düğmesini tıklayın. 5.202 Kısım II C# Dilini Anlamak 5. Desteyi karıştırın 1. 6. Diamonds (Karo). Bu defa. bir ArrayList yaratan ve bu sınıf tarafından tanımlanmış Accept yöntemini kullanarak ArrayList’e 52 oyun kartını ekleyen bir kurucuya sahip olduğuna dikkat edin. Çünkü henüz kartları desteye döndürecek yöntem yazılmadı. eldeki kartlar yok olur. 4. cards adında bir özel ArrayList alanı içerir. 7. Code and Text Editor penceresinde. Code and Text Editor penceresinde Pack. bu kısımları ekleyeceksiniz. . PlayingCard sınıfı ile gösterilir. Pack sınıfı.cs dosyasını görüntüleyin. } 6. Çünkü kartlar dağıtılmadan önce. Tekrar Deal düğmesini tıklayın. Belki de en kolayı sıradan bir kart seçip onu rastgele bir kartla değiştirmektir. Kodu inceleyin. 3. Shuffle yöntemi şimdi tam olarak aşağıdaki gibi görünmelidir: public void Shuffle() { Random random = new Random(). bir deste kart üzerinde gerçekleştirmek isteyebileceğiniz tipik işlemleri oluşturur. Bu sınıftaki yöntemler (Shuffle. Pack. kartların destesini gösterir.

Shuffle yöntemi şimdi tam olarak aşağıdaki gibi görünmelidir (yeni ifadeler koyu harflerle gösterilmiştir): public void Shuffle() { Random random = new Random(). Burada for ifadesi kullanmak zorunda olduğunuza dikkat edin.Count . bir ArrayList’de var olan öğelere erişmek için kurallı dizi gösterimini (köşeli parantez ve bir dizin) kullanabileceğinize de dikkat edin.Next yöntemine bir üst sınır belirleyebilirsiniz. Bir koleksiyon sınıfı (ArrayList gibi) içindeki öğelerin object türünde olduğunu hatırlayın. Random.Bölüm 10 public void Shuffle() { Random random = new Random(). cardToSwap adında bir yerel değişken bildirin ve aşağıda koyu harflerle gösterildiği gibi.1). i++) { int cardToSwap = random.Next(cards.Count.Count. i < cards.Next(cards.Count – 1 arasında rastgele bir dizin seçmektir. i dizinindeki kartla cardToSwap dizinindeki kartı değiştirmektir. object temp = cards[i]. Daha sonra i dizinindeki kartla bu rastgele dizindeki kartı değiştireceksiniz. Parametre olarak Random. i < cards. i++) { } } Dizileri ve Koleksiyonları Kullanmak 203 Bir sonraki adım 0 ile cards. i dizinindeki kartla cardToSwap dizinindeki kartı değiştirmek için üç ifade ekleyin. Bunun için. for ifadesinin içinde. 7. 8.Count.1). for (int i = 0. Ayrıca. } } . geçici yerel bir değişken kullanmanız gerekir. i++) { int cardToSwap = random. } } Son adım.Next oluşum yöntemini çağırarak rastgele bir tamsayı üretebilirsiniz. çünkü ArrayList’deki öğelerin her birini değiştirmeniz gerekir ve foreach döngüsü sadece salt okunur erişim sağlar. cards[cardToSwap] = temp. for (int i = 0. foreach ifadesi çalışmayacaktır. değişkene başlangıç değeri olarak 0 ile cards.Count . cards[i] = cards[cardToSwap]. for (int i = 0. i < cards.Count – 1 arasında rastgele bir sayı atayın: public void Shuffle() { Random random = new Random().

Oyuncuların ellerindeki kartları tek tek elden geçiren ve kartları desteye döndüren bir döngü yaratmanız gerekir. Formu kapatın. Bu defa deste.204 Kısım II C# Dilini Anlamak 9. 10. ya destede ya da oyuncunun elinde olmasıdır. Hand. Son adım. Pack sınıfının Accept adında.Accept(card). (Ekranınız her seferinde biraz farklı görünebilir.Clear(). oyuncunun elindeki kartları gösteren. cards adında bir ArrayList vardır. çünkü kart sırası rasgeledir. Buradaki temel düşünce. 3. Hand sınıfında da.cs dosyasını görüntüleyin. ReturnCardsTo yöntemini tamamlayın: public void ReturnCardsTo(Pack pack) { foreach (PlayingCard card in cards) { pack. Hand sınıfındaki ReturnCardsTo yöntemini bulun. Form üzerinde Deal’ı tıklayın. } . Debug menüsünde. Code and Text Editor penceresinde. Aşağıda koyu harflerle gösterildiği gibi. kartları desteye geri döndürecek kodu yazmaktır.) 11. 2. Start Without Debugging’i tıklayın. PlayingCard türünde tek bir parametre alan bir yöntemi vardır. dağıtılmadan önce karıştırılır. } cards. Kartları desteye geri taşıyın 1. her kartın herhangi bir anda.

Ayrıca.Clear yöntemini çağırmak önemlidir. Not Return to Pack’i tıklamadan. 5. kullanıcı arayüzünü değiştiren bir kod yazacağız. 6. Karıştırılmış kartlar yeniden dört oyuncuya dağıtılır. Oyuncuların elleri temizlenir. ArrayList sınıfının Clear yöntemi. “Windows Uygulamaları ile Çalışmak” başlıklı Kısım IV’de. Return to Pack’i tıklayın. Return to Pack düğmesi tıklanana kadar Deal düğmesini etkisiz hale getirmelisiniz. iki defa Deal düğmesini tıklarsanız. tüm kartları kaybedersiniz. farklı yöntemlerde bellekte veriyi saklamak ve bellekteki veriye erişmek için bazı yaygın koleksiyon sınıflarının nasıl kullanıldığını gördünüz. Clear (Temizle) yöntemi. ArrayList içeriğini boşaltır. böylece kartlar hem destede hem de oyuncunun elinde olmazlar. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakın ve Bölüm 11’e geçin. Gerçek dünyada. Start Without Debugging’i tıklayın. veri kümesini işlemek için dizileri nasıl yaratacağınızı ve kullanacağınızı öğrendiniz. Formu kapatın. n . Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Bu bölümde. Save iletişim kutusu görünürse. bir koleksiyondan tüm öğeleri kaldırır. Debug menüsünde. Karıştırılmış kartlar daha önce olduğu gibi dört oyuncuya dağıtılır. 8. Kartları desteye taşıdıktan sonra cards. Kartlar şimdi yeniden destelenir. Form üzerinde Deal’ ı tıklayın. çünkü öğelere yazma hakkı ve öğelerin dizinini bilmeniz gerekmiyor.Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 205 Burada foreach ifadesini kullanmak uygundur. C# kullanarak. Tekrar Deal’ı tıklayın. 4. 7. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.

int noOfElements = flags. Dizi için. Bir dizideki öğe sayısını bulmak Length özelliğini kullanın. i++) { Console. . } . Örneğin: ArrayList numbers = new ArrayList(){10.206 Kısım II C# Dilini Anlamak Bölüm 10 Hızlı Başvuru Bunun İçin Bir dizi değişkeni bildirmek Şunu Yapın Öğe türünün adını yazın.. Örneğin: bool[] flags... 6. i < flags. 7. Count özelliğini kullanın. özel değerleri virgülle ayrılmış biçimde parantez içinde yazın. ardından öğe türünün adını ekleyip dizinin boyutunu köşeli parantez içinde yazın.. Bir for ifadesi ya da bir foreach ifadesi kullanın.Length.Count. ardından köşeli parantez ve değişkenin adını yazıp noktalı virgül ekleyin. for (int i = 0. Unutmayın. true. new işlecini kullanın ve virgülle ayrılmış biçimde özel değerle koleksiyon türünü yazın. false. 9. true. Bir koleksiyon için.WriteLine(flags[i]). ardından köşeli parantez içinde dizin tamsayısını yazın. .WriteLine(flag). Örneğin: bool[] flags = { true. 1’den değil. false }. Örneğin: ArrayList flags = new ArrayList(). } foreach (bool flag in flags) { Console. Örneğin: bool[] flags = new bool[10]. Örneğin: bool initialElement = flags[0].. dizi dizinleri 0’dan başlar. 8. Örneğin: bool[] flags = { true. false }. Tek bir dizi öğesine erişmek Dizi değişkeninin adını yazın. Örneğin: int [] flags = . Bir dizinin oluşumunu yaratmak new anahtar sözcüğünü yazın.. int noOfElements = flags.. 5}. Bir dizinin (ya da Add yöntemini destekleyen bir koleksiyonun) öğelerine başlangıç değeri olarak özel değerler atamak. Bir dizi/koleksiyon öğeleri boyunca yineleme yapmak. Bir koleksiyondaki öğe sayısını bulmak.Length. false.

public static void WriteLine(decimal parameter) . aşırı yükleme.. bu cümle sizde hayal kırıklığı yaratmış olabilir. mümkün olduğunda farklı türlerde bağımsız değişkenler alabilen yöntemler yazmak isterseniz. Örneğin. Bir yönteme aşırı yükleme yapmak. ya birçok değeri konsola yazmak isterseniz? Her değer için. bu problemi çözmek için nesne-yönelimli yaklaşım. Microsoft Visual C#’daki klasik aşırı yükleme örneği.. params anahtar sözcüğünü object türü ile birlikte kullanarak herhangi bir türdeki herhangi bir sayıda bağımsız değişken alabilen bir yöntem yazmak n Parametre olarak herhangi bir sayıda. Nesneyönelimli kavramlarına aşina iseniz.Bölüm 11 Parametre Dizilerini Anlamak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n params anahtar sözcüğünü kullanarak herhangi bir sayıda bağımsız değişken alabilen bir yöntem yazmak.WriteLine’dır. } Aşırı yükleme işlemi ne kadar yararlı olursa olsun. değişenin parametrelerin türleri değil sayıları olduğu durumları çok kolay işleyemez. public static void WriteLine(double parameter) . WriteLine yöntemine çok sayıda aşırı yükleme yapılmıştır böylece bu yönteme herhangi bir temel türü geçirebilirsiniz: class Console { public static void WriteLine(int parameter) . bir öncekinden bir fazla parametre alan Console. Ve bu kadar çok yinelenen tüm bu aşırı yüklenmiş yöntemler sizi endişelendirmiyor mu? Endişelendirmeli. params dizilerinin bu sorunu nasıl çözdüklerini görmeden önce basit dizilerin yararlarını ve eksik yönlerini görmek daha yararlı olacaktır. Neyse ki. aşırı yüklenmiş yöntemleri tanımlamaktır. farklı türlerde bağımsız değişkenler üzerinde aynı eylemi gerçekleştirmek istediğiniz bazı durumlarda çok yararlıdır. parametre dizileri kullanışlıdır.. bütün durumları kapsamaz. aynı kapsamda aynı adla iki ya da daha çok sayıda yöntem bildirmenin teknik terimidir. kısa sürede can sıkıcı bir hal alır.WriteLine sürümünü çağırmanız mı gerekir? Bu. Console... 207 . Neticede.. değişen sayılarda bağımsız değişken alan bir yöntem yazmanın bir yolu var (variadic yöntem): Bir parametre dizisi kullanabilirsiniz (params anahtar sözcüğü ile bildirilmiş bir parametre). Aşırı Yükleme (Overloading). Özellikle.

208

Kısım II

C# Dilini Anlamak

Dizi Bağımsız Değişkenlerini Kullanmak
Parametre olarak geçirilmiş bir değer kümesindeki minimum değeri hesaplamak için bir yöntem yazmak istediğinizi varsayın. Bunun bir yolu bir dizi kullanmak olacaktır. Örneğin, belirli bir sayıda int değerin en küçüğünü bulmak için, Min adlı int değerlerden oluşan bir dizi biçiminde tek bir parametresi olan bir statik yöntem yazabilirsiniz:
class Util { public static int Min(int[] paramList) { if (paramList == null || paramList.Length == 0) { throw new ArgumentException(“Util.Min: not enough arguments”); } int currentMin = paramList [0]; foreach (int i in paramList) { if (i < currentMin) { currentMin = i; } } return currentMin; } }

Not ArgumentException sınıfı, bağımsız değişkenler yöntemin gereksinimlerini karşılamazsa, yöntem tarafından atanması için özel olarak tasarlanmıştır. İki int değerden en küçüğünü bulmak için Min yöntemini kullanmak üzere aşağıdakileri yazarsınız:
int[] array = new int[2]; array[0] = first; array[1] = second; int min = Util.Min(array);

Ve üç int değerden en küçüğünü bulmak için Min yöntemini kullanmak üzere ise aşağıdakileri yazarsınız:
int[] array = new int[3]; array[0] = first; array[1] = second; array[2] = third; int min = Util.Min(array);

Bu çözümün çok sayıda aşırı yükleme kullanımını engellediğini görebilirsiniz, ama bunu çok pahalıya yapar: yönteme geçen diziyi yerleştirmek için ek kod yazmanız gerekir. Bununla birlikte, bir params dizisi bildirmek için params anahtar sözcüğünü kullanarak kodun bir kısmını derleyicinin sizin için yazmasını sağlayabilirsiniz.

Bölüm 11

Parametre Dizilerini Anlamak

209

Bir params Dizisi Bildirmek
Bir dizi parametresi düzenleyicisi olarak, params anahtar sözcüğünü kullanırsınız. Örneğin, aşağıda, dizi parametresi bir params dizisi olarak bildirilmiş biçimde yine Min yöntemini görebilirsiniz:
class Util { public static int Min(params int[] paramList) { // kod tam olarak önceki gibi } }

Min yöntemindeki params anahtar sözcüğünün etkisi şudur; onu istediğiniz sayıda tamsayı bağımsız değişken kullanarak çağırabilirsiniz. Örneğin, iki tamsayı değerin en küçüğünü bulmak için şunu yazabilirsiniz:
int min = Util.Min(first, second);

Derleyici bu kodu aşağıdaki koda çevirir:
int[] array = new int[2]; array[0] = first; array[1] = second; int min = Util.Min(array);

Üç tamsayı değerin en küçüğünü bulmak içinse, aşağıdaki kodu yazarsınız. Bu kod da derleyici tarafından bir diziyi kullanan uygun koda çevrilir:
int min = Util.Min(first, second, third);

Min yöntemine yapılan her iki çağrı da (biri iki bağımsız değişken, diğeri de üç bağımsız değişken ile), params anahtar sözcüğü ile aynı Min yöntemine ayrıştırılır. Ve tahmin edebileceğiniz gibi, bu Min yöntemini herhangi bir sayıda int bağımsız değişkeniyle çağırabilirsiniz. Derleyici, int bağımsız değişkenlerini sayar ve o boyutta bir int dizisi yaratır, diziyi bağımsız değişkenlerle doldurur ve daha sonra da tek dizi parametresini geçirerek yöntemi çağırır. Not C ve C++ ile program geliştirenler, params’ı üst bilgi dosyası olan stdarg.h’deki varargs
makrosunun yazım hatasından arındırılmış denkliği gibi algılayabilirler.

Params dizileri hakkında belirtilmesi gereken birkaç nokta vardır:
n

params anahtar sözcüğünü çok boyutlu dizilerde kullanamazsınız. Aşağıdaki kod derlenmez:
// derleme zamanı hatası public static int Min(params int[,] table) ...

210

Kısım II
n

C# Dilini Anlamak

Yalnızca params anahtar sözcüğünü temel alarak aşırı yükleme yapamazsınız. params anahtar sözcüğü, yöntemin imzasının bir parçasını oluşturmaz. Örneğin:
// derleme zamanı hatası: çift bildirim public static int Min(int[] paramList) ... public static int Min(params int[] paramList) ...

n

Aşağıdaki örnekte gösterildiği gibi, params dizileri ile ref ya da out düzenleyicisini belirleyemezsiniz:
// derleme zamanı hatası public static int Min(ref params int[] paramList) ... public static int Min(out params int[] paramList) ...

n

Bir params dizisi son parametre olmalıdır. (Bu, her yöntemde yalnızca bir params dizisi bulunabileceği anlamına gelir). Aşağıdaki örneği düşünün:
// derleme zamanı hatası public static int Min(params int[] paramList, int i) ...

n

params içermeyen bir yöntem her zaman bir params yöntemine göre önceliklidir. Bunun anlamı, isterseniz, yaygın durumlar için yöntemin aşırı yüklenmiş sürümünü de yaratabilirsiniz. Örneğin:
public static int Min(int leftHandSide, int rightHandSide) ... public static int Min(params int[] paramList) ...

Min yönteminin ilk sürümü, iki int bağımsız değişkeni kullanarak çağırdığınız zamanki yöntemdir. Başka sayıda int bağımsız değişkenleri uygulanırsa ikinci sürüm kullanılmıştır. Bu, yöntemin hiçbir bağımsız değişken almadan çağrıldığı zamanı da kapsar. params içermeyen dizi yöntemini eklemek yararlı bir iyileştirme tekniği olabilir çünkü derleyicinin onca diziyi oluşturup doldurması gerekmez.
n

Derleyici her türlü potansiyel şüpheli aşırı yüklemeyi fark edip reddeder. Örneğin, aşağıdaki iki Min yöntemi şüphelidir: iki int bağımsız değişkeni geçirdiğinizde hangisinin çağrıldığı çok açık olmaz:
// derleme zamanı hatası public static int Min(params int[] paramList) ... public static int Min(int, params int[] paramList) ...

Bölüm 11

Parametre Dizilerini Anlamak

211

params object[ ] Kullanmak
int türü bir parametre dizisi oldukça yararlıdır çünkü bir yöntem çağrısında herhangi bir sayıda int bağımsız değişkeni kullanımına izin verir. Bununla birlikte, yalnızca bağımsız değişkenlerin sayısı değil türleri de değişirse ne olacak? C#’da bu sorunu çözmenin bir yolu vardır. Teknik, nesnenin tüm sınıfların kökü olması ve derleyicinin, Bölüm 8’de anlatıldığı gibi kutulamayı kullanarak, değer türlerini (sınıf olmayan şeyler) nesnelere dönüştüren kodu üretebilmesine dayanır. Herhangi bir türde bağımsız değişken geçmesine olanak sağlayan, herhangi bir sayıda object bağımsız değişkeni kabul eden bir yöntem bildirmek için object türü bir parametreler dizisi kullanabilirsiniz. Şu örneğe bakın:
class Black { public static void Hole(params object [] paramList) ... }

Bu kodu, yalnızca her bağımsız değişkeni yuttuğu için değil aynı zamanda hiçbir bağımsız değişken ondan kaçmadığı için Black.Hole (Kara.Delik) olarak adlandırdık:
n

Bu yönteme hiçbir bağımsız değişken geçirmeyebilirsiniz; bu durumda derleyici, uzunluğu 0 olan bir nesne dizisi geçirir:
Black.Hole(); // Black.Hole(new object[0])’e dönüştürüldü;

İpucu Uzunluğu 0 olan bir dizide foreach döngüsü ile ilerlemek güvenlidir.
n

Bu yöntemi, bağımsız değişken olarak null geçirerek çağırabilirsiniz. Bir dizi başvuru türündedir; bu yüzden bir diziyi null olarak başlatabilirsiniz:
Black.Hole(null);

n

Bu yönteme, gerçek bir dizi geçirebilirsiniz. Diğer bir deyişle, normalde derleyicinin oluşturacağı diziyi kendiniz oluşturabilirsiniz:
object[] array = new object[2]; array[0] = "forty two"; array[1] = 42; Black.Hole(array);

n

Bu yönteme herhangi başka bir bağımsız değişkeni geçirebilirsiniz ve geçirdiğiniz bu bağımsız değişkenler otomatik olarak bir object dizisinin içine atılır:
Black.Hole("forty two", 42); //Black.Hole(new object[]{"forty two", 42})’e dönüştürüldü;

212

Kısım II

C# Dilini Anlamak

Console.WriteLine Yöntemi
Console sınıfında WriteLine yöntemi için çok sayıda aşırı yükleme vardır. Bu aşırı yüklemelerden biri aşağıdaki gibi görünür:
public static void WriteLine(string format, params object[] arg);

Bu aşırı yükleme, WriteLine yönteminin, her biri çalışma zamanında herhangi bir tür değer ile değiştirilebilen yer tutucular içeren, bir biçim dize bağımsız değişkenini desteklemesini sağlar. Önceki bölümlerde birkaç defa gördüğünüz, bu yönteme yapılabilecek çağrılara bir örnek aşağıdadır:
Console.WriteLine(“Name:{0}, Age:{1}”, name, age);

Derleyici bu kodu aşağıdaki koda çevirir:
Console.WriteLine(“Name:{0}, Age:{1}”, new object[2]{name, age});

Bir params Dizisi Kullanmak
Aşağıdaki alıştırmada, Util.Sum adında bir static yöntem yazacak ve test edeceksiniz. Bu yöntemin amacı, kendisine geçirilen int türü değişkenlerin toplam sayısını hesaplamak, sonucu int olarak döndürmektir. Bunu, Util.Sum yöntemini params int[ ] parametresi alacak şekilde yazarak yapacaksınız. Util.Sum yönteminin sağlamlığından emin olmak için params parametresi üzerinde iki denetim gerçekleştireceksiniz. Daha sonra, test etmek için değişik sayıda bağımsız değişken kullanarak Util.Sum yöntemini çağırın.

Bir params dizisi yöntemi yazın
1. Microsoft Visual Studio 2008’i başlatın. 2. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 11\ ParamArrays klasöründe yer alan ParamsArray projesini açın. 3. Code and Text Editor penceresinde Util.cs dosyasını açın. Util.cs dosyası, ParamsArray ad alanında Util adında boş bir sınıf içerir. 4. Util sınıfına, Sum (Toplam) adlı bir public statik yöntem ekleyin. Sum yöntemi, bir int döndürür ve int değerlerden oluşan bir params dizisi alır. Sum yöntemi şu şekilde görünmelidir:
public static int Sum(params int[] paramList) { }

Sum yöntemini geliştirmenin ilk adımı paramList parametresini denetlemektir. Geçerli bir tamsayı kümesi içermesinin dışında, null da olabilir, sıfır uzunluğunda da olabilir. Her iki durumda da, toplamı hesaplamak zordur, bu nedenle en iyi seçenek ArgumentException özel durumunu oluşturmaktır. (Sıfır uzunluğundaki bir dizideki tamsayıların toplamı sıfır olacaktır fakat bu örnekte bu durumu özel bir durum olarak ele alacağız.)

Bölüm 11

Parametre Dizilerini Anlamak

213

5. Sum yöntemine paramList, null ise bir ArgumentException özel durumu oluşturan kodu ekleyin. Sum yöntemi şimdi şu şekilde görünmelidir:
public static int Sum(params int[] paramList) { if (paramList == null) { throw new ArgumentException(“Util.Sum: null parameter list”); } }

6. Aşağıda koyu harflerle gösterildiği gibi, Sum yöntemine array uzunluğu 0 ise bir ArgumentException özel durumu oluşturan kodu ekleyin:
public static int Sum(params int[] paramList) { if (paramList == null) { throw new ArgumentException(“Util.Sum: null parameter list”); } if (paramList.Length == 0) { throw new ArgumentException(“Util.Sum: empty parameter list”); } }

Dizi bu iki testi geçerse, bir sonraki aşama dizinin içindeki öğelerin tümünü birlikte toplamaktır. 7. Tüm öğeleri toplamak için bir foreach ifadesi kullanabilirsiniz. Her aşamadaki toplam değeri tutmak için bir yerel değişken gerekli olacaktır. sumTotal adında bir tamsayı bildirin ve değişkene başlangıç değeri olarak 0 atayın. paramList dizisi üzerinden yineleme yapmak için Sum yöntemine bir foreach ifadesi ekleyin. Bu foreach döngüsünün gövdesi dizideki her öğeyi sumTotal’a ekler. Yöntemin sonunda, bir return ifadesi ile sumTotal değerini döndürür.
class Util { public static int Sum(params int[] paramList) { ... int sumTotal = 0; foreach (int i in paramList) { sumTotal += i; } return sumTotal; } }

8. Build menüsünde, Build Solution’ı tıklayın. Çözümünüzün hatasız olarak oluşturulduğunu doğrulayın.

214

Kısım II

C# Dilini Anlamak

Util.Sum yöntemini test edin .
1. Code and Text Editor penceresinde Program.cs dosyasını görüntüleyin. 2. Code and Text Editor penceresinde, Program sınıfındaki Entrance yöntemini bulun. 3. Entrance yöntemine aşağıdaki ifadeyi ekleyin:
Console.WriteLine(Util.Sum(null));

4. Debug menüsünde, Start Without Debugging’i tıklayın. Program oluşur ve çalışır, konsola aşağıdaki iletiyi yazar:
Exception: Util.Min: null parameter list

Bu ileti, yöntemdeki ilk denetimin çalıştığını gösterir. 5. Programı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. 6. Code and Text Editor penceresinde, Entrance yöntemindeki Console.WriteLine çağrısını aşağıdaki gibi değiştirin:
Console.WriteLine(Util.Sum());

Bu defa, yöntem herhangi bir bağımsız değişken olmadan çağrılır. Derleyici, boş bağımsız değişken listesini boş bir diziye çevirir. 7. Debug menüsünde, Start Without Debugging’i tıklayın. Program oluşturulur ve çalışır, konsola aşağıdaki iletiyi yazar:
Exception: Util.Min: empty parameter list

Bu, yöntemdeki ikinci denetimin çalıştığını doğrular. 8. Programı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. 9. Entrance yöntemindeki Console.WriteLine çağrısını aşağıdaki gibi değiştirin:
Console.WriteLine(Util.Sum(10, 9, 8, 7, 6, 5, 4, 3, 2, 1));

10. Debug menüsünde, Start Without Debugging’ i tıklayın. Program oluşturulur, çalışır ve konsola 55 yazar. 11. Uygulamayı kapatmak için Enter’a basın. Bu bölümde, herhangi bir sayıda bağımsız değişken alan bir yöntemi tanımlamak için bir params dizisini nasıl kullanacağınızı öğrendiniz. Ayrıca, herhangi bir türde, herhangi bir sayıda bağımsız değişken alan bir yöntem yaratmak için object türlerinde bir params dizisinin kullanımını öğrendiniz.

Bölüm 11
n

Parametre Dizilerini Anlamak

215

Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakın ve Bölüm 12’ye geçin. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Save iletişim kutusu görünürse, Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.

n

Bölüm 11 Hızlı Başvuru
Bunun İçin
Belirli bir türde herhangi bir sayıda bağımsız değişken alan bir yöntem yazmak

Şunu Yapın
Parametresi belirli bir türde bir params dizisi olan bir yöntem yazın. Örneğin, herhangi bir sayıda bool bağımsız değişkeni alan bir yöntem şöyle olacaktır:
someType Method(params bool[] flags) { ... }

Herhangi bir türde, herhangi bir sayıda bağımsız değişken alan bir yöntem yazmak

Parametresi object türü öğeler içeren bir params dizisi olan bir yöntem yazın. Örneğin:
someType Method(params object[] paramList) { ... }

Bölüm 12

Kalıtım ile Çalışmak
Bu bölümü tamamladıktan sonra öğrenecekleriniz:
n n

Temel sınıftan özellikleri miras alan bir türetilmiş sınıf yaratmak. new, virtual ve override anahtar sözcüklerini kullanarak yöntemi gizlemeyi ve geçersiz kılmayı denetlemek. protected anahtar sözcüğünü kullanarak bir kalıtım hiyerarşisi dahilinde erişilebilirliği sınırlamak. Kalıtım kullanmaya alternatif olarak uzantı yöntemler tanımlamak.

n

n

Kalıtım, nesne yönelim dünyasında kilit bir kavramdır. Ortak olan ve birbiri ile yakından ilişkili olan çok sayıda özelliğe sahip farklı sınıflar tanımladığınızda tekrarlamadan kaçınmak için bir araç olarak kalıtımı kullanabilirsiniz. Bu farklı sınıflar, her biri kendi ayırt edici özelliğine sahip, aynı türün farklı sınıfları olabilir: Örneğin, bir fabrikanın yöneticileri, fiziksel güçle çalışanları ve tüm işçileri. Bir fabrikayı göstermek için bir uygulama yazacaksanız, yöneticiler ve fiziksel güçle çalışanların sahip oldukları ortak özellikleri ve farklı özellikleri nasıl belirleyeceksiniz? Örneğin, tüm çalışanlar bir çalışan numarasına sahiptir, fakat yöneticiler farklı sorumluluklara sahiptir ve fiziksel güçle çalışanlardan farklı görevleri vardır. Bu noktada kalıtım çok yararlıdır.

Kalıtım Nedir?
Birkaç uzman programcıya, kalıtım (inheritance) teriminden ne anladığını sorarsanız, çok farklı ve çelişkili cevaplar alırsınız. Bu karışık cevapların kökü, kalıtım kelimesinin kendisinin farklı anlamlar taşımasından kaynaklanır. Birisi bir şeyleri size kendi isteği ile bırakırsa, onu kalıtımla (miras) aldığınız söylenir. Benzer şekilde, genlerinizin yarısını annenizden, yarısını da babanızdan kalıtımla aldığınız söylenir. Kalıtım sözcüğünün bu her iki kullanımının, programcılıktaki kalıtımla çok az ilgisi vardır. Programcılıktaki kalıtım, tamamen sınıflandırma ile ilgilidir (sınıflar arasındaki bir ilişkidir). Örneğin, okuldayken, büyük olasılıkla memeliler hakkında birçok şeyle birlikte, atın ve balinaların memeli hayvanlar olduğunu öğrendiniz. Her biri, bir memelinin sahip olduğu ortak özelliklere sahiptir (nefes alır, yavrusunu besler, sıcakkanlıdır ve bunun gibi), fakat her biri kendi özelliklerine sahiptir (atın toynakları vardır, balinaların yoktur). Bir programda bir at ve bir balinayı nasıl modelleyebilirsiniz? Bunun bir yolu, At ve Balina adında iki farklı sınıf yaratmaktır. Her sınıf, Yürümek ya da Yüzmek gibi, memelinin o türüne
217

218

Kısım II

C# Dilini Anlamak

özgü olan yöntemleri gerçekleştirebilir. Nefes Almak ya da Yavrusunu Beslemek gibi at ve balinada ortak olan yöntemleri nasıl gerçekleştireceksiniz? Her iki sınıfa da aynı yöntemleri ekleyebilirsiniz fakat bu şekilde programın bakımı zor olacaktır, özellikle de İnsan ya da Karıncayiyen gibi diğer türleri de modellemeye başladığınızda. C#’da bunun için sınıf kalıtımını kullanabilirsiniz. At, balina, insan ve karıncayiyen memeli türündedir, bu nedenle bu türler tarafından sergilenen ortak işlevselliği sağlayan Memeli adında bir sınıf yaratın. Daha sonra, At, Balina, İnsan ve Karıncayiyen sınıflarının tümünü Memeli sınıfından kalıtımla alabilirsiniz. Bu sınıflar otomatik olarak Memeli sınıfının yöntemlerini sağlar (Nefes Almak, Yavrusunu Beslemek ve bunun gibi), ayrıca bir memeli türünün kendisine özgü yöntemlerini de uygun sınıfa ekleyebilirsiniz; At sınıfı için Yürümek yöntemi ve Balina sınıfı için Yüzmek yöntemi gibi. Nefes Almak gibi ortak bir yöntemin çalışma şeklini değiştirmeniz gerekirse, bu değişikliği sadece tek bir yerde, Memeli sınıfında yapmanız gerekir.

Kalıtımı Kullanmak
Bu bölüm, C#’da bir sınıftan miras alınan başka bir sınıf yaratmak için, bilmeniz gereken kalıtımla ilişkili temel sözdizimini ele alır.

Temel Sınıflar ve Türetilmiş Sınıflar
Bir sınıfın başka bir sınıftan kalıtımla aldığını bildiren sözdizimi şu şekildedir:
class DerivedClass : BaseClass { ... }

Türetilmiş sınıf temel sınıftan miras alır ve temel sınıftaki yöntemler aynı zamanda türetilmiş sınıfın da yöntemleri olur. C#’da, bir sınıf en fazla başka bir sınıftan türetilebilir; bir sınıf birden fazla sınıftan türetilemez. Bununla birlikte, DerivedClass (TüretilmişSınıf), mühürlü (sealed) olarak bildirilmediği sürece, aynı sözdizimini kullanarak DerivedClass’dan miras alan başka türetilmiş sınıflar yaratabilirsiniz. (“Arayüzler Yaratmak ve Soyut Sınıflar Tanımlamak” başlıklı Bölüm 13’te mühürlenmiş sınıflar hakkında daha fazla bilgi bulacaksınız.)
class DerivedSubClass : DerivedClass { ... }

alınamaz.

Önemli Yapılarda kalıtım kullanamazsınız. Bir yapı, bir sınıftan ya da başka bir yapıdan miras

Bölüm 12

Kalıtım ile Çalışmak

219

Daha önce açıklanan örnekte, Mammal sınıfını aşağıda gösterildiği gibi bildirebilirsiniz. Breathe ve SuckleYoung yöntemleri tüm memelilerde ortaktır.
class Mammal { public void Breathe() { ... } public void SuckleYoung() { ... } ... }

Daha sonra, farklı memeli türlerinin her biri için sınıflar tanımlayabilir, gerekirse ek yöntemler ekleyebilirsiniz. Örneğin:
class Horse : Mammal { ... public void Trot() { ... } } class Horse : Whale { ... public void Swim() { ... } }

Not C++ ile program geliştiriciler kalıtımın genel, özel ya da korumalı olup olmadığının açık bir şekilde belirtilmediğine ve belirtilemeyeceğine dikkat etmelidir. C#’da kalıtım, her zaman dolaylı olarak geneldir. Java programcıları, extends anahtar sözcüğünün olmadığına ve iki nokta üst üste kullanıldığına dikkat etmelidir. System.Object sınıfı, tüm sınıflar için kök sınıftır. Tüm sınıflar dolaylı olarak System.Object sınıfından türerler. Bundan dolayı, C# derleyicisi Mammal sınıfını aşağıdaki gibi yeniden yazar (gerçekten isterseniz açık bir şekilde yazabilirsiniz):
class Mammal : System.Object { ... }

220

Kısım II

C# Dilini Anlamak

System.Object sınıfındaki her yöntem otomatik olarak, Horse ve Whale gibi Mammal sınıfından türetilmiş sınıflara geçer. Pratikte bunun anlamı, tanımladığınız tüm sınıfların otomatik olarak System.Object sınıfının tüm özelliklerini miras almasıdır. Bu, bir nesneyi dize gösterimine çeviren ToString yöntemi (ilk olarak Bölüm 2’de incelenmişti) gibi yöntemleri de kapsar.

Temel Sınıf Kurucularını Çağırmak
Bir türetilmiş sınıf, otomatik olarak temel sınıfın tüm alanlarını içerir. Bu alanlar genellikle, nesne yaratıldığında başlatılmasını gerektirir. Bu tür bir başlatmayı genellikle bir yapıda gerçekleştirirsiniz. Tüm sınıfların en az bir kurucuya sahip olduğunu hatırlayın. (Siz bir kurucu sağlamamışsanız, derleyici sizin için bir tane üretir.) Türetilmiş bir sınıftaki kurucunun, başlatma kısmı olarak kendi temel sınıfının kurucusunu çağırması iyi bir uygulamadır. Miras alan bir sınıf için bir kurucu tanımladığınızda, temel sınıf kurucusunu çağırmak için, base anahtar sözcüğünü kullanabilirsiniz. Örneğin:
class Mammal // temel sınıf { public Mammal(string name) { ... } ... }

// temel sınıf için kurucu

class Horse : Mammal // türetilmiş sınıf { public Horse(string name) : base(name) // Mammal(name) yöntemini çağırır { ... } ... }

Türetilmiş sınıf kurucusu içinde, temel sınıf kurucusunu açıkça çağırmıyorsanız, derleyici türetilmiş sınıf kurucusundaki kodu uygulamadan önce temel sınıfın varsayılan kurucusuna bir çağrı yerleştirmeye çalışır. Önceki örneği ele alırsak, derleyici aşağıdaki şu kodu:
class Horse : Mammal { public Horse(string name) { ... } ... }

Bölüm 12

Kalıtım ile Çalışmak

221

Bu biçimde yeniden yazar:
class Horse : Mammal { public Horse(string name) : base() { ... } ... }

Mammal sınıfı public bir varsayılan kurucuya sahipse, bu işlem çalışır. Bununla birlikte, tüm sınıflar public bir varsayılan kurucuya sahip değildir (Mammal sahip değildir!). Temel sınıf kurucusunu çağırmanın unutulduğu durumlar derleme zamanı hatası ile sonuçlanır.

Sınıflar Atamak
Bu kitaptaki önceki örneklerde, bir sınıf türünü kullanarak bir değişkeni nasıl bildireceğinizi ve daha sonra bir nesne yaratmak için new anahtar sözcüğünün kullanımını gördünüz. Ayrıca, C#’daki tür denetim kurallarının bir türdeki nesneyi, farklı bir türde bildirilmiş bir değişkene atamanızı engellediğini gördünüz. Örneğin, Mammal, Horse ve Whale sınıflarının burada gösterilen tanımlarına göre aşağıdaki kod geçerlidir:
class Mammal { ... } class Horse : Mammal { ... } class Whale : Mammal { ... } ... Horse myHorse = new Horse(“Neddy”); Whale myWhale = myHorse;

// önceki gösterilen kurucu bir ad bekler! // hata – farklı türler

Bununla birlikte, tür olarak kalıtım hiyerarşisinde üst sırada yer alan sınıf kullanıldığı sürece, farklı türdeki bir değişkenindeki nesneye başvurmak mümkündür. Buna göre, aşağıdaki ifadeler geçerli ifadelerdir:
Horse myHorse = new Horse(“Neddy”); Mammal myMammal = myHorse; // doğru, Mammal Horse’un temel sınıfıdır

Mantıksal terimler olarak düşünürseniz, tüm Horse sınıfı, Mammal sınıfındadır, bu nedenle Horse türü bir nesneyi Mammal türü bir değişkene güvenle atayabilirsiniz. Kalıtım hiyerarşisi,

222

Kısım II

C# Dilini Anlamak

Horse sınıfını birkaç ekstra bit ile (Horse sınıfına eklediğiniz yöntemler ve alanlar tarafından tanımlanan), özel bir Mammal türü (Mammal türünün sahip olduğu herşeye sahiptir) olarak düşünebileceğiniz anlamına gelir. Ayrıca, bir Mammal değişkeninin bir Whale nesnesine başvurmasını sağlayabilirsiniz. Bununla birlikte, önemli bir kısıtlama vardır; bir Mammal değişkeni kullanarak bir Horse ya da Whale nesnesine başvurduğunuzda, sadece Mammal sınıfı tarafından tanımlanmış yöntemler ve alanlara erişebilirsiniz. Horse ya da Whale sınıfı tarafından tanımlanmış ekstra yöntemlere, Mammal sınıfı üzerinden erişilemez.
Horse myHorse = new Horse(“Neddy”); Mammal myMammal = myHorse; myMammal.Breathe(); // Tamam - Breathe Mammal sınıfının parçasıdır myMammal.Trot(); // hata - Trot Mammal sınıfının parçası değildir

Not Bu, bir object değişkenine neredeyse her şeyi atayabileceğinizi açıklar. object’in System. Object için takma ad olduğunu ve tüm sınıfların System.Object’dan doğrudan ya da dolaylı olarak miras alındığını hatırlayın. Bunun tersinin doğru olmadığı konusunda uyarmalıyız. Bir Horse değişkenine koşulsuzca bir Mammal nesnesi atayamazsınız:
Mammal myMammal = myMammal(“Mammalia”); Horse myHorse = myMammal; // hata

Bu garip bir kısıtlama gibi görünüyor fakat tüm Mammal nesnelerinin Horse olmadığını, bazılarının Whale olduğunu unutmayın. Bir Horse değişkenine bir Mammal nesnesi atayabilirsiniz fakat ilk olarak as ya da is işleci kullanarak ya da bir atama (cast) kullanarak Mammal nesnesinin gerçekten bir Horse olup olmadığını kontrol etmeniz gerekir. Aşağıdaki kodda, myMammal değişkeninin bir Horse’a başvurup başvurmadığını denetlemek için as işleci kullanılmıştır ve eğer başvuruyorsa, myHorseAgain ataması, aynı Horse nesnesine başvuran myHorseAgain olarak sonuçlanır. myMammal değişkeni başka bir Mammal türüne başvuruyorsa, as işleci null sonucu verir.
Horse myHorse = new Horse(“Neddy”); Mammal myMammal = myHorse; ... Horse myHorseAgain = myMammal as Horse; ... Whale myWhale = new Whale(“Moby Dick”); myMammal = myWhale; ... myHorseAgain = myMammal as Horse; // myMammal Horse’a başvurur // Tamam - myMammal Horse’tu

// null döndürür - myMammal Whale idi

new Yöntemleri Bildirmek
Bilgisayar programlama dünyasında en zor problemlerden biri, tanımlayıcılar için benzersiz ve anlamlı adlar bulmaktır. Bir sınıf için bir yöntem tanımlarsanız ve o sınıf bir kalıtım

Bölüm 12

Kalıtım ile Çalışmak

223

hiyerarşisinin parçası ise, er ya da geç hiyerarşinin tepesindeki sınıflardan biri tarafından kullanılmakta olan bir adı yeniden kullanmaya kalkışabilirsiniz. Temel bir sınıf ve türetilmiş bir sınıf aynı imzalı (yöntem imzası, yöntemin adı ve parametrelerin tipi ve sayısıdır) iki yöntemi bildirirse, uygulamayı derlerken hata alırsınız. Türetilmiş sınıftaki yöntem, temel sınıftaki aynı imzaya sahip yöntemi maskeler (ya da gizler). Örneğin, aşağıdaki kodu derlerseniz, derleyici Horse.Talk’ın miras alınmış Mammal.Talk’ı gizlediğini söyleyen bir uyarı iletisi oluşturacaktır:
class Mammal { ... public void Talk() // tüm memeliler konuşur { ... } } class Horse : Mammal { ... public void Talk() { ... } }

// atlar diğer memelilerden farklı yolla konuşur!

Kodunuz derlense ve çalışsa bile, bu uyarıyı ciddiye almalısınız. Başka bir sınıf, Horse sınıfından türerse ve Talk yöntemini çağırırsa, Mammal sınıfındaki Talk yönteminin çağrıldığı düşünülebilir. Ama, Horse sınıfındaki Talk yöntemi Mammal sınıfındaki Talk yöntemini gizler ve bu nedenle Horse.Talk yöntemi çağrılır. Çoğu zaman, böyle bir rastlantı bir kargaşaya neden olur ve karmaşıklığı önlemek için bu yöntemleri yeniden adlandırmayı düşünebilirsiniz. Bununla birlikte, iki yöntemin aynı imzaya sahip olmasını istediğinizden, bu nedenle de Mammal.Talk yöntemini gizlemek istediğinizden eminseniz, aşağıdaki gibi new anahtar sözcüğünü kullanarak uyarıyı engelleyebilirsiniz:
class Mammal { ... public void Talk() { ... } } class Horse : Mammal { ... new public void Talk() { ... } }

224

Kısım II

C# Dilini Anlamak

new anahtar sözcüğünü bu biçimde kullanmak, iki yöntemin halen tamamen ilişkisiz olduğu ve gizlemenin halen var olduğu olgusunu değiştirmez. Yalnızca uyarıyı engeller. Sonuçta, new anahtar sözcüğü, “Ben ne yaptığımı biliyorum, bu uyarıları artık gösterme.” demektir.

Virtual (Sanal) Yöntemler Bildirmek
Bazen, bir yöntemin temel sınıftaki uygulanma yolunu gizlemek istersiniz. Örneğin, System. Object’deki ToString yöntemini düşünün. ToString yönteminin amacı, bir nesneyi dize gösterimine çevirmektir. Bu yöntem kullanışlı olduğundan, bir System.Object üyesidir, dolayısıyla tüm sınıflar otomatik olarak ToString yöntemine sahiptir. Bununla birlikte, System. Object tarafından uygulanan ToString sürümü, bir türetilmiş sınıf oluşumunu bir dizeye nasıl çevireceğini nereden bilebilir? Türetilmiş bir sınıf, dize parçası olması gereken ilginç değerlerle çok sayıda alan içerebilir. System.Object’de ToString uygulanır yanıtı gerçekten basit bir yanıt olur. Yapabileceğinizin tümü, nesneyi “Mammal” ya da “Horse” gibi, tür adını içeren bir dizeye çevirmektir. Ancak, bu da çok kullanışlı değildir. Öyleyse, çok kullanışlı olmayan bir yöntemi neden sunuyoruz? Bu sorunun yanıtı biraz daha detaylı düşünmeyi gerektiriyor. ToString yönteminin kavramsal olarak iyi bir fikir olduğu açıktır ve tüm sınıflar nesneleri görüntülemek ya da hataları bulmak amacıyla, nesneleri dize gösterimine çevirmek için kullanılabilecek bir yöntem sağlamalıdır. Problemli olan sadece uygulamasıdır. Aslında, System.Object tarafından tanımlanan ToString yöntemini çağırmanız beklenmez (bu sadece bir yer tutucudur). Bunun yerine, tanımladığınız her sınıfta, ToString yönteminin System. Object’daki varsayılan uygulaması yerine kendi ToString sürümünüzü sağlamalısınız. System. Object’deki sürüm sadece, sınıf kendi ToString yöntemini sağlamadığı durumda, güvenlik ağı olarak mevcuttur. Böylece, herhangi bir nesne üzerinde ToString yöntemini çağırabileceğinize ve yöntemin bir dize döndüreceğine emin olabilirsiniz. ToString yöntemini geçersiz kılmak için tasarlanan yöntem, sanal yöntem olarak adlandırılır. Bir yöntemi gizlemek ve bir yöntemi geçersiz kılmak arasındaki farkı net olarak anlamalısınız. Bir yöntemi geçersiz kılmak, o yöntemin farklı bir uygulamasını sağlamak için kullanılan bir tekniktir (her iki yöntem tamamen birbiri ile ilişkilidir çünkü aynı görevi sınıfa özel bir uygulama ile gerçekleştirirler). Bir yöntemi gizlemek, yöntemi başka bir yöntemle değiştirmektir (yöntemler genellikle birbiri ile ilişkili değildir ve tümüyle farklı görevleri gerçekleştirebilirler). Bir yöntemi geçersiz kılmak yararlı bir programlama kavramıdır; bir yöntemi gizlemek genellikle bir hatadır. virtual anahtar sözcüğünü kullanarak bir yöntemi sanal yöntem olarak belirtebilirsiniz. Örneğin, System.Object sınıfındaki ToString yöntemi şu şekilde tanımlanır:
namespace System { class Object { public virtual string ToString() { ...

aynı sayıda ve türde parametreye ve aynı dönüş türüne sahip olmalıdır. } virtual ve override anahtar sözcüklerini kullanarak çok biçimli (polymorphic) yöntemler bildirirken (“Sanal Yöntemler ve Çok Biçimlilik” başlıklı sonraki metin kutusuna bakın) uymanız gereken bazı önemli kurallar vardır: n virtual ya da override anahtar sözcükleriyle özel bir yöntem bildiremezsiniz.. } Kalıtım ile Çalışmak 225 Not Java yazılım geliştiricileri. (Bir sonraki kısımda göreceğiniz gibi. diğeri de ortak olmalıdır. yöntemlerden biri ortak ise..Bölüm 12 } . yöntemler de korumalı olabilir. Örneğin. Örneğin: class Horse : Mammal { . bir yöntemin virtual (sanal) olduğunu bildirirse.. } } Yöntemin türetilmiş sınıftaki yeni uygulaması. base anahtar sözcüğünü kullanarak temel sınıftaki orijinal uygulamayı çağırabilir... override Yöntemler Bildirmek Temel bir sınıf..ToString(). C# yöntemlerinin varsayılan ayar olarak sanal olmadıklarına dikkat etmeliler.. public override string ToString() { . derleme zamanı hatası alırsınız.. yani. Örneğin: public override string ToString() { base. . türetilmiş bir sınıf o yöntemin başka bir uygulamasını bildirmek için override anahtar sözcüğünü kullanabilir. aynı ada. Bildirmeye çalışırsanız. İki yöntemin aynı erişim hakkına sahip olması gerekir. Özel gerçekten özeldir. } . İki yöntem imzası özdeş olmalıdır..) n n ..

aynı yöntemin farklı biçimlerini çağırmanızı sağlar. temel sınıfa ait olmalıdır. n n Sanal Yöntemler ve Çok Biçimlilik Sanal yöntemler. Temel sınıf yöntemi sanal değilse ve onu geçersiz kılmaya çalışırsanız. } } class Aardvark : Mammal { . aynı ada sahip olan tamamen farklı bir yöntemin uygulaması haline gelir. Türetilmiş sınıf override anahtar sözcüğünü kullanarak yöntem bildirmezse. virtual anahtar sözcüğünü kullanarak bir override yönteminin sanal olduğunu açıkca bildirmenize izin verilmez. Bu hassas bir konudur.. public override string GetTypeName () { return “This is a whale”. temel sınıf yöntemini de geçersiz kılmaz..226 Kısım II n C# Dilini Anlamak Yalnızca sanal bir yöntemi geçersiz kılabilirsiniz. } .. Bir override yöntemi dolaylı olarak sanaldır ve daha ileri türetilmiş bir sınıfta kendisi geçersiz kılınabilir. yöntemlerinin geçersiz kılınıp kılınmaması konusunda karar. çalışma zamanında dinamik olarak hesaplanan nesne türüne dayanarak. Bu durum.. public virtual string GetTypeName() { return “This is a mammal”. new anahtar sözcüğünü önceden anlatıldığı gibi kullanarak kapatılabilen derleme zamanı gizli uyarısına neden olur. Diğer bir deyişle.. public override string GetTypeName() { return “This is a horse”. derleme zamanı hatası ile karşılaşırsınız. Bununla birlikte.. } } class Horse : Mammal { . Daha önce anlatılan Mammal hiyerarşisi üzerinde bir çeşitlilik tanımlayan aşağıdaki örnek sınıfları düşünün: class Mammal { . } } class Whale : Mammal { ...

Horse sınıfı Mammal sınıfından türetildiğinden. Aardvark sınıfı bir GetTypeName yöntemine sahip değildir. Aardvark sınıfının bir GetTypeName yöntemine sahip olmadığı gerçeği. üç ifadenin de “Bu bir memeli” çıktısını vermesini beklersiniz. (Hatırlayın. ikinci ifade de “Bu bir balina” çıktısını verir. ilk durumda. Horse ve Whale sınıflarındaki GetTypeName yöntemi (kısaca tanımlanacaktır) tarafından kullanılan override anahtar sözcüğü ve ikincisi.GetTypeName()). tam olarak “çok sayıda biçim” anlamına gelir.GetTypeName()). bu nedenle ifade gerçekte “Bu bir at” çıktısını verir.WriteLine(myMammal. myMammal = myHorse.GetTypeName()). Aardvark myAardvark = new Aardvark(.WriteLine ifadesinin sonucu ne olacaktır? İlk bakışta... Bununla birlikte.. Horse myHorse = new Horse(. Kalıtım. nesne yönelimli programlama dilinde uzman programcıların tümünün bildiği gibi. // Horse myMammal = myWhale. Şimdi aşağıdaki kod bloğunu inceleyin: Mammal myMammal. private (özel) alanları ve yöntemleri sadece sınıfın kendisi tarafından erişilebilir.WriteLine(myMammal.WriteLine yöntemini çağırır.).) GetTypeName yöntemi. Console. Aynı ifadenin farklı yöntemleri çağırıyor olması çok biçimlilik (polymorphism) olarak adlandırılır.WriteLine ifadesine de aynı mantık uygulanır. // Whale myMammal = myAardvark. sınıfları birleştirmenin güçlü bir yoludur ve türetilmiş bir sınıf ile onun temel sınıfı arasında çok özel ve yakın bir ilişki vardır. Bununla birlikte. tek başlarına sınıflar karmaşık problemleri çözemezler. Çoğunlukla. İkinci Console. protected Erişimi Anlamak public ve private erişim anahtar sözcükleri erişim konusunda iki uç durum oluşturur: bir sınıfın public (ortak) alanları ve yöntemleri herkesin erişimine açık iken.WriteLine(myMammal.GetTypeName yöntemini çağırması gerektiğini anlar. Bu iki uç durum. Whale myWhale = new Whale(. bu nedenle “Bu bir memeli” çıktısını veren Mammal sınıfındaki varsayılan yöntem çağrılır.Bölüm 12 Kalıtım ile Çalışmak 227 İki şeye dikkat edin: Birincisi... myMammal değişkeninin gerçekte Horse’a başvurduğunu görebilirsiniz.. Console. Aardvark nesnesi üzerinde Console. Console.). virtual (sanal) olarak bildirildiğinden. bir Mammal değişkenine bir Horse atayabilirsiniz. Bununla birlikte. sınıfları tek başlarına düşünürken yeterlidir. . // Aardvark Üç farklı Console.). Üçüncü ifade. her ifade de bir Mammal türünde myMammal değişkeni üzerinde GetTypeName yöntemini çağırdığından. çalışma zamanı Horse.

farklı taşıt türlerini modellemek için basit bir sınıf hiyerarşisi tanımlayacaksınız. alanlarınızı kesinlikle özel tutmanızı önerir. bu alanlara erişemeyen sınıfın kullanıcılarına kapsülleme sağlar. A sınıfı. Bu şekilde üyeleri belirlemek için. B sınıfının korumalı üyesi etkin olarak özeldir. protected (korumalı) anahtar sözcüğünü kullanabilirsiniz: n Bir A sınıfı. . türetilmiş sınıflara özel olan bazı ek yöntemler ekleyeceksiniz. Diğer bir deyişle. Vehicle sınıfına Drive adında bir sanal yöntem ekleyerek. Add’i işaret edin ve daha sonra Class’ı tıklayın. B sınıfının korumalı üyesi etkin biçimde ortaktır. bu yöntemin türetilmiş sınıfların her ikisindeki varsayılan uygulamasını geçersiz kılacaksınız. Bununla birlikte. Korumalı alanlar. nesne-yönelimli programcılık kılavuzlarının çoğu. Microsoft Visual Studio 2008’i çalıştırın. Vehicle (Taşıt) adında bir temel sınıf ve Airplane (Uçak) ve Car (Araba) adında türetilmiş sınıflar tanımlayacaksınız. 2. Son olarak. Sınıfın tüm kullanıcılarının alanlara doğrudan. kapsüllemenin. aynı zamanda türetilmiş sınıftan türetilmiş sınıflardan da erişebilirsiniz. Diğer bir deyişle. Korumalı temel sınıf üyesi. Not Korumalı bir temel sınıf üyesine. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 12\ Vehicles klasöründe yer alan Vehicles projesini açın. B sınıfından türetilmiş değilse. Projeye. B sınıfından türetilmiş ise. korumalı alanlar. A sınıfı içinde. B sınıfının korumalı üyelerine erişemez. B sınıfının korunmuş üyelerine erişebilir.228 Kısım II C# Dilini Anlamak bir temel sınıf için. StartEngine ve StopEngine adında iki ortak yöntem tanımlayacaksınız. Sınıfların bir hiyerarşisini oluşturun 1. Vehicles projesinde bir önceki alıştırmada gördüğünüz Main ve Entrance yöntemleri ile Program sınıfını tanımlayan Program. türetilmiş sınıfların bu üyelere erişmesine izin vermek yararlıdır. Vehicle sınıfında. yalnızca türetilmiş bir sınıftan değil. yeni bir sınıf tanımlayan yeni bir dosya eklemenizi sağlayan Add New Item— Vehicles iletişim kutusu açılır. sınıftan kalıtımla alan sınıflar tarafından bozulmasına hala izin vermektedir. Ayrıca.cs dosyası yer almaktadır. erişilebilirliğini türetilmiş bir sınıfta koruyabilirken daha ileri türetilmiş sınıflar için erişilebilir konumdadır. Solution Explorer’da Vehicles projesini farenin sağ düğmesiyle tıklayın. Aşağıdaki alıştırmada. n C#. sınırsız erişimi olduğundan ortak alanlar kapsüllemeyi bozarlar. 3. programcılara hem yöntemleri hem de alanları korumalı olarak bildirmek için tam bir özgürlük vermektedir. Bununla birlikte. temel sınıfın bazı üyelerini hiyerarşide yer almayan sınıflardan gizlerken. türetilmiş A sınıfı içinde.

Vehicle. Dosya.WriteLine(“Landing”). 5. Name kutusuna Airplane. noiseToMakeWhenStarting). Aşağıda gösterildiği gibi.cs yazın ve Add’i tıklayın. Airplane sınıfına TakeOff ve Land yöntemlerini ekleyin: class Airplane : Vehicle { public void TakeOff() { Console. Project menüsünde Add Class’ı tıklayın. } public void StopEngine(string noiseToMakeWhenStopping) { Console.cs dosyası yaratıldığı ve projeye eklendiği. Add New Item—Vehicles iletişim kutusunda. 6. Airplane adında bir sınıf içeren yeni bir dosya projeye eklenir ve Code and Text Editor penceresinde görüntülenir.WriteLine(“Taking off”). Code and Text Editor penceresinde. her taşıt türü için farklı olacaktır ve daha sonraları hangi taşıtın çalıştığını.cs yazın ve Add’ i tıklayın. noiseToMakeWhenStopping). hangisinin durduğunu anlamanıza yardımcı olacaktır. Airplane sınıfının tanımlamasını. 8. } } . Name kutusuna Vehicle. Aşağıda koyu harflerle gösterildiği gibi. Vehicle sınıfına StartEngine ve StopEngine yöntemlerini ekleyin: class Vehicle { public void StartEngine(string noiseToMakeWhenStarting) { Console.WriteLine(“Stopping engine: {0}”. Vehicle adında boş bir sınıfın tanımlamasını içerir. noiseToMakeWhenStarting ve noiseToMakeWhenStopping parametrelerinin değerleri. } } Vehicle sınıfından türetilen tüm sınıflar bu yöntemleri kalıtımla alacaktır. Vehicle sınıfından türetilmiş olacak şekilde değiştirin: class Airplane : Vehicle { } 9. } public void Land() { Console. Add New Item—Vehicles iletişim kutusu görünür.Bölüm 12 Kalıtım ile Çalışmak 229 4. Code and Text Editor penceresinde görünür. 7.WriteLine(“Starting engine: {0}”.

WriteLine(“Default implementation of the Drive method”). Airplane sınıfının oluşumunu yaratın ve aşağıdaki gibi. Project menüsünde. 12.. } } 14.cs dosyasını görüntüleyin.StartEngine(“Contact”).230 Kısım II C# Dilini Anlamak 10.cs yazın ve Add’ i tıklayın. Aşağıda koyu harflerle gösterildiği gibi. Code and Text Editor penceresinde.WriteLine(“Journey by airplane:”). Airplane myPlane = new Airplane(). 17. Vehicle sınıfına. Vehicle sınıfından türetilmiş olacak şekilde değiştirin: class Car : Vehicle { } 13. myPlane. Add Class’ı tıklayın. 15. Code and Text Editor penceresinde Program. Add New Item—Vehicles iletişim kutusu görünür. Car adında bir sınıf içeren yeni bir dosya.WriteLine(“Braking”). hızlı bir uçak gezisi simule ederek yöntemlerini test edin: static void Entrance() { Console. public virtual void Drive() { Console. Entrance yönteminde. projeye eklenir ve Code and Text Editor penceresinde görüntülenir.WriteLine(“Accelerating”). Car sınıfının tanımlamasını. Car sınıfına Accelerate ve Brake yöntemlerini ekleyin: class Car : Vehicle { public void Accelerate() { Console.cs dosyasını görüntüleyin. . Car. Code and Text Editor penceresinde Vehicle.. } } 16. sanal Drive yöntemini ekleyin: class Vehicle { . Aşağıda koyu harflerle gösterildiği gibi. Name kutusuna. 11. } public void Brake() { Console.

Bölüm 12 myPlane. myCar. } .StopEngine(“Phut phut”).WriteLine(“Flying”). konsol penceresinde.StartEngine(“Brm brm”). 21. Bu ifadeler. uçak ve araba ile yapılan bir gezinin farklı aşamalarını gösteren iletilerin çıktısını verdiğini doğrulayın: Her iki ulaşım biçiminin de sanal Drive yönteminin varsayılan uygulamasını çağırdığına dikkat edin. Car myCar = new Car(). Entrance yönteminde biraz önce yazdığınız kodun hemen arkasına aşağıda koyu harflerle gösterilen ifadeleri ekleyin. myPlane. static void Entrance() { . Programın. aşağıdaki resimde gösterildiği gibi. myPlane. Debug menüsünde. Airplane sınıfındaki Drive yöntemini geçersiz kılın: public override void Drive() { Console.Drive(). Console. Car sınıfının bir oluşumunu yaratır ve yöntemlerini test eder. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın.TakeOff().Drive(). myCar.. } Kalıtım ile Çalışmak 231 18. myCar.Accelerate().WriteLine(“\nJourney by car:”). Aşağıdaki gibi. } 19. myCar.StopEngine(“Whirr”). Airplane sınıfını görüntüleyin.Land(). 20. Start Without Debugging’i tıklayın.. Code and Text Editor penceresinde. myCar.Brake(). myPlane. Çünkü sınıfların her ikisi de bu yöntemi geçersiz kılmaz.

Console. Vehicle v = myCar. v. Kod. Vehicle değişkenini Airplane nesnesine ilişkilendirir ve Drive yöntemi ile aynı görünen yöntemi tekrar çağırır. v = myPlane. Entrance yönteminin sonuna. Debug menüsünde.Drive(). Car nesnesinin de Motoring iletisini gösterdiğine dikkat edin. Car sınıfında Drive yöntemini geçersiz kılın: public override void Drive() { Console.232 Kısım II C# Dilini Anlamak Not IntelliSense’in kullanılabilir yöntemlerin listesini otomatik olarak görüntülediğine dikkat edin. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. Son iki ifade.Drive(). Böyle olursa.. 25. Vehicle nesnesidir) ve daha sonra bu Vehicle değişkenini kullanarak Drive yöntemini çağırır. } Bu kod. Konsol penceresinde. bu alıştırma için gerekli olmayan ifadeyi silin.cs dosyasını görüntüleyin. v. uygulama Drive yöntemini çağırdığında Airplane nesnesinin şimdi Flying iletisini. Code and Text Editor penceresinde Car sınıfını görüntüleyin. çünkü tüm Car nesneleri. aşağıda koyu harflerle gösterilen ifadeleri ekleyin: static void Entrance() { . daha önceki iletinin arkasından aşağıdaki metnin görüntülendiğini doğrulayın: Testing polymorphism Motoring Flying . Code and Text Editor penceresinde Program. Aşağıdaki gibi.WriteLine(“\nTesting polymorphism”). Start Without Debugging’ i tıklayın.. sanal Drive yöntemi tarafından sağlanan çok biçimliliği test eder. } 23. IntelliSense listesinden Drive yöntemini seçerseniz. Debug menüsünde. 27. Start Without Debugging‘i tıklayın. Visual Studio otomatik olarak. 22. 26.WriteLine(“Motoring”). base. bir Vehicle değişkeni kullanarak Car nesnesine başvuru oluşturur (bu güvenlidir. Konsol penceresinde.Drive yöntemini çağıran ifadeyi kodunuza ekler. 24.

Int32 türü ile ilgili tüm işlevselliği miras alacaktır. genişletilmiş türdeki veriye başvuran herhangi bir ifadede hemen kullanılabilir hale gelir. . Int32’den kalıtımla alan (int türü System.Drive yöntemini çağırır.. en uygun mekanizma değildir özellikle var olan kodu etkilemeden bir türü hızlıca genişletmeniz gerekiyorsa.Int32 türü aslında bir sınıf değil. Negate yöntemine ek olarak. Uzantı Yöntemlerini Anlamak Kalıtım oldukça kullanışlı bir yöntemdir. bu değişken tarafından başvurulan nesnenin gerçek türüne dayanan bir Vehicle değişkeni üzerinde çağırdığınızda. Şu iki nedenden dolayı bu yaklaşımı kullanmayı istemeyebilirsiniz: n Bu yöntem sadece NegInt32 türüne uygulanır ve yöntemi kodunuzda var olan int değişkenlerle kullanmak isterseniz. bir yapıdır ve yapılarla kalıtımı kullanamazsınız.Int32 için bir takma addır) ve Negate yöntemini ekleyen NegInt32 adında yeni bir tür tanımlamak olabilir: class NegInt32 : System. 28. System. int türüne yeni bir özellik eklemek istediğinizi varsayın: bir tamsayının içerdiği değerin negatifini döndüren Negate adlı bir yöntem. bu nedenle çalışma zamanı (derleyici değil). İkinci durumda. ek statik yöntemlerle genişletmenizi sağlar. } } // bunu denemeyin! Teori şudur: NegInt32. Bir uzantı yöntemi mevcut bir türü (sınıf ya da yapı). bazen yeni davranışlar eklemek için kalıtım kullanmak. İlk durumda. her int değişkenin tanımını. Bununla birlikte. System. (Aynı görevi gerçekleştirmek için tek bir eksi işlecini (-) kullanabileceğinizi biliyorum. türü NegInt32 olacak şekilde değiştirmeniz gerekir. n Bu noktada uzantı (extension) yöntemleri çok kullanışlıdır.) Bunu yapmanın bir yolu.Drive yöntemini çağırır. bir sınıftan yeni bir sınıf yaratarak. fakat sabredin.Int32 { public int Negate() { . hangi Drive yönteminin çağrıldığını bulur. bu nedenle uygulama Car. Vehicle nesnesi bir Car’a başvurur. o sınıfın işlevselliğini genişletmenizi sağlar.Bölüm 12 Kalıtım ile Çalışmak 233 Drive yöntemi sanaldır. bu nedenle uygulama Airplane. Bu statik yöntemler.. System. Vehicle nesnesi bir Airplane’a başvurur. Örneğin. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın.

// to do yorum satırı dışında boştur. Bir uzantı yöntemi yaratın 1. . Aşağıdaki alıştırmada. Console. fakat Negate yöntemini bir uzantı yöntemi olarak tanımlayan parametreyi ekleyen. Util. Uzantı yöntemlerini bir statik sınıf içinde tanımlamanız gerektiğini hatırlayın. Code and Text Editor penceresinde Util.WriteLine(“x. Negate yöntemini çağıran ifadede herhangi bir yerde Util sınıfına başvurmanıza gerek olmadığına dikkat edin. this anahtar sözcüğünün önüne eklenen parametrenin int olması. int türüne bir uzantı yöntemi ekleyeceksiniz.Negate {0}”. Burada. Extensions adındaki ad alanında Util adında bir statik sınıf içerir. Util sınıfını kapsam içine getirin (Gerekirse. Bu dosya.WriteLine(“x. Sınıf. bu kullanım.234 Kısım II C# Dilini Anlamak Bir static sınıfta bir uzantı yöntemi tanımlayın ve this anahtar sözcüğü ile yöntemin ilk parametresinin türünü belirtin. this anahtar sözcüğüdür. 2. Ayrıca. parametre olarak int türü geçiren Utils. int türünü genişlettiğiniz anlamına gelir.Negate {0}”. Daha sonra yönteme başvurmak için “. } } Sözdizimi biraz garip görünüyor. kapsam içindeki statik sınıfların tümünden uzantı yöntemlerini otomatik olarak ortaya çıkarır. Util sınıfının ait olduğu ad alanını belirten bir using ifadesi ekleyin).Negate()). Uzantı yöntemini kullanmak için. verilen bir tür için.Negate yöntemini de çağırabilirsiniz: int x = 591.Negate(x)).” nokta işaretini kullanabilirsiniz: int x = 591.cs dosyasını görüntüleyin. yöntemi bir uzantı yöntemi olarak tanımlama amacını karşılamamasa da. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 12\ ExtensionMethod klasöründe yer alan ExtensionMethod(UzantıYöntemi) projesini. C# derleyicisi. farklı sayı tabanındaki gösterimine çevirir. Console. 10 tabanında bir sayı içeren int değişkeninin değerini. Visual Studio 2008’de açın. int türü için Negate uzantı yöntemini nasıl uygulayabileceğinizi gösteren örnek şu şekildedir: static class Util { public static int Negate(this int i) { return –i. daha önce gördüğünüz sıradan sözdizimini kullanarak. x. Bu uzantı yöntemi.

Yöntem. Aşağıda koyu harfle gösterilen ifadeleri. return result. Yöntem. Bu alıştırma tarafından kullanılan algoritma. Program. result += nextDigit * (int)Math.Pow(10. baseToConvertTo ile gösterilen sayı tabanına çevirir. } 5. } while (i != 0). ArgumentException özel durumu oluşturan ifadeden sonra. ConvertToBase yöntemi şu şekilde görünmelidir: static class Util { public static int ConvertToBase(this int i... i parametresinin değerini. Bu kod. int baseToConvertTo) { if (baseToConvertTo < 2 || baseToConvertTo > 10) throw new ArgumentException(“Value cannot be converted to base “ + baseToConvertTo. ConvertToBase yöntemine ekleyin. do { int nextDigit = i % baseToConvertTo.ToString()). int iterations = 0. 10 tabanındaki sayıyı farklı bir sayı tabanına çeviren. iterations++. i /= baseToConvertTo. iterations). uygun bir iletiyle bir ArgumentException özel durumu oluşturun. int baseToConvertTo) { . int baseToConvertTo) { } } 4. Util sınıfına. Yöntem iki parametre almalıdır: yöntemin int türü için bir uzantı yöntemi olduğunu göstermek için. baseToConvertTo değeri.cs dosyasını görüntüleyin. Code and Text Editor penceresinde. çevrilmiş değeri içeren bir int döndürmelidir. ConvertToBase yöntemine. baseToConvertTo parametresinin değerinin 2 ile 10 arasında olup olmadığını denetleyen bir if ifadesi ekleyin. int result = 0. bu sayı aralığı dışında güvenli olarak çalışmaz. . ConvertToBase yöntemi şu şekilde görünmelidir: public static int ConvertToBase(this int i. bilinen bir algoritmayı uygular: public static int ConvertToBase(this int i. } 6. this anahtar sözcüğü ile i adında int türü bir parametre ve baseToConvertTo adında sıradan bir int türü parametre. ConvertToBase adında bir public statik yöntem ekleyin.Bölüm 12 Kalıtım ile Çalışmak 235 3. bu aralık dışında ise.

konsolda farklı sayı tabanlarında 591 değerini gösteren iletileri görüntülediğini doğrulayın: 10. i. Bu ifade. Programı kapatmak için Enter’a basın.WriteLine(“{0} in base {1} is {2}”. Bu görevi gerçekleştirmezseniz. . 8. Tebrikler. Util sınıfını içeren ad alanını kapsam içine getirir. ConvertToBase’in IntelliSense’de bir uzantı yöntemi olarak göründüğüne dikkat edin. x’den sonra (. (İstediğiniz bir tamsayı değerini seçebilirsiniz. i <= 10. i++) { Console.236 Kısım II C# Dilini Anlamak 7. Dosyanın en üstündeki ifadeden. 2 ile 10 arasındaki tüm sayı tabanlarında 591 değerinin çıktısını veren bir döngü kullanır.) nokta yazdığınızda. Programın aşağıdaki gibi.WriteLine ifadesinde. Start Without Debugging’i tıklayın.ConvertToBase(i)). Debug menüsünde. Ayrıca. aşağıdaki using ifadesini ekleyin: using Extensions. x. for (int i = 2. mevcut bir türe bir uzantı yöntemini nasıl ekleyeceğinizi gördünüz. Sınıfların hiyerarşisini tanımlamak için başarılı bir şekilde kalıtımı kullandınız ve şimdi kalıtımla alınmış yöntemleri nasıl geçersiz kılacağınızı ve sanal yöntemleri nasıl uygulayacağınızı anlamış olmalısınız. } Bu kod. x adında bir int değişken yaratır ve 591 değerini atar. ConvertToBase uzantı yöntemi Program.cs dosyasında erişilebilir olmaz. 9. Console. using System’den sonra. x. Program sınıfının Entrance yöntemine aşağıdaki ifadeleri ekleyin: int x = 591.) Kod daha sonra.

.Bölüm 12 n Kalıtım ile Çalışmak 237 Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 13’e geçin. } .. public Derived(int x) : Base(x) { .. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.. } . Örneğin: class Mammal { public virtual void Breathe() { .. Save iletişim kutusu görünürse... } . n Bölüm 12 Hızlı Başvuru Bunun İçin Temel bir sınıftan türetilmiş bir sınıf oluşturmak Şunu Yapın Yeni sınıf adı bildirin. ardından iki nokta üst üste ve temel sınıfın adını yazın... } Bir sınıfı kalıtımla almak için kurucu parçası olarak bir temel sınıf kurucusu çağırın Türetilmiş sınıf kurucusunun gövdesinden önce kurucu parametre listesini sağlayın.. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Örneğin: class Derived : Base { . Örneğin: class Derived : Base { . } Sanal bir yöntem bildirmek Yöntemi bildirirken virtual anahtar sözcüğünü kullanın...

} Bir tür için uzantı yöntemi tanımlamak Statik sınıfa statik ortak yöntem ekleyin. } } ..238 Kısım II C# Dilini Anlamak Kalıtımla alınan sanal yöntemi geçersiz kılan bir türetilmiş sınıftaki yöntemi uygulamak Türetilmiş sınıftaki yöntemi bildirirken override anahtar sözcüğünü kullanın. Örneğin: static class Util { public static int Negate(this int i) { return –i. } . İlk parametre.. Örneğin: class Whale : Mammal { public override void Breathe() { . önünde this anahtar sözcüğü ile genişletilmiş türde olmak zorundadır...

bir sınıfın yöntemlerinin adları ve imzalarını. Bununla birlikte. Bir arabirim kullanmak. Soyut sınıflar. problem.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n Yöntem adlarını belirleyen bir arabirim tanımlamak. Fakat bu belirtilmemiş nesneleri sıralamanın bir yolunu bulmanız gerekir. Bir an düşünürseniz. nesneleri saklamak için bir uygulama sağlayan yeni bir koleksiyon sınıfı tanımlamak istediğinizi varsayın. Koleksiyon sınıfı yazdığınızda türünü bilmediğiniz nesneleri sıralayan bir yöntemi nasıl sağlayacaksınız? İlk bakışta. Bir arabirim herhangi bir kod ya da veri içermez. tutabileceği nesnelerin türünde bir kısıtlama olmasını istemezsiniz ve bu nedenle bu nesneleri nasıl sıralayacağınızı bilemezsiniz. nesnelerin kendi türlerine bağlı olmasıdır. Bununla birlikte. yöntemin uygulanmasından tamamen ayırabilmenizi sağlar. fakat kalıtımın gerçek gücü bir arabirimden kalıtımla almasından gelir. Çoğu kez. Yöntemlerin gövdesini yazarak bir yapı ya da sınıf içinde bir arabirim uygulamak. sealed anahtar sözcüğünü kullanarak bir sınıfın temel bir sınıf olarak kullanılamayacağını bildirmek. bu yöntemler için kendi uygulamasını sağlamak zorundadır. Koleksiyon sınıfını tanımladığınızda. Bir sınıftan kalıtımla almak güçlü bir mekanizmadır. soyut sınıfları arabirimlerle kullanırsınız. bu nedenle sanal yöntem çok fazla kullanılmayacaktır. Bölüm 12’de anlatılan ToString problemine benzer ve koleksiyon sınıfınızın alt sınıflarının geçersiz kılabileceği bir sanal yöntem bildirerek çözülebilir gibi görünüyor. koleksiyondaki nesnelerin sıralanma şeklinin koleksiyona değil. Bu nedenle 239 . Birlikte. kod ve veri içerebilmeleri dışında. Arabirimleri Anlamak İçerdiği nesnelerin türüne bağlı olan bir sırada. bu nedenle soyut sınıftan kalıtımla alan bir sınıf. sadece bir arabirimden kalıtımla alan bir sınıfın sağlamak zorunda olduğu yöntemler ve özellikleri belirtir. bir soyut sınıfın başlıca yöntemlerini belirleyebilirsiniz. durum bu değil. Genellikle koleksiyon sınıfı ile sınıfın tuttuğu nesneler arasında kalıtıma benzer bir ilişki yoktur. Bir soyut sınıf içinde yaygın uygulama ayrıntılarını yakalamak. birçok yönden arabirimlere benzer. genişletilebilir programlama çerçeveleri oluşturmanızı sağlayan anahtar teknikler sağlarlar.

arabirim sınıfın. burada gösterildiği gibi.NET Framework belgeleri. . Bu teknikle. } Koleksyion sınıfı. } İpucu Microsoft . aşağıdaki CompareTo yöntemine bakın: int CompareTo(object obj) { // return 0 if this instance is equal to obj // return < 0 if this instance is less than obj // return > 0 if this instance is greater than obj . arabirimlerinizin adını büyük harf I ile başlatmanızı önerir. size yalnızca yöntemin adının. içeriklerini sıralamak için bu yöntemi kullanabilir. Arabirim içinde. interface anahtar sözcüğünü kullanırsınız. tüm nesnelerin koleksiyonun çağırabileceği ve koleksiyonun nesneleri birbirleri ile karşılaştırmasına imkan tanıyan bir yöntem sağlamaları gerekmesidir. bir nesnenin o anda nasıl kullanıldığından çok. class ya da struct anahtar sözcükleri yerine. biriktirilebilir nesneler için bir arabirim tanımlayabilir ve koleksiyon sınıfının sadece bu arabirimi uygulayan sınıfları biriktirebileceğini belirtebilirsiniz. System ad alanı. Bu. koleksiyondaki tüm nesneler üzerinde CompareTo yöntemini çağırabilir ve nesneleri sıralayabilirsiniz. Arabirim. arabirimde belirtilen tüm yöntemleri içerdiğini garanti eder. Bir sınıf bir arabirim uyguluyorsa. bir arabirim bir sözleşmeye benzer.240 Kısım II C# Dilini Anlamak çözüm.. Arabirimler “ne”yi “nasıl”dan doğru olarak ayırmanızı sağlar. sizin onu nasıl kullanmak istediğinizi gösterir.. Arabirim. private ya da protected) kullanmazsınız ve yöntem gövdesini noktalı virgülle değiştirirsiniz. farklı olarak herhangi bir erişim değiştirici (public. zaten IComparable arabirimini tanımlar. Bu biçimde. yöntemleri aynen bir sınıf ya da yapı içindeki gibi bildirirsiniz. Örnek olarak. dönüş türünün ve parametrelerinin ne olduğunu söyler. Yöntemin kesin olarak nasıl kullanıldığı arabirimin konusu değildir. CompareTo yöntemini içeren. Bu arada. Örneğin: interface IComparable { int CompareTo(object obj). Arabirim Sözdizimi Bir arabirim tanımlamak için. C#’taki Macar Simgelemi’nin son eseridir.

sınıflar ya da arabirimler gibi) yuvalayamazsınız. Bir arabirimdeki tüm yöntemler dolaylı olarak ortaktır. int ILandBound. Bölüm 12’de gösterilen Mammal hiyerarşisini tanımladığınızı ve ayaklı memelilerin bacak sayısını int olarak döndüren NumberOfLegs adında bir yöntem sağlamanız gerektiğini varsayın (Deniz hayvanları bu arabirimi uygulamaz. arabirimden kalıtımla alan ve arabirim tarafından belirtilen tüm yöntemleri sağlayan bir sınıf ya da yapı bildirirsiniz. Horse sınıfında bu arabirimi uygulayabilirsiniz: class Horse : ILandBound { . Fakat bir arabirim başka bir arabirimden kalıtımla alınabilir. Bir arabirim içinde yıkıcı tanımlamanıza izin verilmez. Kurucu da. bir arabirimin hiçbir zaman hiçbir uygulama içermediğidir. bir arabirimin bunların herhangi birinden kalıtımla alınmasına izin verilseydi. Aşağıdaki kısıtlamalar bu durumun doğal sonuçlarıdır: n Bir arabirim için herhangi bir alan tanımlamanıza izin verilmez (statik alana bile). (Yıkıcılar ”Çöp Toplama ve Kaynak Yönetimini Kullanmak” başlıklı Bölüm 14’te anlatılmıştır. Bir alan.) Herhangi bir yöntem için bir erişim değiştiricisi belirtemezsiniz. } } . yapılar. Bir yıkıcı. Bir arabirim içinde hiçbir türü (numaralandırmalar. n n n n n Bir Arabirim Uygulamak Bir arabirim uygulamak için. Yapılar ve sınıflar uygulamalar içerirler.NumberOfLegs() { return 4. Bir arabirim içinde kurucu tanımlamanıza izin verilmez... bir sınıf ya da yapının uygulama detayı olarak düşünülür. bir sınıf ya da yapının uygulama detayıdır. } Daha sonra. Örneğin. bir nesne oluşumunu yıkmak için kullanılan ifadeleri içerir.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 241 Arabirim Kısıtlamaları Hatırlanması gereken konu. Bir arabirimi bir yapı ya da sınıftan kalıtımla almanıza izin verilmez.) Bu yöntemi içeren ILandBound arabirimini aşağıdaki gibi tanımlayabilirsiniz: interface ILandBound { int NumberOfLegs(). bazı uygulamaları da kalıtımla almış olacaktı.

Yöntem adı. Açık olarak arabirim uygulaması. Bu durumda. Bununla birlikte. Aynı adda. Bu farklılıkların bazıları karışıklığa neden olabilir. Ayrıca. sınıf derlenmez. C#. bakımı daha kolay ve önceden tahmin edilebilir daha çok kod yazmanıza yardımcı olan pek çok avantaj sunar. Arabirim adını açık olarak belirtmeden bir yöntem uygulayabilirsiniz fakat bu. arabirim adı ile başlar. dönüş türünde ve parametrelerde yöntemler içeren birden fazla arabirim mümkündür. Java’da olduğu gibi bir . Açık Arabirim Uygulamalarının Avantajları Bir arabirimi açık biçimde uygulamak biraz gereksiz görünebilir fakat daha temiz. mümkün olduğunca arabirimi açık olarak uygulamayı önerdik. bir sınıftaki yöntemin hangi arabirime ait olduğunu tanımlar. ancak arabirim adını ihmal etmek bu davranışa izin verir. anahtar sözcükler kullanarak temel sınıf ve temel arabirim arasında. ortak imzalara sahip yöntemlerle birden fazla arabirim uygularsa. yöntem bir erişim nitelendiriciye sahip olmamalıdır. Parametreler (ref ve out anahtar sözcük değiştiricileri de dahil) kesin olarak eşleşmelidir. uygulamanın davranış biçimlerinde bazı farklılıklara neden olabilir. her yöntemin kendine uygun olan arabirim yöntemiyle tam olarak eşleşmesini garantiye almalısınız: n n n Yöntem adları ve dönüş türleri kesin olarak eşleşmelidir . Bu kitapta. Bir sınıf. açıkça arabirim uygulamasını kullanarak tanımlanmış bir yöntem sanal olarak bildirilemez. Bir sınıf başka bir sınıfa genişletebilir ve aynı anda bir arabirim uygulayabilir. Bir arabirim uygulayan tüm yöntemler ortak olarak erişilebilir olmak zorundadır. n Arabirim tanımı ve arabirimin bildirilen uygulaması arasında herhangi bir fark varsa. Örneğin.242 Kısım II C# Dilini Anlamak Bir arabirim uyguladığınızda. açık arabirim uygulaması kullanıyorsanız. her arabirim için yöntemler ortak olarak erişilebilir fakat sadece arabirimin kendisi üzerinden erişilebilir. Bu açık olarak arabirim uygulaması olarak bilinir ve iyi bir alışkanlıktır. Bir sonraki “Bir Sınıfa Arabirimi Üzerinden Başvurmak” başlıklı bölümde bunun nasıl olacağına bakacağız. yöntem uygulamaları arasındaki belirsizliği gidermek için açık olarak arabirim uygulamasını kullanabilirsiniz.

C# konumsal bir belirtim kullanır. aşağıda gösterilen FindLandSpeed yöntemi.. çünkü türler belirtilen arabirimi uyguladığı sürece. aşağıdaki gibi. parametre olarak farklı türler alabilen yöntemler tanımlayabilmenizi sağlar. } class Mammal { ..Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 243 ayırım yapmaz.. fakat ek olarak ILandBound arabirimini uygulayan bir sınıf olarak tanımlar: interface ILandBound { . fakat tersi doğru değildir. . Bunun yerine. // çalışır Tüm atların ayakları olduğundan bu başvuru çalışır.. } Bir arabirim üzerinden bir nesneye başvurduğunuzda.). Bir nesneye bir arabirim üzerinden başvurma tekniği yararlıdır... ILandBound iMyHorse = myHorse. Horse sınıfını.. aynı şekilde. Bir önceki örneği ele alırsak. } Bir Sınıfa Arabirimi Üzerinden Başvurmak Hiyerarşide üst sırada yer alan sınıf olarak tanımlanmış bir değişken kullanarak bir nesneye başvurabildiğiniz gibi.. bir Mammal olan. Dönüştürme yapmadan. sadece arabirim üzerinden erişilebilen yöntemleri çağırabileceğinize dikkat edin. bir ILandBound değişkeni kullanarak bir Horse nesnesine başvurabilirsiniz: Horse myHorse = new Horse(. ILandBound { . Örneğin.. Önce temel sınıf adlandırılır. bunu bir virgül takip eder. Aşağıdaki örnek. } class Horse : Mammal .. ILandBound arabirimini uygulayan herhangi bir bağımsız değişken alabilir: int FindLandSpeed(ILandBound landBoundMammal) { . sınıfının uyguladığı bir arabirim olarak tanımlanmış bir değişken kullanarak bir nesneye başvurabilirsiniz. bir Horse değişkenine bir ILandBound nesnesi atayamazsınız. daha sonra temel arabirim yazılır.

Horse sınıfını şu şekilde tanımlayabilirsiniz: class Horse : Mammal.WriteLine(“Chewing grass”). } Soyut Sınıflar ILandBound ve IGrazable arabirimleri. Bir sınıf yine de tüm arabirimlerinden kalıtımla aldığı yöntemlerin tümünü uygulamak zorundadır. ILandBound. ortak . IGrazable { . } class Sheep : Mammal. aşağıdaki iki sınıftaki yineleme çok açıktır: class Horse : Mammal. Bu gibi durumlarda.WriteLine(“Chewing grass”). Bir sınıf ayrıca bir temel sınıfa sahipse. Bu yeniden düzenlemenin yolu. Yinelemeden kaçınmak ve kodun bakımını kolaylaştırmak için kodu yeniden düzenlemelisiniz..ChewGrass() { Console. C# uygulamanızda kaç farklı memeli türü modellemek istediğinize bağlı olarak. // geviş getiren at için olan kodun aynısı }. ILandBound. birden fazla arabirimden kalıtımla alınırsa. arabirimler temel sınıftan sonra listelenir. Örneğin.. void IGrazable. void IGrazable. Örneğin. IGrazable { . bir yapı ya da bir sınıf.. IGrazable { .. // geviş getirme için kod }. tüm otobur hayvanlar için ChewGrass (GevişGetirme) yöntemi içeren IGrazable adında başka bir arabirim tanımladığınızı varsayın.244 Kısım II C# Dilini Anlamak Çoklu Arabirimlerle Çalışmak Bir sınıf en fazla bir temel sınıfa sahip olabilir fakat sınırsız sayıda arabirim uygulamasına izin verilir. Bir arabirim. çok sayıda farklı sınıflar tarafından uygulanabilir.ChewGrass() { Console. türetilmiş sınıfların parçalarının ortak uygulamaları paylaşmaları oldukça yaygındır. arabirimleri virgülle ayırarak yazarsınız... } Kodda meydana gelen yineleme bir uyarı işaretidir. ILandBound.

GrazingMammal sınıfında. Bu gerçekten mantıksız. GrazingMammal sınıfı. Soyut bir sınıfta varsayılan bir uygulama sağlamak mantıklı değilse . } Bir GrazingMammal nesnesi oluşturmaya çalışırsanız. } class Sheep : GrazingMammal.. (Bölüm 12’de sanal yöntemleri görmüştünüz.. ILandBound { .ChewGrass() { Console. Soyut yöntem. kendi haklarına sahip bir girişten çok. abstract anahtar sözcüğünü kullanarak. // geviş getirme için ortak kod } } class Horse : GrazingMammal. // derlenmez Soyut Yöntemler Bir soyut sınıf. kod derlenmez: GrazingMammal myGrazingMammal = new GrazingMammal(.... temelde sanal yönteme benzer. bir yöntem gövdesi içermemesi dışında. Bir sınıfın oluşumlarının yaratılmasına izin verilmediğini bildirmek için. sanal yöntem olarak DigestGrass yöntemini tanımlar. otçul memeliler otları çiğnemek için aynı kodu kullanabilirler fakat DigestGrass yönteminin kendi uygulamasını sağlamak zorundadırlar.). Aşağıdaki örnek. soyut yöntemler içerebilir. ILandBound { . Örneğin: abstract class GrazingMammal : Mammal. IGrazable { . sınıf hiyerarşisine yeni bir sınıf ekleyebilirsiniz. Tek amacı.. Gerçekte. void IGrazable. ortak varsayılan uygulamayı sağlamak için vardır.. } Bu iyi bir çözümdür fakat hala tam olarak doğru olmayan birşey var: Gerçekten GrazingMammal sınıfının (ya da Mammal sınıfının) oluşumlarını yaratabilirsiniz. IGrazable { .) Türetilmiş bir sınıf. ortak işlevselliklerin bir soyutlamasıdır. GrazingMammal sınıfı...WriteLine(“Chewing grass”)..Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 245 uygulamayı özellikle bu amaç için yaratılmış yeni bir sınıfa yerleştirmektir. Örneğin: class GrazingMammal : Mammal. kalıtımla alınmasıdır. açıkça sınıfın soyut olduğunu bildirmeniz gerekir. bu yöntemi geçersiz kılmak zorundadır.

Bir sanal (virtual) yöntem. soyut sınıflar ve sınıflar hiyerarşisi oluşturma becerisi geliştirebilirsiniz fakat bu çaba gerektirir ve ayrıca modellediğiniz problemi çok iyi anlamanız gerekir. o sınıfın temel sınıf olarak kullanılmasını önlemek için sealed anahtar sözcüğünü kullanmanıza imkan tanır. temel bir sınıf olarak kullanmak amacıyla bilerek bir sınıf tasarlamadığınız sürece. Örneğin: sealed class Horse : GrazingMammal.. virtual. Mühürlenmiş Yöntemler sealed anahtar sözcüğünü. bir sınıfın temel sınıf olmaması gerektiğine karar verdiyseniz. Buradaki sorun. ILandBound { . IGrazable { abstract void DigestGrass(). mühürlenmemiş bir sınıfta tek bir yöntemi mühürlenmiş olarak bildirmek için de kullanabilirsiniz. Bir geçersiz kılma (override) yöntemi. . kullanımı kolay arabirim. } Mühürlenmiş Sınıflar Kalıtımı her zaman akıllıca kullanmak kolay değildir. sealed override olarak bildirirsiniz.. Pratik yaptıkça ve deneyim kazandıkça. gelecekte kalıtımla alınacak bir şeyler yazıyorsunuz demektir. Bir mühürlenmiş (sealed) yöntem. Bu. Sealed (Mühürlenmiş) sınıf. bir yöntemin diğer bir uygulamasıdır. Bunu yapmanın başka bir yolunu bulmak için. abstract class GrazingMammal : Mammal. bir yöntemin ilk uygulamasıdır. geleceği önceden tahmin etmenin zor olmasıdır. } Herhangi bir sınıf. override ve sealed anahtar sözcüklerini şu şekilde düşünebilirsiniz: n n n n Bir arabirim (interface). Not Bir yapı dolaylı olarak mühürlenmiştir. Bir arabirim ya da soyut bir sınıf yaratırsanız. bir soyut yöntem yararlı olacaktır.) interface. herhangi bir sanal yöntem bildiremez ve soyut bir sınıf mühürlenemez. derleme hatası meydana gelir. Bir yapıdan asla türetemezsiniz. C#.. . temel sınıf olarak görev yapması imkansızdır. bir yöntemin adını tanıtır. türetilmiş bir sınıfın daha sonra mühürlenmiş yöntemi geçersiz kılamayacağı anlamına gelir.246 Kısım II C# Dilini Anlamak ve bir sınıftan kalıtımla almanın o yöntemin kendi uygulamasını sağladığından emin olmak istiyorsanız. esnek.. bir yöntemin son uygulamasıdır. Horse sınıfını temel sınıf olarak kullanmaya kalkarsa. (Yöntemi. Sadece bir override yöntemi mühürleyebilirsiniz.

şunları yaratabilirsiniz: n n Zengin metin kutusunda kaynak dosyayı gösteren görüntüleyici ziyaretçi (visitor) sınıfı. işleçler ve bunun gibi) içinde sınıflandırmak için birlikte basit bir çerçeve (framework) uygulayan arabirimler ve sınıfların hiyerarşisi ile tanışacaksınız. Çerçeve. Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\Chapter 13\ Tokenizer klasöründeki Tokenizer projesini açın. Addison Wesley Longman. Code and Text Editor penceresinde SourceFile. 1. Sekmeleri boşluklara dönüştüren ve küme parantezlerini doğru olarak hizalayan bir yazıcı ziyaretçi sınıfı. tokens olarak adlandırılan bir özel dizi alanı içerir: private { new new new new . anahtar sözcükler.cs dosyasını görüntüleyin. Not Bu çerçeve. ilk olarak Erich Gamma. Richard Helm. her sınıftaki üyelerin sayısını ve her kaynak dosyasındaki satırların sayısını sayan sayıcı ziyaretçi sınıfı.. . bir C# kaynak dosyasını okumak ve dosyanın içeriğini tokens (simgeler) (tanımlayıcılar. n n n n Kalıtım hiyerarşisini ve amacını anlayın . 1995) kitabında belgelendirilen Visitor modelini uygular. IdentifierToken(“System”). SourceFile sınıfı. Kodda yuvalanmış küme parantezlerinin derinliğini gösteren karmaşıklık ziyaretçi sınıfı. 2. WhitespaceToken(“ “). PunctuatorToken(“. Ralph Johnson ve John Vlissides tarafından Design Patterns: Elements of Reusable Object-Oriented Software (Tasarım Modelleri: Yeniden Kullanılabilir Nesne-Yönelimli Yazılımın Elemanları. IVisitableToken[] tokens = KeywordToken(“using”).Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 247 Genişletilebilir Çerçeve Uygulamak Aşağıdaki alıştırmada. 3. Büyük harfle başlayan ortak tanımlayıcıları ve büyük I ile başlayan arabirimleri denetleyen kılavuz ziyaretçi sınıfı. tipik bir derleyicinin gerçekleştirebileceği bazı görevleri yerine getirir. sırayla her bir simgeyi “ziyaret etmek” için bir teknik sağlar.. }.”). Bu çerçeve. Her bir tanımlayıcının yazılışını denetleyen heceleyici ziyaretçi sınıfı. Örneğin. özel görevleri gerçekleştirmek için. Microsoft Visual Studio 2008’i başlatın. Her yöntemdeki satır sayısını.

Bu dosya IVisitableToken arabirimini tanımlar. simgenin türüne göre değişik yollarla işleyecektir: public void Accept(ITokenVisitor visitor) { foreach (IVisitableToken token in tokens) { token.Accept yöntemi geçerli simgeyi. visitor parametresi. IVisitable arabirimi.cs dosyasını görüntüleyin. Bu dosya. IVisitable ve IToken arabirimlerinden kalıtımla alır fakat kendi yöntemlerini tanımlamaz: interface IVisitableToken : IVisitable. Code and Text Editor penceresinde IVisitable. tipik olarak bir switch ifadesi üzerinden.Accept yönteminin gövdesi simgelerin içinden yinelenir. her bir simgenin türünü tanımlayacak ve dinamik olarak tokens dizisi yaratacaktır. tümü IVisitableToken arabirimini (kısaca açıklanmıştır) uygulayan art arda gelen nesneleri içerir. Accept (KabulEt) adında bir ortak yöntem içerir. onların Accept yöntemlerini çağırır. simgenin kendi sınıfının yöntemleri devreye girer. world” kaynak dosyasının simgelerini taklit ederler. ITokenVisitor türünde tek bir parametreye sahiptir. uygun sınıf türünü kullanarak yaratılacaktır. her simgenin Accept yöntemini uygulamak zorunda olduğunu hatırlayın. (Bütün bir derleyici bir kaynak dosyayı gramer bakımından inceleyecek. Token . IVisitableToken arabirimi kullanılarak erişilir. . (Bir arabirimden kalıtımla alan herhangi bir sınıf. SourceFile . Accept adında tek bir yöntem bildirir: interface IVisitable { void Accept(ITokenVisitor visitor). visitor nesnesinin ziyaret ettiği simgeyi işleyen ziyaretçi sınıfının bir oluşumudur. } SourceFile sınıfı içindeki simgelerin dizisindeki her nesneye.Accept(visitor). IVisitable arabirimini tanımlar. View menüsünde. bu simgeler basit bir “hello. SourceFile . } } Bu şekilde. Her simge. Birlikte.) SourceFile sınıfı ayrıca. IToken { } 5. IVisitableToken arabirimi.248 Kısım II C# Dilini Anlamak tokens dizisi.Accept yöntemi. visitor nesnesi simgeyi işlediğinde. Class View’i tıklayın. Code and Text Editor penceresinde IVisitableToken.cs dosyasını görüntüleyin. 4. visitor parametresi sırayla her simgeyi “ziyaret eder”. arabirimdeki tüm yöntemleri uygulamak zorunda olduğundan.) 6. IVisitableToken arabirimi Accept yöntemini kalıtımla alır ve her simge Accept yöntemini uygular.

} Not VisitIdentifier yöntemi. Arabirimleri sınıflardan ayırmak için kullanılan simgelere dikkat edin. . Bu ad alanındaki sınıflar ve arabirimler listelenir. visitor nesnesinin uygun gördüğü şekilde. (Gerçekte SourceFile. IVisitableToken arabiriminin genişlettiği arabirimler (IToken ve IVisitable).ToString()). Aşağıdaki alıştırmada. IdentifierToken sınıfını farenin sağ düğmesiyle tıklayın ve daha sonra. proje tarafından tanımlanan ad alanları. Aşağıdaki gibi. IVisitableToken arabirimini genişletin ve daha sonra Base Types düğümünü açın. Solution Explorer tarafından kullanılan pencerede görünür. 7. Tokenizer projesini genişletin ve daha sonra {} Tokenizer ad alanını açın. simgeleri belirli renklerle gösteren VisitIdentifier yönteminin uygulamasını sağlayacaksınız.) IdentifierToken sınıfı DefaultTokenImpl soyut sınıfından ve IVisitableToken arabiriminden kalıtımla alır.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 249 Class View penceresi. yönteme parametre olarak geçen simgeyi işler. Bu dosyadaki diğer simge sınıfları da aynı yolu izler. Bu pencere.VisitIdentifier(this. sınıflar ve arabirimleri görüntüler. şu şekilde görüntülenir: 8.Accept(ITokenVisitor visitor) { visitor. Class View penceresinde. Accept yöntemini uygular: void IVisitable.cs dosyasında yer almaktadır. Code and Text Editor penceresinde bu sınıfı görüntülemek için Go To Definition’ı tıklayın. Class View penceresinde.

} public void VisitKeyword(string token) { . MyVisitor visitor = new MyVisitor(). her simge türü için bir yöntem içerir. Örneğin: class MyVisitor : ITokenVisitor { public void VisitIdentifier(string token) { . Design View penceresinde Color Syntax formunu görüntülemek için. soyut sınıfların ve sınıfların hiyerarşisinin sonucu olarak.. ITokenVisitor arabiriminden ve onun uygulamalarından türeyen ve “ziyaret etme” tekniğini kullanarak renkli sözdizimi ile (örneğin..Accept(visitor).cs kaynak dosyasını görüntüler.. Solution Explorer’da. class Program { static void Main() { SourceFile source = new SourceFile(). ITokenVisitor arabirimi..250 Kısım II C# Dilini Anlamak 9.. Class View penceresinde. Bu hareket. ITokenVisitor arabirimini farenin sağ düğmesiyle tıklayın ve daha sonra Go To Definition’ı tıklayın. ColorSyntaxVisitor sınıfını yazın 1. source. anahtar sözcükleri mavi renkte) zengin metin kutusunda kaynak kodumuzdaki simgeleri görüntüleyen bir sınıf yaratacaksınız. bu sınıfın bir oluşumunu yaratabilir ve SourceFile nesnesinin Accept yöntemine parametre olarak bu oluşumu geçirebilirsiniz.xaml’ı çift tıklayın. Aşağıdaki alıştırmada. } } Main yöntemindeki kod. ITokenVisitor arabirimini uygulayan bir sınıf yaratabilir. . (Class View penceresinin altındaki Solution Explorer sekmesini tıklayın) Window1. } } .. kaynak dosyasındaki her simgenin visitor nesnesindeki izleme yöntemini çağırması ile sonuçlanır. Bu arabirimlerin. Code and Text Editor penceresinde ITokenVisitor.

3. openClick yöntemini bulun. basit biçimlendirilmemiş metinden çok biçimlendirilmiş içerik görüntüleyebilmesi dışında. SourceFile sınıfında gösterilen biçimde simgeleştirir. Bu form.Accept(visitor). 2. her simgeyi bir renkle gösteren ColorSyntaxVisitor nesnesidir. } SourceFile sınıfının Accept yönteminin tüm simgeler üzerinde yinelenerek. . kullanıcıyı metin dosyasının adını vermesi için uyarır ve daha sonra metin dosyasını gramer bakımından inceler ve Accept yöntemini çağırmadan önce. Not Geçerli uygulamada. sıradan metin kutusu gibidir. ziyaretçi. SourceFile sınıfında tanımlanmış simgelerin ColorSyntaxVisitor nesnesi kullanılarak zengin metin kutusunda görüntülenmesi için bu yöntemi uygulamak zorundasınız. Tümüyle işlevsel uygulamada. Open düğmesi sadece SourceFile sınıfında kodlanmış veriyi kullanır. Bu örnekte. openClick yöntemine aşağıda koyu harflerle gösterilen kodu ekleyin: private void openClick(object sender. formun kodunu görüntülemek için View Code’u tıklayın. Not Zengin metin kutusu. Formu farenin sağ düğmesiyle tıklayın ve sonra Code and Text Editor penceresinde.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 251 Çerçeveyi test etmek için bu formu kullanacaksınız. Kullanıcı Open düğmesini tıkladığında bu yöntem çağrılır. Open düğmesi. RoutedEventArgs e) { SourceFile source = new SourceFile(). ColorSyntaxVisitor visitor = new ColorSyntaxVisitor(codeText). simgeleştirilecek dosyayı açmak için bir düğme ve simgeleri görüntülemek için bir zengin metin kutusu içerir: Formun ortasındaki zengin metin kutusu codeText olarak ve düğme de Open olarak adlandırılmıştır. belirtilen ziyaretçiyi kullanarak her simgeyi işlediğini hatırlayın. source.

Length . Brushes. Code and Text Editor penceresinde ColorSyntaxVisitor.ContentEnd. Merak ediyorsanız. } Bu kod.ContentEnd. kodu renkli olarak görüntülemek için.) Bu kodun arabirimi açık olarak uyguladığına.Document. ContentEnd özelliğinin kolları olduklarından negatif değerlerdir. 6.Green ve diğer tüm yöntemler için de Brushes.VisitComment(string token) { Write(token. Göreviniz. ColorSyntaxVisitor sınıfı kısmen yazılmıştır. yeni eklenen simgeyi gösteren zengin metin kutusundaki metin parçasına başvuru sağlar. zengin metin kutusunda yeni simgenin nerede başladığını ve nerede bittiğini gösterir. (Bu konumların nasıl hesaplandığını düşünmeyin. aşağıdaki Write yöntemini ekleyin: private void Write(string token.GetPositionAtOffset(offsetToStartOfToken). ColorSyntaxVisitor sınıfına. TextRange text = new TextRange(start.ApplyPropertyValue(TextElement. int offsetToEndOfToken = -2. her yöntemi arabirim adı ile tanımladığına dikkat edin. ITokenVisitor arabirimini uygular ve simgeleri görüntülemek için kullanılan. TextPointer end = target.Document.VisitIdentifier(string token) { Write(token. target değişkeni tarafından tanımlanan her simgeyi belirtilen rengi kullanarak zengin metin kutusuna ekler. int offsetToStartOfToken = -1 * token.Blue. Brushes. } void ITokenVisitor.ForegroundProperty.cs dosyasını açın. bu metnin rengini ikinci parametrede belirtilen renge ayarlar. SolidColorBrush color) { target. ITokenVisitor arabiriminden kalıtımla alınan yöntemleri uygulamak ve ayrıca zengin metin kutusuna simgeleri yazacak olan bir yöntem yaratmaktır.Black).Media ad alanında tanımlanmış bir sınıftır.Windows. text. color).2. uygun renkle birlikte bu Write yöntemini çağıracaktır.AppendText(token). Anahtar sözcükler için Brushes.252 Kısım II C# Dilini Anlamak 4. başlangıç değeri olarak zengin metin kutusuna target adında bir başvuru atamak için bir kurucu ve iki alan içerir.GetPositionAtOffset(offsetToEndOfToken). Bu sınıf. Code and Text Editor penceresinde. Code and Text Editor penceresinde. TextPointer start = target. ApplyPropertyValue yöntemi. StringLiterals için Brushes. start ve end adındaki iki TextPointer değişkeni.) TextRange türü text değişkeni. end). void ITokenVisitor. System.Black olarak belirleyin. ColorSyntaxVisitor sınıfına ITokenVisitor arabirimini uygulayan aşağıdaki yöntemleri ekleyin. (Brushes. 5. ColorSyntaxVisitor sınıfındaki çeşitli “ziyaret” yöntemlerinin her biri.Black). } .

Brushes.VisitStringLiteral(string token) { Write(token.VisitPunctuator(string token) { Write(token.Black). burada gösterilen kod ile değiştirin. } void ITokenVisitor. Build menüsünde. Brushes. Bunun için. bir NotImplementedException özel durumu oluşturan bir ifade içerir. Kod parçası. Kısayol menüsünde.Black). Brushes.Green). anahtar sözcükler mavi ve dize hazır bilgileri yeşil olacak biçimde zengin metin kutusunda görüntülenir. } void ITokenVisitor. simge dizisindeki simgenin sınıf türüdür. Code and Text Editor penceresinde doğrudan yazabilirsiniz ya da her biri için varsayılan uygulama üretmek ve daha sonra da yöntem gövdesini uygun kod ile değiştirmek için Visual Studio 2008’i kullanabilirsiniz.VisitKeyword(string token) { Write(token. 9. İpucu Bu yöntemleri.Black). Brushes. Build Solution’ı tıklayın. Her yöntem. Start Without Debugging’i tıklayın.Blue).Accept yöntemini geçersiz kılan simgenin yöntemlerinden hangisinin çağrıldığını belirleyen. 7.VisitOperator(string token) { Write(token. Debug menüsünde. Hataları düzeltin ve gerekirse yeniden yapılandırın.VisitWhitespace(string token) { Write(token. sınıf tanımındaki ITokenVisitor tanımlayıcısını farenin sağ düğmesiyle tıklayın. } Token. } void ITokenVisitor. } void ITokenVisitor. .Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 253 void ITokenVisitor. Brushes. Formdaki Open düğmesini tıklayın. Color Syntax formu görünür. Implement Interface’i işaret edin ve Implement Interface Explicitly’ı tıklayın. Bu kodu. mühürlenmiş (sealed) ColorSyntaxVisitor : ITokenVisitor sınıfının. 8.

. Visual C# 2008 Express Edition’da yoktur. ayrıca bu bilgiyi çizimsel olarak gösteren sınıf çizimini oluşturmanızı sağlar. boş bir çizim oluşturur. Class View penceresinden sınıfları ayrı ayrı sürükleyerek ya da ait oldukları ad alanlarını sürükleyerek tüm mevcut sınıfların çizimini oluşturabilirsiniz. çizimi daha okunabilir hale getirmek için. Çizim. yeni türler yaratabilirsiniz. Project menüsünde Add New Item’ı tıklayın. Formu kapatın ve Visual Studio 2008’e dönün. Visual Studio 2008. Sınıfın içeriğini göstermek için her sınıfın tanımını genişletebilirsiniz. Bu işlem. özellikler ve diğer sınıf üyelerini tanımlamak için sınıf çizimini kullanabilirsiniz. yeni sınıflar ve arabirimler eklemek. Add New Item iletişim kutusunda.254 Kısım II C# Dilini Anlamak 10. yöntemler.) Not Bu özellik. Bir Sınıf Çizimi Üretmek Bir projedeki arabirimler ve sınıfların hiyerarşisini görüntülemek ve üzerinde hareket etmek için Class View penceresi kullanışlıdır. sınıflar ve arabirimler arasındaki ilişkileri gösterir. Class Diagram şablonunu seçin ve sonra da Add’i tıklayın. sınıflar ve birimleri sürükleyerek hareket ettirebilirsiniz. Toolbox’daki Class Designer kategorisinden öğeleri sürükleyerek. Yeni bir sınıf çizimi oluşturmak için. (Ayrıca. Bir sonraki sayfadaki resimde gösterildiği gibi.

Anahtar Sözcük abstract new override private protected public sealed virtual 1 Bir 2 Bir 3 Bir 4 Bir Arabirim hayır evet1 hayır hayır hayır hayır hayır hayır Soyut Sınıf evet evet evet evet evet evet evet evet Sınıf hayır evet evet evet evet evet evet evet Sealed sınıf hayır evet evet evet evet evet gerekli hayır Yapı hayır hayır2 hayır3 evet hayır4 evet hayır hayır arabirim başka bir arabirime yayılabilir ve aynı imzayla yeni bir yöntemi tanıtabilir. yapı. .Object’ten dolaylı olarak türeyebilir. sınıflar ve arabirimler yaratırken kullanılabilecek çeşitli geçerli (evet). yapının saklayabileceği yöntemleri içeren System. geçersiz (hayır) ve zorunlu (gerekli) anahtar sözcük bileşenlerini özetlemektedir. yapı. sanal yöntemleri içeren System.Object’ten dolaylı olarak türeyebilir. yapı dolaylı olarak mühürlüdür ve kendisinden türetilemez.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 255 Anahtar Sözcük Bileşimlerini Özetlemek Aşağıdaki tablo.

bir temel sınıf olarak kullanılabilecek bir soyut sınıf yaratmak abstract anahtar sözcüğünü kullanarak bir sınıf bildirin. n Bölüm 13 Hızlı Başvuru Bunun İçin Bir arabirim bildirmek Şunu Yapın interface anahtar sözcüğünü kullanın. Örneğin: interface IDemo { string Name().. Her soyut yöntem için. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Save iletişim kutusu görünürse. abstract anahtar sözcüğü ile.. } Temel sınıf olarak kullanılamayan bir mühürlenmiş sınıf yaratmak Sınıfı sealed anahtar sözcüğünü kullanarak bildirin... } .256 Kısım II n C# Dilini Anlamak Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 14’e geçin. Örneğin: class Test : IDemo { public string IDemo.Name() { . } Bir arabirim uygulamak Kalıtımdaki sözdiziminin aynısını kullanan bir sınıf bildirin ve sonra arabirimin tüm üye işlevlerini oluşturun.. string Description(). Örneğin: abstract class GrazingMammal { abstract void DigestGrass().. } public string IDemo. Örneğin: sealed class Horse { . yöntem gövdesi olmadan bir yöntem bildirin.. ..Description() { . } } Soyut yöntemler içeren.

bilinen bir zamanda bir kaynağı özel durum olmadan serbest bırakmak. using ifadesi yazarak. bir nesne yarattığınızda neler olduğunu tekrarlayalım. Bir yıkıcı kullanarak nesne sonlandırıldığında çalışacak kodu yazmak . new işleci kullanarak bir nesne yaratırsınız. new işlemi. bu nedenle bir değişken ya da bir nesne artık kullanılmadığında ayrılan bellek iade edilmelidir. öbekten ham bellek yığını ayırır. new işlemi atomik bir işlemdir fakat daha derine inildikçe.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n Çöp toplamayı kullanarak sistem kaynaklarını yönetmek . Veri türleri kapsam dışına çıktığında yok edilir ve bellekleri iade edilir. Microsoft . TextBox sınıfının yeni bir oluşumunu yaratır. Aşağıdaki örnek. ham bellek yığınını bir nesneye dönüştürür. Bu bir parça kolaydır. nesne yaratımı gerçekten iki aşamalı bir süreçtir: 1. try/finally ifadesi yazarak.) TextBox message = new TextBox(). (Değeri türleri yığın üzerinde ve başvuru türleri de öbekten alınan bellek üzerinde yaratılır. new işlemi. Nesne yaratımının bu aşaması üzerinde hiçbir denetiminiz yoktur. 257 .) Bilgisayarlar sonsuz belleğe sahip değildir. Bir Nesnenin Ömrü ve Ömür Uzunluğu İlk olarak. değişkenleri ve nesneleri nasıl yaratacağınızı gördünüz ve değişken ve nesneler yarattığınızda nasıl bellek ayrıldığını anlamış olmalısınız. Ya başvuru türleri? new anahtar sözcüğünü kullanarak bir nesne yaratırsınız. nesneye başlangıç değeri ataması gerekir. 2. Fakat bir nesne ne zaman ve nasıl ortadan kaldırılır? Bu bölüm tümüyle bununla ilgilidir. Bir kurucu kullanarak bu aşamayı denetleyebilirsiniz. // TextBox başvuru türüdür Sizin bakış açınızdan. bilinen bir zamanda bir kaynağı özel durum olmadan serbest bırakmak. (Bu sınıf.NET Framework içinde sağlanmıştır. n Önceki bölümlerde.

C#’ta silme işleminin olmadığına dikkat etmeliler. Çalışma zamanının daha önce nesneye ait olan belleği öbeğe geri döndürmesi gerekir. çöp toplama olarak bilinir. Nesnenin yok edilmesinin iki aşaması. Çalışma zamanının bazı bağlamaları yapması gerekir. Bir nesneyi yok etme ve bellek alanını öbeğe geri döndürme işlemi. Nesne yaratımı gibi. C#’ta yerleşimi denetlemek için new’in aşırı yüklenemeyeceğine dikkat etmelidir. diğer değişkenler (messageRef gibi) yine de var olabilir. Bir nesnenin ne zaman ortadan kaldırılacağını çalışma zamanı denetler. aşağıdaki gibi erişebileceğiniz. Bir yıkıcı yazmak için gerekli sözdizimi tilda (~) ve ardından sınıfın adının yazılması biçimindedir. Çalışma zamanının tüm bu başvuruları izlemesi gerekir. aşağıda.Text = “People of Earth. nesnenin içinde yaşadığı belleğin serbest bırakılması gerekir. nesne ölümü de iki aşamalı bir işlemdir. Bir nesne. biraz kurucuya benzeyen özel bir yöntemdir. 2. Yıkıcılar Yazmak Bir nesne için çöp toplandığında gerekli olan bağlama işlemlerini gerçekleştirmek için bir yıkıcı kullanabilirsiniz. Örneğin. Yıkıcı. TextBox sınıfı. . Bu aşamada bir denetime sahip değilsiniz. message değişkeni yok olursa (kapsam dışına çıkarsa). sadece tüm başvurular yok olduğunda ortadan kaldırılabilir ve belleği iade edilebilir. Bir yıkıcı yazarak bunu denetleyebilirsiniz.258 Kısım II C# Dilini Anlamak Not C++ programcıları. Bir nesneye kaç adet başvuru oluşturabilirsiniz? İstediğiniz kadar! Bu nesnenin ömrünü etkiler. your attention please”. Bir nesne yarattıktan sonra.) kullanarak nesnenin üyelerine erişebilirsiniz. yaratılmasının iki aşamasını tam olarak yansıtmaktadır: 1. nokta işleci (. belirli bir başvuru değişkenine bağlı olamaz. Farklı olarak çalışma zamanı nesneye son başvuru da yok olduktan sonra yıkıcıyı çağırır. Diğer başvuru değişkenlerinin aynı nesneye başvurmasını sağlayabilirsiniz: TextBox messageRef = message. Text adında bir üye içerir: message. Örneğin. Not C++ program geliştiricileri. Bir nesnenin ömrü.

kendinizin bir yıkıcı çağırmayacağınızdır. } Yıkıcılar için bazı çok önemli kısıtlamalar vardır: n Yıkıcılar sadece başvuru türlerine uygulanır. Kendi kodunuzda asla bir yıkıcı çağırmazsınız (çöp toplama olarak adlandırılan çalışma zamanı parçası bunu sizin için yapar).instanceCount++. } .. } public static int InstanceCount() { return this... public ~Tally() { ... Diğer bir deyişle derleyici aşağıdaki yıkıcıyı: class Tally { ~Tally() { . } ~Tally() { this. private static int instanceCount = 0. } // derleme zamanı hatası n Bir yıkıcıyı hiçbir zaman parametrelerle bildiremezsiniz ve yıkıcı bir parametre alamaz.instanceCount.instanceCount--.. Bunun nedeni de.. otomatik olarak bir yıkıcıyı Object... ~Tally(int parameter) { . Bir struct gibi veri türlerinde bir yıkıcı bildiremezsiniz. } // derleme zamanı hatası Derleyici. } } .Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 259 kurucudaki statik değişkenin değerini artırarak ve yıkıcıdaki aynı statik değişkenin değerini azaltarak mevcut oluşumların sayısını hesaplayan basit bir sınıf görebilirsiniz: class Tally { public Tally() { this.. } // derleme zamanı hatası } n Bir yıkıcı için bir erişim değiştiricisi (public gibi) belirtemezsiniz. struct Tally { ~Tally() { .Finalize yönteminin geçersiz kılma biçimine dönüştürür.

er ya da geç aşağıdaki durumlar meydana gelecekti: n Bir nesneyi yok etmeyi unutacaktınız. Bu. ya kullanılmayan belleğe ya da aynı bellek alanındaki tamamıyla farklı bir nesneye başvurur.) Bu. C# tasarımcılarının nesneleri yok etmek için kod yazılmasını yasaklamaya karar vermelerinin çok açık nedenleri vardır. Nesnelerin yok edilmesi için sizin yerinize çöp toplayıcı sorumludur. yıkıcı gövdesini bir try bloğunda içerir. tam olarak sadece bir defa yok edilecektir. bir yıkıcının her zaman temel sınıf yıkıcısını çağırmasını sağlar.Finalize(). Kendiniz Finalize yöntemini geçersiz kılamazsınız ve çağıramazsınız. Her iki durumda da böyle sallantıda olan bir başvuruyu kullanmak tanımsız olur. Aynı nesneyi birden çok kez yok etmeye çalışacaktınız. n n Bu problemler. } finally { base. Kolayca belleği doldurabilirdiniz. Çöp toplayıcı şunları garanti eder: n Her nesnenin yıkıcısı çalışacak ve her nesne yok edilecektir. nesne yıkıcısının (varsa) çalışmayacağı ve bu belleğin yığına yeniden verilmeyeceği anlamına gelir. Bu.. tasarım amaçlarında sağlamlığı ve güvenliği en üst sırada tutan C# gibi bir programlama dilinde kabul edilemez. n . bu sallantıda bir başvuru olacaktı. Her nesne. Sallantıdaki bir başvuru. nesnelere başvurular yoluyla erişilir. (try ve finally anahtar sözcükleri “Hataları ve Özel Durumları Yönetmek” başlıklı Bölüm 6’da anlatılmıştır. Sadece derleyicinin bu dönüşümü yapabileceğini anlamak önemlidir. Bunun için bir sözdizimi olmadığı gibi. Etkin bir nesneyi yok etmeye çalışacaktınız. Neden Çöp Toplayıcı Kullanılır? C# kodu kullanarak hiçbir zaman bir nesneyi kendi kendinize yok edemeyeceğinizi anlamış olmalısınız. Hatırlayın. Program sonlandığında bütün etkin nesneler yok edilecektir. Bir sınıf yok edilmiş bir nesneye başvuruyu tutarsa. bunu temel sınıftaki Finalize yöntemini çağıran finally bloğu izler.260 Kısım II C# Dilini Anlamak şuna çevirir: class Tally { protected override void Finalize() { try { . yıkıcıdaki koda bağlı olarak bir felaket olabilir. Nesneleri yok etmek sizin sorumluluğunuzda olsaydı. } } } Derleyicinin oluşturduğu Finalize yöntemi..

Bölüm 14 n Çöp Toplama ve Kaynak Yönetimini Kullanmak 261 Her nesne. Bu grafikte bulunmayan bütün nesnelerin erişilmez olduğu varsayılır. yani ona başvuran tüm başvurular ortadan kalktığında yok edilecektir. Bununla birlikte. bir nesne daha fazla gerekli olmadığında çöp toplama meydana gelir. bunu nesneler kullanılırken yapamaz. Fakat hemen meydana gelmesi şart değildir. Bu garantiler büyük ölçüde yararlıdır ve sizi.Collect yöntemi çöp toplamayı başlatır fakat işlem eşzamanlı olarak çalışmaz ve yöntem çağrısı tamamlandığında. yineleyen biçimde nesnelerin içindeki başvuru alanlarını izleyerek yapar.Collect statik yöntemini çağırarak çöp toplamayı başlatabilirsiniz. Çöp toplayıcı çalıştığında aşağıdaki adımları gerçekleştirir: 1. System. 2. Birkaç büyük bellek çöpü toplamak. Programın mantığına odaklanmanızı ve daha üretken olmanızı sağlar. Bunun nedeni. çok sayıda küçük bellek çöpü kırıntısı toplamaktan daha verimlidir! Not Bir programda.GC. Anlaşılması gereken son şey en önemlisidir: yıkıcılar. çalıştırılacağını bilirsiniz fakat ne zaman çalışacağını bilemezsiniz. çöp toplayıcının nesneleri hareket ettirmesinin ve nesne başvurularını güncellemesinin gerekebilmesidir. hala nesnelerinizin yok edilip edilmediğini bilemezsiniz. Bütün erişilebilir nesnelerin bir grafiğini oluşturur. freachable queue (F-reachable olarak okunur) olarak adlandırılan bir sıraya konur. Sonuçta. Çöp toplama ne zaman meydana gelir? Bu tuhaf bir soru gibi gelebilir. Çöp toplayıcı çalışırken. elbette. bu önerilmez. System.GC. programcıyı. sadece nesne erişilemez olduğunda. Erişilmez olan nesnelerden herhangi birinin bir yıkıcıya sahip olup olmadığını denetler (sonlandırma olarak adlandırılan işlem) Sonlandırılması gereken erişilemez nesneler. Bir yıkıcı yazdıysanız. Bunu. nesneler için çöp toplanana kadar çalışmaz. . uygulamanız bir yöntemin sonuna ulaştığında). uygulamanızda çalışan diğer temalar geçici olarak durur. sıkıcı düzenleme işlerinden ve kolayca hata yapma olasılığından kurtarır. Çöp Toplayıcı Nasıl Çalışır? Çöp toplayıcı kendi temasında (thread) çalışır ve sadece belirli zamanlarda uygulanır (tipik olarak. bu nedenle çalışma zamanı sadece gerektiğinde (kullanılabilir bellek yetersiz olmaya başladığında) ve mümkün olduğunca çok çöp toplar. birkaç durum dışında. Çöp toplayıcı bu grafiği çok dikkatli biçimde oluşturur ve dairesel başvuruların sonsuz döngüye girmediğini garantiler. Ne zaman çöp toplanacağına en iyisi çalışma zamanı karar versin! Çöp toplamanın bir özelliği de şudur: Nesnelerin hangi sırayla yok edileceğini bilemezsiniz ve bu sıralamaya güvenmemelisiniz. Çöp toplama masraflı bir süreç olabilir.

bazı kaynaklar çöp toplayıcı gerçekten onları serbest bırakana kadar isteğe bağlı bir süre serbest bırakılmamış olarak kalmalarını gerektirecek kadar değerlidir ve az bulunur. Öneriler Yıkıcı içeren sınıflar yazmak. Not Yok etme yöntemi terimi. Bu nedenle. Sonlandırılması gereken erişilmez nesneler (şu anda freachable queue’de olanlar) kendi temaları tarafından sonlandırılır. yıkıcıların bir diğerine bağlı olmadığından ya da bir diğer yıkıcı ile çakışmadığından emin olun. çok dikkatli yazmalısınız. tek seçeneğiniz kaynağı sizin serbest bırakmanızdır. sonlandırmanın sırası belirsizdir. Açıkçası.262 Kısım II C# Dilini Anlamak 3. Bu tür durumlarda. . kodunuzun ve çöp toplama işinin karmaşıklığını artırır ve programınızın çalışmasını yavaşlatır. Bir yok etme yöntemi yaratarak bunu sağlayabilirsiniz. 5. Bu nedenle. bir yöntem adı olmaktan çok yöntemin amacını gösterir. Özellikle.) Kaynak Yönetimi Bazen bir yıkıcıda bir kaynağı serbest bırakmak önerilmez. Programınız hiç yıkıcı içermezse. bir kaynağı açık olarak yok etme yöntemidir. Çöp toplayıcı bu iade işlemini erişilebilir nesneleri öbekte aşağıya taşıyarak ve böylece öbeği birleştirip en üstteki belleği boşaltarak gerçekleştirir. Unutmayın. Az bulunur kaynakların serbest bırakılmaları ve bunun mümkün olan en kısa sürede yapılması gerekir. yıkıcınız. Geri kalan erişilemez nesnelerin (sonlandırılması gerekmeyenler) bellek alanı iade edilir. Örneğin. (Örneğin. aynı kaynağı serbest bırakmaya çalışan iki yıkıcıya sahip olmayın. Bir sınıf bir yok etme yöntemine sahipse. bunun yerine using ifadesi kullanın. bu yöntemi çağırarak kaynağın ne zaman serbest bırakılacağını denetleyebilirsiniz. çöp toplayıcının erişilmez nesneleri freachable queue sırasına yerleştirmesine ve onları sonlandırmasına gerek yoktur. 4. o nesneye yapılan bütün başvuruları da güncelleştirir. bir şeyi yapmamak yapmaktan daha hızlıdır. (Bu bölümdeki “using İfadesi” başlığına bakın.) Bir yıkıcı yazarsanız. Bir yok etme yöntemi herhangi geçerli bir C# tanımlayıcısı kullanılarak adlandırılabilir. gerçekten gerekmedikçe yıkıcılar kullanmaktan kaçınmaya çalışın. Çöp toplayıcı erişilebilir bir nesneyi taşıdığında. yıkıcıları çöp toplayıcı tarafından zaten çağrılmış olabilecek olan diğer nesneleri çağırıp çağırmadığının farkında olmalısınız. Bir yok etme yöntemi. Çöp toplayıcı şimdi diğer temaların kaldıkları yerden devam etmelerine izin verir.

ReadLine ya da WriteLine çağrılması bir özel durum oluşturursa. System. try { string line. while ((line = reader. Bu sınıf. Özel Durum-Güvenli Yok Etme Bir yok etme yönteminin (Close gibi). StreamReader sınıfını kullanarak bir dosyadaki metnin satırlarını okuyan ve daha sonra ekranda görüntüleyen örnek aşağıdadır: TextReader reader = new StreamReader(filename).ReadLine()) != null) { Console. dosya işlemeyi bitiremez ve başka dosya açamazsınız.IO ad alanının TextReader sınıfıdır. Bununla birlikte. } .WriteLine(line). art arda girilen karakterleri okumak için bir teknik sağlar. ReadLine yöntemi metnin bir sonraki satırını bir dize olarak okur. reader ile işiniz bittiğinde. TextReader sınıfı.WriteLine(line). dosya işleme ve ilgili kaynakları serbest bırakmak için önemlidir. karakter akışını sonlandıran. } reader. while ((line = reader. string line. Close yöntemi çağrılmayacaktır. yok etme yöntemini bir finally bloğu içinde çağırmaktır.Close().Close(). Akışta başka bir şey kalmamışsa. bu örnekle ilgili bir sorun vardır: özel durum-güvenli değildir. özel durum olsa da olmasa da her zaman çağrıldığından emin olmanın yolu. Bu durum sık meydana gelirse. Close yöntemini çağırmak. } } finally { reader. ReadLine yöntemi null döndürür. Close adında bir sanal yöntem içerir.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 263 Yok Etme Yöntemleri Bir yok etme yöntemine sahip sınıfa örnek. Bir önceki örneğin bu yöntemi kullanan biçimi aşağıdaki gibidir: TextReader reader = new StreamReader(filename).ReadLine()) != null) { Console. StreamReader sınıfı (bir açık dosya gibi bir akıştan karakterleri okur) ve StringReader sınıfının (bir dizeden karakterleri okur) her ikisi de TextReader sınıfından türer ve her ikisi de Close yöntemini geçersiz kılar.

işe yarar fakat onun ideal çözüm olmasına engel olan bazı kötü yanları vardır: n Birden çok kaynağı bırakacaksanız hızla hantallaşır (iç içe geçmiş birçok try ve finally bloğu ile uğraşırsınız. n n n using ifadesi tüm bu sorunları çözmek için tasarlanmıştır.) Bazı durumlarda. kodu değiştirmeniz gerekir. Bunun anlamı. using İfadesi using ifadesi. while ((line = reader. Bir nesne yaratabilirsiniz ve bu nesne using ifadesi bittiğinde yok edilir.WriteLine(line).264 Kısım II C# Dilini Anlamak Bu biçimde bir finally bloğu kullanmak. çözümün anlaşılmasının zor olduğu ve gerekli olduğunda her seferinde yinelenmesi gerektiğidir. Önemli Bu bölümde gösterilen using ifadesini kapsama bir ad alanı getiren using yönergesi ile karıştırmayın. Bunun anlamı. kaynak başvurularının bildirimlerinin sırasını değiştirmeniz gerekebilir. aynı anahtar sözcük iki farklı anlam taşımaktadır.) Çözümün bir sanalını yaratamazsınız. using ifadesinin sözdizimi aşağıdaki gibidir: using ( type variable = initialization ) { StatementBlock } Kodunuzun her zaman bir TextReader üzerinde Close yöntemini çağırdığından emin olmanın en iyi yolu şudur: using (TextReader reader = new StreamReader(filename)) { string line. Ne yazık ki.ReadLine()) != null) { Console. kaynakların ömrünü denetlemek için açık bir teknik sağlar. } } . (Örneğin. başvuruyu null olarak başlatmayı unutmayın ve başvurunun finally bloğunda null olmadığından emin olun. Kaynağa yapılan başvuru finally bloğundan sonra da kapsam içinde kalır. serbest bırakıldıktan sonra bir kaynağı kazayla kullanabileceğinizdir.

. using ifadesinde bildirdiğiniz değişken. Bu düzenleme.WriteLine(line). } } StreamReader sınıfının IDisposable arabirimini uygulaması ve akışı bitirmek için Dispose yönteminin Close’u çağırması olan bir durumdur.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 265 Bu using ifadesi. try { string line. Program kodunun mantığını bozmaz. IDisposable arabirimini uygulayan türde olmak zorundadır. gömülü ifadenin sonunda otomatik olarak kapsam dışına çıkması ve yok edilen kaynağa kazara erişemeyeceğiniz anlamına gelir. using ifadesi içinde bildirilen değişkeni (bu örnekte reader değişkeni) using ifadesi sonlandıktan sonra kullanamazsınız.ReadLine()) != null) { Console. IDisposable arabirimi System ad alanında bulunur ve yalnızca Dispose yöntemini içerir: namespace System { interface IDisposable { void Dispose(). Artık aşağıdaki özelliklere sahip bir çözümünüz var: n n n n Birden çok kaynağı yok etmeniz gerektiğinde kolayca ölçeklenebilir. tam olarak aşağıdaki çeviriye denktir: { TextReader reader = new StreamReader(filename).Dispose(). } } } Not using ifadesi. Güçlüdür. Bir kaynağın her zaman serbest bırakıldığından emin olmak için açık. } } finally { if (reader != null) { ((IDisposable)reader). Bu yaklaşım. try/finally çözümündeki tüm sorunları çözer. kapsam amaçları için kendi bloğunu sağlar. özel durum-güvenli ve güçlü bir yol olarak using ifadesini kullanabilirsiniz. while ((line = reader. Sorunu soyutlar ve yinelemeden kaçınır. çünkü artık kapsam içinde değildir (derleme zamanı hatası alırsınız). using ifadesinde bildirdiğiniz değişkenin.

Dispose yöntemini yıkıcıdan çağırarak her zaman çağrılacağından emin olabilirsiniz. } } } public void SomeBehavior() // örnek yöntem { checkIfDisposed().disposed) { throw new ObjectDisposedException(“Example: object has been disposed”). private bool disposed = false. bir yıkıcı yazmalı mısınız ya da IDisposable yöntemini mi uygulamalısınız? Bir yıkıcıya yapılan çağrı gerçekleşecektir fakat ne zaman gerçekleşeceğini bilemezsiniz. ~Example() { Dispose().. GC.. } .... Bununla birlikte.266 Kısım II C# Dilini Anlamak Bir Yıkıcıdan Dispose Yöntemini Çağırmak Bir sınıf yazarken. çünkü programcının bir using ifadesi yazmayı unutmamasına bağlıdır. Diğer taraftan. Dispose yöntemini çağırmayı unutabilirsiniz fakat en azından program kapatılırken bile olsa. Bu. } . . Bunu nasıl yapabileceğinizi gösteren bir örnek aşağıdadır: class Example : IDisposable { . private void checkIfDisposed() { if (this. } } private Resource scarce. çağrılacağından emin olabilirsiniz.SuppressFinalize(this). } public virtual void Dispose() { if (!this. Dispose yöntemine yapılan çağrının ne zaman gerçekleşeceğini tam olarak bilirsiniz fakat gerçekten gerçekleşeceğinden emin olamazsınız.disposed) { try { // kıt kaynağı burada serbest bırak } finally { this. yararlı bir “yedek” gibi çalışır..disposed = true.

bir özel durum oluşturur. metin dosyasını kapatmak için yapılan çağrı atlanır. nesnenin yok edilip edilmediğini denetler.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 267 Example sınıfının aşağıdaki özelliklerine dikkat edin: n n n n Sınıf IDisposable arabirimini uygular. Yok edildiyse. Dispose yöntemi ortaktır ve herhangi bir zamanda çağrılabilir. Bununla birlikte. Kod. Dispose yöntemi statik GC. Form üzerinde Open File’ı tıklayın. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 14\UsingStatement\UsingStatement klasörüne gidin ve Window1. Yıkıcı Dispose yöntemini çağırır. Az bulunur bir kaynak. 4. 2. bir parça kodu özel durum güvenli yapmak için yeniden yazacaksınız. Bir using ifadesi yazın 1. uygulama için kaynak dosyadır. Open iletişim kutusunda. Sınıfın (SomeBehavior gibi) tüm normal yöntemleri. Bir Windows Presentation Foundation (WPF) formu açılır. sadece yöntem ilk çağrıldığında serbest bırakılır. Bir using ifadesi kullanarak kodu yeniden yazacak ve böylece kodu özel durumlardan arındıracaksınız. 3. Dispose yöntemi güvenli bir biçimde birden çok kez çağrılabilir. bir metin dosyasını açar. Microsoft Visual Studio 2008’i açın. çöp toplayıcının bu nesne üzerinde yıkıcı çağırmasını engeller. bir defada bir satır olacak biçimde okur. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 14\ UsingStatement klasöründe yer alan UsingStatement projesini açın. 5. çünkü nesne henüz sonlandırılmıştır. Bu. bu satırları ekranda bir metin kutusuna yazar ve daha sonra metin dosyasını kapatır. disposed değişkeni yöntemin zaten çalışıp çalışmadığını gösterir. cs kaynak dosyasını seçin. n n Kodu Özel Durum-Güvenli Yapmak Aşağıdaki alıştırmada.SuppressFinalize yöntemini çağırır. Debug menüsünde Start Without Debugging’i tıklayın. dosya okunurken ya da satırlar metin kutusuna yazılırken bir özel durum oluşursa. Bu yöntem.xaml. .

Code and Text Editor penceresinde Window1.Text = src. TextReader reader = new StreamReader(fullPathname). System.Close(). Yöntem şu şekilde görünmelidir: private void openFileDialogFileOk(object sender. source. aşağıdaki gibi form üzerinde gösterilir: 7. string line. FileInfo src = new FileInfo(fullPathname). 8. Open’ı tıklayın. } .Text += line + “\n”. while ((line = reader.ComponentModel. Dosya içeriği. } reader. Visual Studio 2008’e dönmek için formu kapatın.ReadLine()) != null) { source.FileName.xaml.Name.CancelEventArgs e) { string fullPathname = openFileDialog.268 Kısım II C# Dilini Anlamak 6. fileName.cs dosyasını açın ve daha sonra openFileDialogFileOk yöntemini bulun.Clear().

private void openFileDialogFileOk(object sender. FileInfo src = new FileInfo(fullPathname).CancelEventArgs e) { string fullPathname = openFileDialog. TextReader nesnesini kapatan ifadeyi kaldırın.FileName. 11. Uygulamanın önceki gibi çalıştığından emin olun ve daha sonra formu kapatın. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Debug menüsünde Start Without Debugging’i tıklayın.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 269 fileName. reader. openFileDialog ve source değişkenleri Window1 sınıfının üç özel alanıdır. System. } } } using ifadesi tamamlandığında.Name. using (TextReader reader = new StreamReader(fullPathname)) { string line. while ((line = reader.Text += line + “\n”. Bu. 9. using ifadesinin doğal olarak bitmesini ya da özel durum nedeniyle sonlanmasını sağlar.Close çağrısına gerek yoktur.Text = src.ReadLine()) != null) { source. Dosyanın açılmasından sonra bir özel durum oluşursa.Clear(). reader. StreamReader sınıfının Dispose yöntemi tarafından otomatik olarak çağrılacağından. Save iletişim kutusu görünürse. 10. openFileDialogFileOk yöntemini değiştirin ve dosyayı işleyen kodu bir using ifadesi içine yerleştirin.Close’a yapılan çağrının gerçekleşeceğinin kesin olmamasıdır.ComponentModel. source. Bu koddaki sorun. Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 14’e geçin. fileName. . n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. yöntem sonlanacak fakat dosya uygulama bitene kadar açık kalacaktır.

} } Bir yıkıcı çağırmak Çöp toplayıcıyı zorlamak (önerilmez) Bir kaynağı bilinen bir zamanda bırakmak (özel durum uygulamayı keserse.Close().. } } class Example { void Use() { TextReader reader = .GC. System. bellek kaybetme riskini göze alarak) Bir yıkıcı çağıramazsınız. Örneğin: class TextReader { . Sadece çöp toplayıcı bir yıkıcı çağırabilir...Collect’i çağırın.. Bir yok etme yöntemi (bir kaynağı yok eden bir yöntem) yazın ve onu programda çağırın... Örneğin: class Example { ~Example() { . // okuyucuyu kullan reader. } } .. Yöntem.. değiştiriciye (public gibi) erişememelidir ve parametresi olmamalıdır ya da bir değer döndürmemelidir.. public virtual void Close() { .270 Kısım II C# Dilini Anlamak Bölüm 14 Hızlı Başvuru Bunun İçin Bir yıkıcı yazmak Şunu Yapın Adı sınıfın adıyla aynı olan ve (~) ile başlayan bir yöntem yazın.

.) { // okuyucuyu kullan } } } ....Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 271 Bir kaynağı bilinen bir zamanda özel durum güvenli olarak bırakmak (önerilen yaklaşım) Kaynağı bir using ifadesi ile serbest bırakın. Örneğin: class TextReader : { . } } IDisposable void Dispose() çağır void Close() class Example { void Use() { using (TextReader reader = ... public virtual { // Close’u } public virtual { .

.

. . . İşleç Aşırı Yüklemesi . . . . . . . . . . . . . . . . . . . . . . . Dizinleyicileri Kullanmak . . . . . . . . . . . . . . . . . Alanlara Erişmek İçin Özellikler Uygulamak . . . Bölüm 16 . . . . Bölüm 19 . . . . 275 295 311 333 355 371 395 Kısım III 273 . . . . . . . . . . . . . . . . . . . . . . . . . . . . Program Akışını Kesmek ve Olayları İşlemek . . . . . . . . . . . . . . . . . . . . Generics’e Giriş . . . . . . . . . Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak . . . . . Bölüm 20 . . . Bölüm 17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Koleksiyonları Numaralandırmak . . . . . . . Bölüm 18 . . . . . . . . . . .Adım Adım Microsoft Visual C# 2008 Bileşenler Yaratmak Bu kısımdaki konular: Bölüm 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . Bölüm 21 . . . . . . . . . . .

.

set erişimcileri bildirerek özelliklere yazma erişimini denetlemek. bu yolla bir alana erişim için sözdizimi doğal değildir. C# nesnelerinin ömrünü anlamış olmalısınız. Bu bölümde. Özellikler bu uygunsuzluğu gidermek için tasarlanmıştır. get erişimcileri bildirerek özelliklere okuma erişimini denetlemek. Yapılar ve sınıflar kullanarak. özellikler içeren arabirimler uygulamak. bu nedenle bir alanda (sonuç olarak. “Bileşenler Yaratmak” başlıklı Kısım III’te. Ayrıca. bir sınıftaki alanları gizlemek için özellikleri nasıl tanımlayacağınız ve kullanacağınız ele alınacaktır. bölümler. Otomatik olarak alan tanımlarına dayalı özellikler üretmek. Bu yaklaşım. bir değişken) aynı etkiye erişmek için bir yöntem çağırmak biraz acemiliktir. numaralandırmalar ve sınıflar kullanarak yeni türleri C# dilinde nasıl oluşturacağınız gösterildi. normal olarak bir atama ifadesi kullanırsınız. bu bilgi üzerine oluşturuldu. bir program çalıştığında. alanlara güvenli ve kontrollü bir erişim sağlar ve izin verilen değerlere ilişkin ek mantık ve kuralları kapsüllemenizi sağlar. Özellikler bildiren arabirimler yaratmak. Bu kitabın ilk iki kısmında C# dilinin temel sözdizimi sunuldu ve yapılar. Bir değişken okumak ya da yazmak istediğinizde.Bölüm 15 Alanlara Erişmek İçin Özellikler Uygulamak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n n n Özellikleri kullanarak mantıksal alanları kapsüllemek. Önceki bölümlerde. Bununla birlikte. bir sınıf içindeki alanları özel yapmanız ve bu alanlardaki değerleri saklamak ve yeniden elde etmek için yöntemler sağlamanız gerektiği vurgulanmıştır. Nesneleri başlatmak için özellikler kullanmak. çalışma zamanının değişkenler ve nesneler tarafından kullanılan belleği nasıl yönettiğini gördünüz. 275 .

origin.276 Kısım III Bileşenler Yaratmak Yöntemleri Kullanarak Kapsülleme Uygulamak İlk olarak. Örneğin. public int Y. } public int X. alanları gizlemek için yöntemleri kullanmayı özetleyelim. ScreenPosition kurucu aralığı parametrelerini denetler fakat böyle bir denetim ortak alanlara “ham” erişim üzerine yapılamaz. } return x..Y = -100. yani. x-koordinatı için geçerli aralığın 0 ile 1280 arasında olduğunu ve y-koordinatı için de geçerli aralığın 0 ile 1024 arasında olduğunu varsayın: struct ScreenPosition { public ScreenPosition(int x. } return y. private static int rangeCheckedX(int x) { if (x < 0 || x > 1280) { throw new ArgumentOutOfRangeException(“X”). kapsüllemenin altın kuralına uymamasıdır. Er ya da geç (büyük olasılıkla hemen). programlama hatası sonucu olarak. // oops . int xpos = origin. 0). Bilgisayar ekranındaki bir noktayı x ve y koordinatları olarak gösteren aşağıdaki yapıyı düşünün. X ya da Y aralığının dışına düşecektir: ScreenPosition origin = new ScreenPosition(0..X. . this.X = rangeCheckedX(x). verisi özel (private) değildir. } } Bu yapı ile ilgili bir problem. int y) { this. Ortak (public) veri kötü bir fikirdir çünkü kullanımı denetlenmez. } private static int rangeCheckedY(int y) { if (y < 0 || y > 1024) { throw new ArgumentOutOfRangeException(“Y”).Y = rangeCheckedY(y).

Bunu X alanı ortak olduğunda kullanılan denk kodla karşılaştırın: origin. ortak (public) alanları kullanmak kapsüllemeyi kırar. Bunu yapmak için.x.x = rangeCheckedX(newX). int xpos = origin.. bu durumda alanları kullanmak daha kısa. } public void SetX(int newX) { this.. alanları özel yapmak ve her özel alanın değerini sırasıyla okumak ve yazmak için bir değiştirici yöntem ve bir erişimci yöntemi eklemektir. Aşağıdaki örnek. Hiç şüphe yok ki.. Ne yazık ki.. Değiştirici yöntemler daha sonra yeni alan değerlerinde aralık denetimi yapabilirler. Bununla birlikte. } private int x.SetX(xpos + 10). aşağıdaki kod X alanı için bir erişimci (GetX) ve bir değiştirici (SetX) içerir.. bu değerli garanti için ödenmesi gereken bir bedel vardır (ScreenPosition artık doğal bir alan benzeri sözdizimine sahip değildir. private static int rangeCheckedX(int x) { . daha açık ve daha kolaydır. X ’ in değerini 10 artırır.Bölüm 15 Alanlara Erişmek İçin Özellikler Uygulamak 277 Bu problemi çözmek için yaygın yöntem. GetX erişimci yöntemini kullanarak X ’ in değerini okumak ve SetX değiştirici yöntemini kullanarak X ’ in değerini yazmak zorundadır.. y. origin. } Kod artık aralık kısıtlamalarını başarıyla uygular. bu da iyidir. Örneğin.GetX(). . public int GetX() { return this. struct ScreenPosition { .. SetX ’ in parametre değerini nasıl denetlediğine dikkat edin. her iki örneğin iyi yönlerini birleştirmenizi sağlar: alan benzeri sözdizimine izin verirken.X += 10.. Özellikler. } private static int rangeCheckedY(int y) { . kapsüllemeyi de sürdürmek. bunun yerine artık yöntem temelli sözdizimine sahiptir). } .

derleyici otomatik olarak bu alan benzeri sözdizimini erişimci yöntemlere çağrıya dönüştürür. bir alan gibi görünür fakat bir yöntem gibi çalışır. Sonraki kod örneği. standart Microsoft Visual C# public/private (ortak/özel) adlandırma geleneklerini izler. get ve set erişimciler tarafından okunan ve yazılan verinin türünü belirler. value adında tümleşik. Bir özellik bildirimi aşağıdaki gibi görünür: AccessModifier Type PropertyName { get { // erişimci kodu oku } set { // erişimci kodu yaz } } Bir özellik. Bununla birlikte. Bu kodu okurken şunlara dikkat edin: n n n Küçük harfte x ve y private alanlardır. this. get ve set anahtar sözcükleri ile başlayan iki kod bloğu içerebilir. ScreenPosition yapısının özellikler kullanılarak yazılmış biçimini gösterir. private alanlar ve özellikler küçük harfle başlamalıdır.x = rangeCheckedX(X).278 Kısım III Bileşenler Yaratmak Özellikler Nelerdir? Bir özellik (property). } . özellik okunduğunda uygulanan ifadeler içerir. mantıksal bir alanla fiziksel bir yöntem arasındaki geçiştir. Büyük harfte X ve Y public alanlardır. struct ScreenPosition { public ScreenPosition(int X. İpucu Alanlar ve özellikler. set bloğu da özellik yazıldığında çalışan ifadeler içerir. int Y) { this. gizli bir parametre kullanarak yazılan veriyi geçirir. Public alanlar ve özellikler büyük harfle. get bloğu. Tüm set erişimcileri.y = rangeCheckedY(Y). Özellik türü.

origin. y. } Alanlara Erişmek İçin Özellikler Uygulamak 279 Bu örnekte. Böyle bir değer kolayca hesaplanabilir ve bu durumda da fiziksel bir alana gereksinim yoktur. Aşağıdaki örnek bir ScreenPosition yapısının X ve Y özelliklerindeki değerleri okumayı gösterir: ScreenPosition origin = new ScreenPosition(0. Not Bu bölümdeki örnekler bir yapı için özellik tanımlamayı gösterse de bunlar aynen sınıflara da uygulanabilir. } private static int rangeCheckedY(int y) { . bir private alan doğrudan her bir özelliği geliştirir. int xpos = origin. Gereken tek şey bir get erişimcisinin bir değeri belirtilen türde döndürmesidir..Set’i çağır Daha önce açıklandığı gibi. Özellikleri Kullanmak Bir özelliği bir deyimde kullandığınızda onu ya bir okuma bağlamında (değerini değiştirmediğiniz durumlar) ya da bir yazma bağlamında (değerini değiştirdiğiniz durumlar) kullanırsınız..y = rangeCheckedY(value). } set { this. } } public int Y { get { return this. sözdizimi aynıdır. atanan değerler value değişkeni kullanılarak set erişimcilerine geçirilir. 0).x = rangeCheckedX(value).Y.Y. Benzer biçimde.. // origin. derleyici alan benzeri kodunuzu otomatik olarak o özelliğin set erişimcisine yapılan bir çağrıya dönüştürür: origin.x.set’i çağır // değeri 100’e ayarlayarak origin.get’i çağır Özellik ve alanlara aynı sözdizimini kullanarak eriştiğinize dikkat edin. // origin.Y.X. Bir özelliği okuma bağlamında kullandığınızda derleyici alan benzeri kodunuzu otomatik olarak o özelliğin get erişimcisine yapılan bir çağrıya dönüştürür. } } private static int rangeCheckedX(int x) { . // değeri 40’a ayarlayarak origin. bir özelliği yazma bağlamında kullanıyorsanız.y. Çalışma zamanı bunu otomatik olarak yapar.get’i çağır int ypos = origin.X = 40. .. } set { this. Bu bir özellik geliştirmenin yollarından yalnızca biridir.Bölüm 15 public int X { get { return this.Y = 100. } private int x.X.X.

Örneğin. Statik özelliklere. aşağıda ScreenPosition yapısının X özelliğinin salt yazılır bir özellik olarak bildirilmiş biçimini görebilirsiniz: struct ScreenPosition { .X += 10. yalnızca set erişimcisi olan bir özellik bildirebilirsiniz. Örneğin: origin.X = 140. özelliği yalnızca yazma bağlamında kullanabilirsiniz. } } } . derleyici aşağıdaki gibi ifadeleri otomatik olarak get ve set erişimcilerine yapılan çağrılara dönüştürür: origin. aşağıda ScreenPosition yapısının X özelliğinin salt okunur bir özellik olarak bildirilmiş biçimini görebilirsiniz: struct ScreenPosition { . sınıfın ya da yapının adı kullanılarak erişilir.x = rangeCheckedX(value). Örneğin. // derleme zamanı hatası Salt Yazılır Özellikler Benzer biçimde. Bu durumda.x. hem get hem de set erişimcileri kullanılır. } } } X özelliği bir set erişimcisi içermez. Salt Okunur Özellikler Yalnızca get erişimcisi olan özellikler bildirmenize izin verilir.. Örneğin. public int X { get { return this. özelliği yalnızca okuma bağlamında kullanabilirsiniz. X’i bir yazma bağlamında kullanmak için yapılan her girişim başarısız olur. sınıf ya da yapının bir oluşumu kullanılarak değil. Bu durumda... public int X { set { this. bu nedenle.. İpucu static özellikleri tıpkı static alan ve yöntemleri bildirdiğiniz gibi bildirebilirsiniz.280 Kısım III Bileşenler Yaratmak Bir özelliği okuma/yazma bağlamında kullanmak da olasıdır. Bu durumda.

Bölüm 15

Alanlara Erişmek İçin Özellikler Uygulamak

281

X özelliği bir get erişimcisi içermez; X’i bir okuma bağlamında kullanmak için yapılan her girişim başarısız olur. Örneğin:
Console.WriteLine(origin.X); origin.X = 200; origin.X += 10; // derleme zamanı hatası // derlenir // derleme zamanı hatası

Not Salt yazılır özellikler parola gibi güvenli veri için yararlıdır. İdeal olarak, güvenliği gözeten

bir uygulamanın parola oluşturmanıza izin vermesi ancak parolanızı okumanıza izin vermemesi gerekir. Oturum açma yöntemi yalnızca kullanıcının girdiği dize ile depolanmış parolayı karşılaştırmalı ve bunların eşleşip eşleşmediğini bildirmelidir.

Özellik Erişebilirliği
Bir özelliğin erişebilirliği (public, private ya da protected) özelliği bildirdiğinizde belirtilir. Ancak, get ve set erişimcileri için farklı erişebilirlik belirtmek olanaklıdır. Örneğin, ScreenPosition yapısının aşağıda gösterilen sürümü X ve Y özelliklerinin set erişimcilerini private olarak tanımlamaktadır (get erişimcileri public olarak kalır):
struct ScreenPosition { ... public int X { get { return this.x; } private set { this.x = rangeCheckedX(value); } } public int Y { get { return this.y; } private set { this.y = rangeCheckedY(value); } } ... private int x, y; }

Birbirinden farklı erişebilirlikleri olan erişimcileri tanımlarken bazı kurallara uymanız gerekir:
n

Tanımlarken, erişimcilerden yalnızca bir tanesinin erişebilirliğini değiştirebilirsiniz. Her iki erişimcinin erişebilirliğinin private olduğu public bir özellik yazmak zaten anlamsızdır! Değiştirici, özelliğinkinden daha az kısıtlayıcı bir erişebilirlik belirtmemelidir. Örneğin, özellik private olarak bildirilmişse okuma erişimcisini public olarak belirtemezsiniz (bu örnekte, özelliği public, okuma erişimcisini private yaparsınız) .

n

282

Kısım III

Bileşenler Yaratmak

Özellikler ve Alan Adları: Bir Uyarı
Özellikler ve özel alanlara, sadece ilk harfin büyük ve küçük harf olarak farklı olması dışında, aynı adın verilmesi yaygın bir uygulama olmakla birlikte, bir dezavantajı vardır. Employee adında bir sınıf gerçekleştiren aşağıdaki kodu inceleyin. employeeID alanı özeldir fakat EmployeeID özelliği, bu alana erişim sağlar.
class Employee { private int employeeID; public int EmployeeID; { get { return this.EmployeeID; } set { this.EmployeeID = value; } }

Bu kod sorunsuzca derlenir fakat EmployeeID özelliğine erişildiğinde bir StackOverflowException özel durumu oluşturur. Bunun nedeni, get ve set erişimcilerinin private alandan (küçük harf e) çok, özelliğe (büyük harf E) başvurmasıdır. Bu, kullanılabilir bellek alanını tüketen sonsuz bir döngüye neden olur. Bu tür hatayı yakalamak çok zordur!

Özellik Kısıtlamalarını Anlamak
Özellikler, alanlar gibi görünür, davranır ve hissedilirler. Ancak gerçekte alan değildirler ve onlara bazı kısıtlamalar uygulanır:
n

Bir yapının ya da sınıfın özelliğine sadece sınıf ya da yapı başlatıldıktan sonra bir değer atayabilirsiniz. Aşağıdaki örnekteki kod geçersizdir çünkü konum değişkeni başlatılmamıştır (new kullanılarak). Örneğin:
ScreenPosition location; location.X = 40; // derleme zamanı hatası, konum atanmamış

Not Bu önemsiz görünebilir, ancak X bir özellik değil bir alan olsaydı kod geçerli olurdu.

Bunun anlamı, alan ve özellikler arasında bazı farklar olduğudur. Yapı ve sınıfları, daha sonra özelliklere geçirdiğiniz alanlar kullanarak değil, ilk baştan özellikler kullanarak tanımlamanız gerekir; alanları özelliklere dönüştürürseniz sınıf ve yapılarınızı kullanan kod artık çalışmayabilir. Bu konuyu, “Otomatik Özellikler Üretmek” başlıklı bölümde yeniden ele alacağız.

Bölüm 15
n

Alanlara Erişmek İçin Özellikler Uygulamak

283

Bir özelliği bir ref ya da out bağımsız değişkeni olarak kullanamazsınız (ama yazılabilir bir alanı bir ref ya da out bağımsız değişkeni olarak kullanabilirsiniz). Özellik gerçekte bir bellek konumunu değil bir erişimci yöntemini işaret ettiğinden, bu mantıklıdır. Örneğin:
MyMethod(ref location.X); // derleme zamanı hatası

n

Bir özellik yalnızca tek bir get ya da set erişimcisi içerebilir. Bir özellik başka yöntem, alan ya da özellik içeremez. get ve set erişimcileri parametre alamaz. Atanmakta olan veri, value değişkeni kullanılarak otomatik olarak set erişimcisine geçirilir. const özellikleri bildiremezsiniz. Örneğin:
const int X { get { ... } set { ... } } // derleme zamanı hatası

n

n

Özellikleri Uygun Biçimde Kullanmak
Özellikler temiz, alan benzeri bir sözdizimi içeren güçlü araçlardır. Doğru biçimde kullanıldıklarında özellikler kodun okunuşunu ve bakımını kolaylaştırır. Ancak, nesnelerin özelliklerine değil, davranışına odaklanan özenli nesne yönelimli tasarımının yerini almaları söz konusu değildir. Sıradan yöntemlerle ya da özelliklerle özel alanlara erişmek kendi başına kodunuzun tasarımını geliştirmez. Örneğin, bir banka hesabı bir bakiye (Balance) içerir. Dolayısıyla, aşağıdaki gibi, bir BankAccount (BankaHesabı) sınıfında bir Balance özelliği oluşturmak isteyebilirsiniz:
class BankAccount { ... public money Balance { get { ... } set { ... } } private money balance; }

Bu kötü bir tasarımdır. Bir banka hesabına para yatırırken ve hesaptan para çekerken gereken işlevselliği yansıtmamaktadır. (Bakiyeyi sizin belirlemenize izin veren bir banka biliyorsanız bana da haber verin.) Program yazarken sorunun ifade edilmesi işini bir yığın alt düzey sözdizimi içinde kaybetmemeye çalışın; Çözdüğünüz sorunu çözümde ifade etmeye çalışın:
class BankAccount { ... public money Balance { get { ... } } public void Deposit(money amount) { ... } public bool Withdraw(money amount) { ... } private money balance; }

284

Kısım III

Bileşenler Yaratmak

Arabirim Özelliklerini Bildirmek
Bölüm 12’de arabirimleri gördünüz. Arabirimler, yöntemlerin yanı sıra özellikler de belirtebilir. Bunu yapmak için, ya get ya set anahtar sözcüğünü ya da her ikisini birden bildirmeniz gerekir ama get/set erişimcilerinin gövdelerini bir noktalı virgülle değiştirin. Örneğin:
interface IScreenPosition { int X { get; set; } int Y { get; set; } }

Bu arabirimi kullanan bütün sınıf ya da yapılar, get ve set erişimci yöntemleri ile X ve Y özelliklerini de kullanmak zorundadır. Örneğin:
struct ScreenPosition : IScreenPosition { ... public int X { get { ... } set { ... } } public int Y { get { ... } set { ... } } ... }

Arabirim özelliklerini bir sınıf içinde kullanırsanız, özellik kullanımlarını virtual olarak bildirebilirsiniz. Bu da daha sonra bundan türetilen sınıfların bu kullanımları geçersiz kılmasını sağlar. Örneğin:
class ScreenPosition : IScreenPosition { ... public virtual int X { get { ... } set { ... } } public virtual int Y { get { ... } set { ... } } ... }

Bölüm 15

Alanlara Erişmek İçin Özellikler Uygulamak

285

Not Örnek, bir sınıf göstermektedir. virtual anahtar sözcüğü yapılar için geçerli değildir; çünkü yapılardan türetme yapamazsınız; yapılar mühürlü (sealed) olarak kapalıdır. Bir özelliği ayrıca, Bölüm 13’te anlatılan açık arabirim geliştirmesi sözdizimini kullanarak da uygulayabilirsiniz. Bir özelliğin açık kullanımı genel de değildir sanal da (ve geçersiz de kılınamaz). Örneğin:
struct ScreenPosition : IScreenPosition { ... int IScreenPosition.X { get { ... } set { ... } } int IScreenPosition.Y { get { ... } set { ... } } ... private int x, y; }

Özellikleri Bir Windows Uygulamasında Kullanmak
Microsoft Visual Studio 2008’te Properties penceresini kullandığınızda, aslında, çeşitli uygulama bileşenlerinin (TextBox denetimleri, Windows ve Button denetimleri gibi öğeler) özellik değerlerini ayarlayan ve alan bir kod oluşturursunuz. Bazı bileşenlerin çok sayıda özelliği vardır ve bazı özellikler diğerlerinden daha çok kullanılır. Bu bölümde gördüğünüz sözdiziminin aynısını kullanarak bu özelliklerin çoğunu çalışma zamanında değiştirebilirsiniz. Aşağıdaki alıştırmada, pencere yeniden boyutlandığında bile sürekli ana penceresinin boyutlarını gösteren basit bir uygulama yaratmak için TextBox denetimlerinin ve Window sınıfının bazı önceden tanımlı özelliklerini kullanacaksınız.

Özellikleri kullanın
1. Visual Studio 2008’i başlatın. 2. Belgeler klasörünüzde bulunan \Microsoft Press\Visual CSharp Step by Step\Chapter 15\ WindowProperties klasöründeki WindowProperties projesini açın. 3. Debug menüsünde Start Without Debugging’ i tıklayın.

286

Kısım III

Bileşenler Yaratmak

Proje oluşturulur ve çalışır. Width ve Height olarak etiketlenmiş iki boş metin kutusu görüntüleyen bir pencere (Windows Presentation Foundation [WPF] formu) belirir. Programda metin kutusu denetimleri width ve height olarak adlandırılır. Şu an için boştur. Uygulamaya, pencerenin geçerli boyutunu gösteren kodu ekleyeceksiniz. 4. Formu kapatın ve Visual Studio 2008 programlama ortamına dönün. 5. Code and Text Editor penceresinde, Window1.xaml.cs dosyasını görüntüleyin ve sizeChanged yöntemini bulun. Bu yöntem Window1 kurucusu tarafından kullanılır. Bunu, formun geçerli boyutunu width ve height metin kutularında görüntülemek için kullanacaksınız. Window sınıfının ActualWidth ve ActualHeight özelliklerini kullanışlı hale getireceksiniz. Bu özellikler, double değerler olarak geçerli width ve height değerini döndürür. 6. Formun boyutunu görüntülemek için, sizeChanged yöntemine iki ifade ekleyin. İlk ifade, formun ActualWidth özelliğinin değerini okumalı, bu değeri bir dizeye çevirmeli ve bu değeri width metin kutusunun Text özelliğine atamalıdır. İkinci ifade, formun ActualHeight özelliğinin değerini okumalı, bir dizeye çevirmeli ve bu değeri height metin kutusunun Text özelliğine atamalıdır. sizeChanged yöntemi tam olarak şu şekilde görünmelidir:
private void sizeChanged() { width.Text = this.ActualWidth.ToString(); height.Text = this.ActualHeight.ToString(); }

7. window1SizeChanged yöntemini bulun. Uygulama çalıştığında, pencerenin boyutu her değiştiğinde bu yöntem çalışır. Bu yöntemin, metin kutularında yeni pencere boyutunu görüntülemek için sizeChanged yöntemini çağırdığına dikkat edin. 8. Projeyi oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’ i tıklayın. Form, 305 ve 155 değerlerini içeren iki metin kutusu görüntüler. Bunlar, form tasarlandığında belirlenen, formun varsayılan boyutlarıdır. 9. Formu yeniden boyutlandırın. Metin kutularındaki metnin, yeni boyutu yansıttığına dikkat edin. 10. Formu kapatın ve Visual Studio 2008 programlama ortamına dönün.

Bölüm 15

Alanlara Erişmek İçin Özellikler Uygulamak

287

Otomatik Özellikler Üretmek
Bu bölümün önceki kısımlarında, özelliklerin başlıca amacının, alanların uygulamasını dış dünyadan saklamak olduğundan bahsedilmişti. Özellikleriniz gerçekten bazı yararlı işler yapıyorsa bu iyidir fakat get ve set erişimciler, sadece alana bir değer atamak ya da değer okumak işlemlerini yerine getiriyorsa, bunun doğru bir yaklaşım olup olmadığını sorabilirsiniz. Veriyi public alanlar olarak göstermek yerine özellikler tanımlamanız için en az iki neden vardır:
n

Uygulamalarla uygunluk Alanlar ve özellikler, derlemelerde farklı meta veri kullanarak kendilerini ortaya koyarlar. Bir sınıf geliştiriyorsanız ve public alanlar kullanmaya karar verdiyseniz, bu sınıfı kullanan bir uygulama, alanlar olarak bu öğelere başvuracaktır. Bir özelliği okurken ve yazarken kullandığınız C# sözdizimini, bir alanı okumak ve yazmak için kullanabilseniz de, derlenen kod gerçekte oldukça farklıdır (C# derleyici bu farkları sizden saklar). Daha sonra bu alanları, özellikler olarak değiştirmeniz gerektiğine karar verirseniz (işin gereksinimleri değişmiş olabilir ve değerleri atarken ek bir mantık gerçekleştirmeniz gerekebilir), mevcut uygulamalar yeniden derlenmeden sınıfın güncellenmiş sürümünü kullanamaz. Uygulamayı bir şirketin çok sayıda kullanıcısına uyguladıysanız, bu bir dezavantajdır. Bunu çözmenin yolları vardır fakat genellikle ilk başta bu durumla karşılaşmaktan kaçınmak en iyisidir. Arabirimlerle uygunluk Bir arabirim gerçekleştiriyorsanız ve arabirim özellik olarak bir öğe tanımlıyorsa, özellik sadece private alandaki veriyi okuyor ve yazıyor olsa bile, arabirimdeki şartlara uyan bir özellik yazmanız gerekir. Sadece aynı adla bir public alan göstermek yoluyla bir özellik geliştiremezsiniz.

n

C# dili tasarımcıları, programcıların gereğinden fazla kod yazacak kadar zamanı olmayan meşgul insanlar olduğunu bilir. Bu amaçla, C# derleyici sizin için otomatik olarak özellikler kodunu üretebilir:
class Circle { public int Radius{ get; set; } ... }

Bu örnekte, Circle sınıfı Radius adında bir özellik içerir. Bu özellik türü dışında, bu özelliğin nasıl çalıştığını belirtmeniz gerekmez (get ve set erişimcileri boştur). C# derleyicisi, bu tanımı aşağıdakine benzer bir private alana ve bir varsayılan uygulamaya dönüştürür:

288

Kısım III

Bileşenler Yaratmak

class Circle { private int _radius; public int Radius{ get { return this._radius; } set { this._radius = value; } } ... }

Daha az uğraşmak için, otomatik olarak üretilmiş kodu kullanarak basit bir özelliği gerçekleştirebilirsiniz ve daha sonra ek bir mantık gerekirse, mevcut uygulamaları bozmadan bunu yapabilirsiniz. Bununla birlikte, otomatik olarak üretilmiş özellikle birlikte get ve set erişimcilerinin her ikisini de belirtmeniz gerektiğine dikkat edin (otomatik özellik salt-okunur ya da salt-yazılır olamaz). Not Bir otomatik özelliği tanımlamak için kullanılan sözdizimi, bir arabirimdeki özelliği

tanımlamak için kullanılan sözdizimine benzer. Farklı olarak, otomatik özellik, private, public ya da protected gibi bir erişim düzenleyici belirleyebilir.

Özellikleri Kullanarak Nesneleri Başlatmak
Bölüm 7’de, bir nesneyi başlatmak için kurucular tanımlamayı öğrendiniz. Bir nesne birden fazla kurucuya sahip olabilir ve bir nesnedeki farklı öğeleri başlatmak için çeşitli parametrelerle kurucular tanımlayabilirsiniz. Örneğin, aşağıdaki gibi, bir üçgeni modelleyen bir sınıf tanımlayabilirsiniz:
public class Triangle { private int side1Length; private int side2Length; private int side3Length; // varsayılan kurucu - tüm yönler için varsayılan değerler public Triangle() { this.side1Length = this.side2Length = this.side3Length = 10; } // side1Length için uzunluk belirle, diğerleri için varsayılan değerler public Triangle(int length1)

Bölüm 15
{ this.side1Length = length1; this.side2Length = this.side3Length = 10; } // side1Length ve side2Length için uzunluk belirle, // side3Length için varsayılan değer public Triangle(int length1, int length2) { this.side1Length = length1; this.side2Length = length2; this.side3Length = 10; }

Alanlara Erişmek İçin Özellikler Uygulamak

289

// tüm yönler için uzunluk belirle public Triangle(int length1, int length2, int length3) { this.side1Length = length1; this.side2Length = length2; this.side3Length = length3; } }

Bir sınıfın kaç adet alan içerdiğine ve alanları başlatmak için istediğiniz çeşitli bileşimlere bağlı olarak, çok sayıda kurucu yazmaya son verebilirsiniz. Ayrıca çok sayıda alan aynı türde ise problemler meydana gelebilir: Alanların tüm bileşimleri için benzersiz bir kurucu yazamayabilirsiniz. Örneğin, önceki Triangle sınıfında, sadece side1Length ve side3Length alanlarını başlatan bir kurucuyu kolayca ekleyemezsiniz çünkü benzersiz bir imzaya sahip olmayacaktır; iki int parametresi alacaktır, side1Length ve side2Length alanlarını başlatan kurucu zaten bu imzaya sahiptir. Bunun çözümü, aşağıdaki gibi, private alanları varsayılan değerleri ile başlatmak ve özellikler tanımlamaktır:
public class Triangle { private int side1Length = 10; private int side2Length = 10; private int side3Length = 10; public int Side1Length { set { this.side1Length = value; } } public int Side2Length { set { this.side2Length = value; } } public int Side3Length { set { this.side3Length = value; } } }

290

Kısım III

Bileşenler Yaratmak

Bir sınıfın oluşumunu yarattığınızda, set erişimcilere sahip public özellikler için değerler belirleyerek bu oluşumu başlatabilirsiniz. Yani, Triangle nesneler yaratabilir ve üçgenin üç kenarını herhangi bir bileşimle başlatabilirsiniz:
Triangle Triangle Triangle Triangle tri1 tri2 tri3 tri4 = = = = new new new new Triangle Triangle Triangle Triangle { { { { Side3Length Side1Length Side2Length Side1Length Side3Length = = = = = 15 }; 15, Side3Length = 20 }; 12, Side3Length = 17 }; 9, Side2Length = 12, 15 };

Bu sözdizimi, object initializer (nesne başlatıcı) olarak bilinir. Bu yolla bir nesne başlatıcı çağırdığınızda, C# derleyici, varsayılan kurucuyu çağıran ve daha sonra belirtilen değer ile başlatmak için adlandırılmış her özelliğin set erişimcisini çağıran kodu üretir. Nesne başlatıcıları, varsayılan olmayan kurucularla da belirleyebilirsiniz. Örneğin, Triangle sınıfı, üçgenin türünü tanımlayan tek bir dize parametresi alan bir kurucu da içeriyorsa, aşağıdaki gibi bu kurucuyu çağırabilir ve diğer özellikleri başlatabilirsiniz:
Triangle tri5 = new Triangle(“Equilateral triangle”) { Side1Length = 3, Side2Length = 3, Side3Length = 3 };

Unutmamanız gereken önemli bir nokta, kurucunun ilk olarak çalıştığı ve özelliklerin daha sonra atandığıdır. Kurucu, bir nesnedeki alanları belirli değerlere atıyorsa ve belirlediğiniz özellikler bu değerleri değiştiriyorsa bu sıralamayı anlamak önemlidir. Sonraki alıştırmada göreceğiniz gibi, nesne başlatıcıları otomatik özelliklerle de kullanabilirsiniz. Bu alıştırmada, bir düzgün çokgeni modellemek için bir sınıf tanımlayacaksınız. Bu sınıf, çokgenin kenar sayısını ve kenarların uzunluklarını sağlamak için otomatik özellikler içerecek.

Otomatik özellikler tanımlayın ve nesne başlatıcıları kullanın
1. Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\Chapter 15\ AutomaticProperties klasöründeki AutomaticProperties projesini Visual Studio 2008’de açın. AutomaticProperties projesi, önceki alıştırmalarda gördüğünüz Main ve Entrance yöntemleri ile Program sınıfını tanımlayan Program.cs dosyasını içerir. 2. Solution Explorer’da, AutomaticProperties projesini farenin sağ düğmesiyle tıklayın, Add’i işaret edin ve sonra da Class’ı tıklayın. Add New Item’da (AutomaticProperties iletişim kutusu), Name metin kutusuna Polygon.cs yazın ve sonra Add’i tıklayın. Polygon.cs dosyası, yaratılarak projeye eklenen ve Code and Text Editor penceresinde gösterilen Polygon sınıfını tutar.

Bölüm 15

Alanlara Erişmek İçin Özellikler Uygulamak

291

3. Polygon sınıfına, aşağıda koyu harflerle gösterilen NumSides ve SideLength otomatik özelliklerini ekleyin:
class Polygon { public int NumSides { get; set; } public double SideLength { get; set; } }

4. Aşağıdaki varsayılan kurucuyu Polygon sınıfına ekleyin:
class Polygon { public Polygon() { this.NumSides = 4; this.SideLength = 10.0; } ... }

Bu alıştırmada, varsayılan çokgen 10 birim uzunluğunda kenarlara sahip bir karedir. 5. Code and Text Editor penceresinde Program.cs dosyasını görüntüleyin. 6. Aşağıda koyu harflerle gösterilen ifadeleri Entrance yöntemine ekleyin:
static void { Polygon Polygon Polygon } Entrance() square = new Polygon(); triangle = new Polygon { NumSides = 3 }; pentagon = new Polygon { SideLength = 15.5, NumSides = 5 };

Bu ifadeler Polygon nesneleri yaratır. square değişkeni, varsayılan kurucu kullanılarak başlatılır ve daha sonra bu kod, Polygon sınıfı tarafından ortaya çıkarılmış özelliklerin değerlerini değiştirir. triangle değişkeni durumunda, NumSides özelliğine 3 değeri atanır fakat SideLength özelliğinin değeri varsayılan değer olan 10.0 olarak bırakılır. pentagon değişkeni için, kod SideLength ve NumSides özelliklerinin değerlerini değiştirir. 7. Aşağıdaki kodu Entrance yönteminin sonuna ekleyin:
static void Entrance() { ... Console.WriteLine(“Square: number of sides is {0}, length of each side is {1}”, square.NumSides, square.SideLength); Console.WriteLine(“Triangle: number of sides is {0}, length of each side is {1}”, triangle.NumSides, triangle.SideLength); Console.WriteLine(“Pentagon: number of sides is {0}, length of each side is {1}”, pentagon.NumSides, pentagon.SideLength); }

292

Kısım III

Bileşenler Yaratmak

Bu ifadeler, her Polygon nesnesi için NumSides ve SideLength özelliklerin değerini görüntüler. 8. Debug menüsünde Start Without Debugging’i tıklayın. Programın oluşturularak çalıştırıldığını ve konsola aşağıdaki iletiyi yazdığını doğrulayın:

9. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. Otomatik özelliklerin nasıl yaratıldığını ve nesneleri başlatırken özellikleri nasıl kullanacağınızı gördünüz.

n

Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 16’ya geçin. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Save iletişim kutusu görünürse, Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.

n

Bölüm 15 Hızlı Başvuru
Bunun İçin
Bir yapı ya da sınıf için bir okuma/ yazma özelliği bildirmek

Şunu Yapın
Özelliğin türünü, adını, bir get erişimcisi ve bir set erişimcisi bildirin. Örneğin:
struct ScreenPosition { ... public int X { get { ... } set { ... } } ... }

Bölüm 15

Alanlara Erişmek İçin Özellikler Uygulamak

293

Bir yapı ya da sınıf için salt okunur bir özellik bildirmek

Yalnızca bir get erişimcisi olan bir özellik bildirin. Örneğin:
struct ScreenPosition { ... public int X { get { ... } } ... }

Bir yapı ya da sınıf için salt yazılır bir özellik bildirmek

Yalnızca bir set erişimcisi olan bir özellik bildirin. Örneğin:
struct ScreenPosition { ... public int X { set { ... } } ... }

Bir arabirim içinde özellik bildirmek

Yalnızca get, set ya da her ikisi de olan bir özellik bildirin.Örneğin:
interface IScreenPosition { int X { get; set; } // int Y { get; set; } // }

gövde yok gövde yok

Bir yapı ya da sınıf için bir arabirim özelliği kullanmak

Arabirimi kullanan yapı ya da sınıfta özelliği bildirin, özelliği bildirin ve erişimcileri uygulayın. Örneğin:
struct ScreenPosition : IScreenPosition { public int X { get { ... } set { ... } } public int Y { get { ... } set { ... } } }

} } Bir nesneyi başlatmak için özellikleri kullanmak Nesneyi kurarken. Örneğin: Triangle tri3 = new Triangle { Side2Length = 12. özellikler ve değerlerini küme parantezi arasında listeleyin. özelliği boş get ve set erişimcilerle tanımlayın. Örneğin: class Polygon { public int NumSides { get.294 Kısım III Bileşenler Yaratmak Otomatik özellik yaratmak Özellik içeren sınıf ya da yapıda. Side3Length = 17 }. set. .

tıpkı bir özelliğin akıllı bir alan olması gibi. Daha sonra aynı sorun üzerinde çalışmaya devam edecek ve dizinleyici kullanan daha iyi bir çözüm göreceğiz. Dizinleyici Kullanmayan Bir Örnek Normalde bir tamsayı değeri taşıması için bir int kullanırsınız. bir int. İlk olarak bir sorun tanımlayacağız ve dizinleyici kullanmayan kötü bir çözüm göreceğiz. Gelin. her bitin 0 ya da 1 olabildiği 32 bitlik bir sırada tutar. değerini. Ancak. Arabirimlerden kalıtımla alınan yapı ve sınıflarda dizinleyiciler kullanmak. (Benim gibi eski bir C program geliştiriciyseniz. Özellikler. doğal ve tanıdık bir sözdizimi kullanarak birden çok değer içeren öğelere erişim sağlamak isterseniz dizinleyiciler çok değerlidir. Ancak. tümüyle bir dizi için kullandığınız sözdiziminin aynısıdır. yalnızca bir tamsayı değeri taşıması için bir int’i kova olarak kullanırsınız. bundan sonra gelenler tanıdık olmalıdır!) 295 . ara sıra bir program bit int’i bir tamsayıyı gösterdiği için değil de 32 bit taşıdığı için kullanabilir. Dizinleyicilere okuma erişimini denetlemek için get erişimcileri bildirmek. Dizinleyicilere yazma erişimini denetlemek için set erişimcileri bildirmek. bazı programlar bir int içindeki tek tek bitleri değiştirirler. Diğer bir deyişle. programcılar int türünü bazen başka amaçlar için kullanırlar. tek bir değer içeren alanları yansıtmak için yararlıdır. Önceki bölümde bir sınıftaki alanlara denetimli başvuru sağlamak için özellikleri kullanıp uygulamak açıklanmıştı. bir örnek üzerinde çalışalım. Dizinleyici Nedir? Bir dizinleyici (indexer). Dizinleyicileri bildiren arabirimler yaratmak. Çoğu zaman bu içsel ikili gösterim konusunu düşünmeniz gerekmez. akıllı bir dizidir. Bir dizinleyici için kullandığınız sözdizimi. İçsel olarak. Sorun tamsayılarla ilgili ya da daha doğru belirtmek gerekirse int türü ile ilgili.Bölüm 16 Dizinleyicileri Kullanmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n Mantıksal dizi benzeri bildirimleri kapsüllemek için dizinleyicileri kullanmak.

Çözüm getirdiği problemin bir soyutlamasını yapamaz. dizindeki bit de sağdan 6. . sıradaki bittir. Bu oldukça karmaşık bir deyim. <<. 6. 1 ise true sonucunu verecektir.296 Kısım III Bileşenler Yaratmak Not Bazı eski programcılar int türlerini bellekten tasarruf etmek için kullanabilir. dizindeki bit 0 ise deyim false. Bit Benzeri ve Kaydırma İşleçleri Bu örneklerde gösterilen bazı ilginç simgeleri fark etmişsinizdir. dizindeki biti 1 olarak ayarlamak istiyorsanız. 8 bit 11001100’ın (204’ün karşılığı) değerini alıp ~ işlecini uygularsanız 00110011 (51’in karşılığı) değerine ulaşırsınız. Tekil bir işleçtir. Özellikle. | ve &. bits adlı int’in 6. n NOT (~) işleci bir bit benzeri tamamlayıcısıdır. Bunlar bit benzeri ve kaydırma işleçlerinden bazıları olup int ve long veri türlerinde tutulan bitleri değiştirmek için kullanılırlar. dizinindeki bitin 0 mı yoksa 1 mi olduğunu bulmak için << ve & bit benzeri işleçleri kullanıyor: (bits & (1 << 6)) != 0 6. Tek bir int 32 bit tutar ve her bit 0 ya da 1 olabilir. çalışıyor olsalar bile neden ve nasıl çalışıyor olduklarının çok açık olmamasıdır. Örneğin. bu nedenle 0 biti en sağdaki bit ve 6. Örneğin. sağdan sola doğru bitlerin konumunu sayar. ~. Benzer şekilde. bit OR (|) işlecini kullanabilirsiniz. Çok karmaşıktırlar ve çözüm çok basittir. dizindeki bit’i. Bazı durumlarda programcılar bir değerin doğru olduğunu belirtmek için 1. Aşağıdaki karmaşık ifade |= birleşik atama işlecine dayanır: bits |= (1 << 6) Bu örneklerle ilgili sorun. &= karşılaştırma atama işleci ile 0’a eşitleyen aşağıdaki deyimle karşılaştırılamaz bile: bits &= ~(1 << 6) Not Bit işleçleri. yanlış olduğunu belirtmek içinse 0 kullanırlar ve daha sonra bir Boolean değerler kümesi olarak bir int kullanırlar. aşağıdaki deyim. ama 6.

AND (&) işleci bir bit benzeri AND (ve) işlemi uygular.Bölüm 16 n Dizinleyicileri Kullanmak 297 << işleci sola kaydırma işlemi uygular. Bunun tam karşıtı olan bir de sağa kaydırma işleci >> vardır. Bu yüzden bu sorunu çözmenin en iyi yolu int değeri 32 bitin oluşturduğu bir dizi olarak kullanmaktır! Diğer bir deyişle bits bir int değerse 6. n n n Aynı Örneğin Dizinleyici Kullanan Biçimi Gelin önceki düşük seviye çözümü bir kenara bırakıp sorunun ne olduğunu kendimize anımsatmak için birazcık duralım. Köşeli parantezi yalnızca bir dizi ya da bir dizi gibi davranan başka bir tür üzerinde kullanabilirsiniz. Bir ikili işleçtir ve iki işleç değişkeninden herhangi biri “1” ise o biti “1” yapar. (İki 1 değeri 0 sonucunu verir – bu da işlecin “özel” bölümüdür. 204 << 2 deyiminin sonucu 48’dir (ikilik sistemde 204 11001100’a karşılık gelir ve iki basamak sola kaydırma işleminin sonunda 00110000 değerine ulaşılır ya da karşılığı olan 48’e). 204 | 24 işleminin değeri 220’dir (204’ün karşılığı 11001100’dır. bir int üzerinde köşeli parantez kullanamazsınız. OR (|) işleci bir bit benzeri OR (ya da) işlemi uygular. Sonuçta sorunun çözümü bool değerlerden oluşan bir dizi gibi davranan. örneğin. yani bir dizinleyici tanımlayan bir tür üstünde. dizindeki bit’i true yapmak için şunu yazabilmeliyiz: bits[6] = true Ne yazık ki. fakat int türü kullanılarak uygulanan yeni bir tür yaratmaktır. 24’ün karşılığı ise 00011000’dır. . Örneğin. 24’ün karşılığı ise 00011000’dır. hisseden ve kullanılan. En soldaki iki bit atılır ve sağdan iki sıfır eklenir. Sorun. bir XOR (özel ya da) işlemi uygular ve işlenenlerden birinde ya da diğerinde 1 varsa (ama ikisinde değil) her bitte 1 döndürür. IntBits (kurucusunda başlatılan) bir int değer içerecek ama biz IntBits’i bool değerlerden oluşan bir dizi gibi kullanacağız. bit benzeri OR işlecine benzer. İkili bir işleçtir. Bu yüzden. XOR (^) işleci. 204&24 işleminin sonucu 8’dir (204’ün karşılığı 11001100’dır. bir int’i bir int gibi kullanmak istemeyip 32 bitlik bir dizi gibi kullanmak istememizdi. AND.) Bu yüzden 204^24 işleminin sonucu 212’dir (11001100^00011000 işleminin sonucu 11010100’dır). Bir ikili işleçtir ve işleç değişkenlerinin her ikisi de “1” ise o biti “1” yapar. 6. yapı olarak yaratmak daha akıllıcadır. İpucu IntBits küçük ve hafif olduğundan onu bir sınıf olarak değil. 220 ise 110011100’dır). dizindeki bit’i almak için yazmamız gereken şudur: bits[6] Ve. 8 ise 00001000’dır). Gelin bu yeni türe IntBits diyelim.

else bits &= ~(1 << index). Dizinleyiciler. get ve set erişim yöntemleri erişilecek öğeleri belirlemek için bu bağımsız değişkeni okuyabilir. özelliklerdeki gibi get ve set erişimcileri içerir. yöntem adı yerine this anahtar sözcüğünü kullanırlar. ama bir dizin belirten köşeli parantez vardır. } set { if (value) // değer true ise bit’i aç. } // dizinleyici buraya yazılır private int bits.. IntBits yapısının dizinleyicisi aşağıdaki gibidir: struct IntBits { .. } } . } Aşağıda belirtilen noktalara dikkat edin: n Dizinleyiciler yöntem değildir. Bu örnekte. hangi öğeye erişildiğini gösterir.298 Kısım III Bileşenler Yaratmak struct IntBits { public IntBits(int initialBitValue) { bits = initialBitValue.. Bu dizin. Bir sınıf ya da yapının yalnızca bir dizinleyici tanımlamasına izin verilir ve bu her zaman this olarak adlandırılır. Dizinleyici bildiriminde belirtilen bağımsız değişken dizinleyici çağrıldığında belirtilen dizin değeriyle doldurulur. Bütün dizinleyiciler. n n n .. değilse kapat bits |= (1 << index). get ve set erişimcileri yukarıda söz edilen karmaşık bit benzeri deyimleri içerir. public bool this [ int index ] { get { return (bits & (1 << index)) != 0. bir parametre içeren parantez kullanılmaz. } Dizinleyiciyi tanımlamak için bir özellik ile bir dizi arasında geçiş olan bir gösterim biçimi kullanırsınız.

// 6 dizininde bool al. Bu ifade bits’in get erişimcisine yapılan bir çağrıya dönüştürülür ve index bağımsız değişkeninin değeri 6 olarak ayarlanır. bool). aşağıdaki örneği düşünün: bool peek = bits[6]. // 0 dizininde bit’i true (1) olarak ayarla bits[3] = false. Ancak. Benzer biçimde. Bu ifade. Örneğin: bits[6] = true. // 3 dizininde bit’i false (0) olarak ayarla // değiştirilen değer şimdi 111011. Sıradan özelliklerdeki gibi. Bir dizinleyici birden çok değeri olan bir özellik gibidir. static özellikler bildirmenize izin verilse de static dizinleyiciler geçersizdir. Örneğin. Not Dizinleyici ve özellikler. ya da ikili temsilde 59 Bu sözdizimini anlamak kesinlikle daha kolaydır. index değerinin 6 olduğu bits’in set erişimcisine yapılan bir çağrıya dönüştürülür. dizinleyiciye yazdığınız değer (bu durumda true) set erişimcisi içinden value anahtar sözcüğü kullanılarak erişilebilir kılınır. value türü dizinleyicinin türüyle aynıdır (bu durumda.Bölüm 16 Dizinleyicileri Kullanmak 299 Not Dizinleyici kodunuzda herhangi bir beklenmedik özel durum oluşmasını önlemek için dizinleyicideki dizin değeri üzerinde bir aralık denetimi yapmanız gerekir. Doğrudan ve uzatmadan sorunun özünü yakalar. true (1) olmalı bits[0] = true. Dizinleyici bildirildikten sonra bir int yerine IntBits türü bir değişken kullanabilir ve köşeli parantez gösterim biçimini uygulayabiliriz: int adapted = 62. get ve set erişimcilerini kullanmaları açısından birbirine benzer. // 62 111110’un ikili temsilidir IntBits bits = new IntBits(adapted). bool peek = bits[6]. . Dizinleyici Erişimcilerini Anlamak Bir dizinleyiciyi okuduğunuzda derleyici otomatik olarak sizin dizi benzeri kodunuzu bu dizinleyicinin get erişimcisine yapılan bir çağrıya dönüştürür. bir dizinleyiciye yazarsanız derleyici otomatik olarak sizin dizi benzeri kodunuzu bu dizinleyicinin set erişimcisine yapılan bir çağrıya dönüştürür ve index bağımsız değişkenini köşeli parantez içinde belirtilen değer olarak ayarlar.

. şunun yerine: Hashtable ages = new Hashtable(). Örneğin. } public PhoneNumber this [ Name name ] { .. diziler yüklenemez: public Name this [ PhoneNumber number ] { . sözdizimi dizi sözdizimine benzer. Örneğin. // derleme zamanı hatası . Dizinleyicilerle Dizileri Karşılaştırmak Bir dizinleyici kullandığınızda. otomatik olarak aşağıdaki koda dönüştürülür: bits[6] = bits[6] ^ true. ages. Bu durumda get ve set erişimcileri kullanılır. } n Dizinleyiciler ref ya da out parametreleri olarak kullanılamazlarken dizi öğeleri kullanılabilir: IntBits bits. 42). } // Tamam İpucu Anahtar/değer çiftlerine bağlı olarak bileşik arama uygulayan Hashtable gibi birçok koleksiyon sınıfı. dizinleyicilerle diziler arasında bazı önemli farklar vardır: n Dizinleyiciler sayı olmayan girdi kullanabilirler. Ancak. // bits bir dizinleyici içerir Method(ref bits[1]). Not Yalnızca bir get erişimcisi (salt okunur bir dizinleyici) ya da set erişimcisi (salt yazılır bir erişimci) içeren bir dizinleyici de bildirebilirsiniz. yeni bir değer eklemek ve kodunuzdaki bir değeri bulmak için Values özelliği boyunca yineleme yapmaya ve Add yöntemini kullanmaya uygun bir alternatif olarak dizinleyicileri kullanır.. aşağıdaki ifadeyi düşünün: bits[6] ^= true. n Dizinleyiciler (yöntemler gibi) aşırı yüklenebilirken.. ages[“John”] = 42...Add(“John”. bunu kullanabilirsiniz: Hashtable ages = new Hashtable(). Bu kod. ama diziler yalnızca tamsayı girdi kullanabilir: public int this [ string name ] { . Bu kod çalışır çünkü dizinleyici hem bir get hem de bir set erişimcisi bildirir.300 Kısım III Bileşenler Yaratmak Ayrıca birleştirilmiş bir okuma/yazma bağlamında bir dizinleyici kullanmak da olanaklıdır.

. myData[1]++. bir tamsayı diziye dönüştürmeniz gereken bir nesne döndürür.) struct Wrapper { private int[] data. . int[] myData = wrap.. veri dizisinin bir kopyasını döndürmek için Data özelliğinin get ve set erişimcisinde Clone yöntemini kullanmalı ya da burada gösterildiği gibi.. bu karmaşık ve bellek kullanımı açısından pahalı bir işlem olabilir. Dizinleyiciler bu soruna doğal bir çözüm sunmaktadır: tüm diziyi bir özellik olarak göstermeyin. Bu zararsız görünmektedir.data. yalnızca bağımsız öğelerini bir dizinleyici içinden kullanılabilir kılın: struct Wrapper { private int[] data. } set { this.data = value.. } set { this. myData değişkenindeki öğelere yaptığınız her değişiklik data dizisine yapılır. diziler başvuru türü olduğu için myData değişkeni Wrapper yapısındaki özel data değişkeniyle aynı nesneye başvurur.Clone() as int[]. Diziler ve Dizinleyiciler Bir özelliğin bir dizi döndürmesi olanaklı olsa da dizilerin başvuru türü olduğunu ve dolayısıyla bir diziyi bir özellik olarak göstermenin birçok verinin üzerine yazılmasını olanaklı kıldığını unutmayın.Clone() as int[]. myData[0]++. Ancak. .Data.. myData[0]++ ifadesinin etkisi data[0]++ ile aynıdır.. } } } Bununla birlikte. Aşağıdaki Data (Veri) adlı. } } } Şimdi bu özelliği kullanan aşağıdaki kodu düşünün: Wrapper wrap = new Wrapper().Bölüm 16 Dizinleyicileri Kullanmak 301 Özellikler. (Clone yöntemi.data = value. . . public int[] Data { get { return this.data. İstediğiniz bu değilse. public int[] Data { get { return this. . ayarlanan değerin bir kopyasını almalısınız. bir dizi özelliğine sahip yapıya bakın: struct Wrapper { private int[] data...

.. Wrapper nesnesindeki veriyi gerçekten değiştirmek istiyorsanız aşağıdaki gibi ifadeler yazmanız gerekir: wrap[0]++. myData[0]++. myData[1] = wrap[1]. myData[1]++. Bunu yapmak için get ve/veya set anahtar sözcükleri bildirirsiniz ama get/set erişimcisinin gövdesinin yerine bir noktalı virgül yazarsınız. } } struct RawInt : IRawInt { .data[i] = value. Bu kez. } } } Aşağıdaki kod. ..302 Kısım III Bileşenler Yaratmak public int this [int i] { get { return this. MyData dizisindeki değerleri artırmanın Wrapper nesnesindeki özgün dizi üzerinde bir etkisi olmaz. dizinleyiciyi daha önce gösterilen özelliğe benzer biçimde kullanır: Wrapper wrap = new Wrapper()... int[] myData = new int[2]. Bu çok daha temiz ve güvenlidir! Arabirimdeki Dizinleyiciler Bir arabirimde dizinleyiciler bildirebilirsiniz. } set { . Örneğin: interface IRawInt { bool this [ int index ] { get.. myData[0] = wrap[0]. } .. set.data[i]. } set { this. Arabirimi kullanan her sınıf ya da yapı arabirimde bildirilmiş olan dizinleyici erişimlerini geliştirmek zorunda kalır... public bool this [ int index ] { get { . } } ..

. } } . Göreviniz PhoneBook (TelefonDefteri) sınıfına biri Name parametresi alıp bir PhoneNumber (TelefonNumarası) döndüren.Bölüm 16 Dizinleyicileri Kullanmak 303 Arabirim dizinleyicisini bir sınıf içinde geliştirirseniz.. Bu.. bool IRawInt.. ilerde türetilen sınıfların get ve set erişimcilerini geçersiz kılmalarını sağlar...... (Name ve PhoneNumber yapıları zaten yazılmış durumdadır. kullanıcının bir telefon numarasını aramasını ve hatta verilen bir numara ile eşleşen adı bulmasını sağlayan bir Windows Presentation Foundation (WPF) uygulamasıdır. 2. diğeri ise bir PhoneNumber alıp bir Name döndüren iki tane dizinleyici yazmak olacak. basit bir telefon defteri uygulamasını inceleyeceksiniz. Örneğin: class RawInt : IRawInt { . Bu.. } } .. } set { ..this [ int index ] { get { . } Dizinleyicileri Bir Windows Uygulamasında Kullanmak Aşağıdaki alıştırmada. . Örneğin: struct RawInt : IRawInt { .) Ayrıca bu dizinleyicileri program içinde doğru yerlerde çağırmanız gerekecek. public virtual bool this [ int index ] { get { . } set { .. Bir dizinleyicinin açık geliştirmesi ne geneldir ne de sanal (ve bu yüzden geçersiz kılınamazlar). Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\Chapter 16\ Indexers klasöründeki Indexers projesini açın.. Uygulamaya yakınlaşın 1. Bölüm 12’de anlatılan açık arabirim geliştirme sözdizimini kullanarak geliştirmeyi de tercih edebilirsiniz. Microsoft Visual Studio 2008’i açın. dizinleyici uygulamalarını sanal olarak bildirebilirsiniz.. } Ayrıca bir dizinleyiciyi..

7. Code and Text Editor penceresinde PhoneBook. Göreviniz bu düğmeleri çalışır duruma getirmek için uygulamayı tamamlamak. Dizinleyicileri yazın 1. Code and Text Editör penceresinde PhoneNumber. telefon defterine ad ve telefon numarası ekleyen bir Add yöntemine sahiptir. PhoneBook sınıfı ayrıca.. PhoneBook. Name yapısını inceleyin. sonuncusu da bir telefon numarası verildiğinde ad bulmak için.. kurucuya bir dize olarak sağlanmıştır.cs kaynak dosyasını görüntüleyin. Amacı adlar için bir tutucu görevi görmektir. diğeri bir ad verildiğinde telefon numarasını bulmak için.cs kaynak dosyasını görüntüleyin ve PhoneBook sınıfını inceleyin.. 4. Debug menüsünde Start Without Debugging’ i tıklayın. Code and Text Editor penceresinde Name. Text adlı salt okunur dize özelliği kullanılarak ad alınabilir. Name ve Phone Number olarak adlandırılmış iki boş metin kutusu gösteren bir form belirir. Bu yöntem daha büyük iki dizi yaratır.304 Kısım III Bileşenler Yaratmak 3. Proje oluşturulup çalıştırılır. Bu sınıf iki özel dizi içerir: names adlı Name değerlerini tutan bir dizi ve phoneNumbers adlı PhoneNumber değerlerini tutan bir dizi. Formu kapatın ve Visual Studio 2008’e dönün. Form ayrıca üç düğme içerir: biri bir ad/telefon numarası çifti eklemek için. Kullanıcı başka bir girdi eklediğinde dizilerin dolu olup olmadığını denetlemek için enlargeIfFull yöntemi Add tarafından çağrılır.cs kaynak dosyasını görüntüleyin. Name yapısına çok benzer. PhoneNumber yapısını inceleyin.. (Equals ve GetHashCode yöntemleri Name değerleri dizisinde arama yaparken Names’i karşılaştırmak için kullanılır (şimdilik bunları göz ardı edebilirsiniz). Bu yöntem Add düğmesi tıklandığında çağrılır. Bu düğmeler şu anda hiçbir iş yapmaz. get erişimcisinin gövdesini boş bırakın.cs kaynak dosyasında PhoneBook sınıfına bir Name döndüren ve bir tek PhoneNumber parametresi alan public salt okunur bir dizinleyici ekleyin. Dizinleyici şöyle görünmelidir: sealed class PhoneBook { . var olan dizilerin içeriğini bunlara kopyalar ve ardından eski dizileri atar. 5. public Name this [PhoneNumber number] { get { } } . 6. } . Ad.

Dizinleyici telefon numarasını bulursa onu döndürür.IndexOf(this. -1 değerini döndürür.names[i].) Tamamlanmış get erişimcisi ile dizinleyici aşağıdaki gibi görünür: sealed class PhoneBook { .. IndexOf’un ikinci bağımsız değişkeni. Bunu yapmak için. Erişimcinin görevi.names. Bu dizinleyiciyi birinci ile aynı biçimde geliştirin (yine PhoneNumber’ın bir yapı olduğuna ve bu yüzden her zaman bir varsayılan kurucusu olacağına dikkat edin). IndexOf aranan öğeyi bulursa öğenin dizininin tam sayı değerini döndürür. public PhoneNumber this [Name name] { get { int i = Array... (Name’in bir yapı olduğuna ve her zaman özel alanını null’a eşitleyen bir varsayılan kurucu içereceğine dikkat edin.phoneNumbers. bulamazsa boş bir Name değeri döndürür. } 3..Bölüm 16 Dizinleyicileri Kullanmak 305 2. else return new PhoneNumber(). number). Array sınıfının statik IndexOf yöntemini çağırmanız gerekir. aradığınız öğedir. if (i != -1) return this. public Name this [PhoneNumber number] { get { int i = Array. } . IndexOf’un ilk bağımsız değişkeni.. aksi takdirde IndexOf.phoneNumbers[i]. içinde arama yapılacak dizidir (phoneNumbers).IndexOf(this. İkinci dizinleyici şöyle görünmelidir: sealed class PhoneBook { . PhoneBook sınıfına tek bir Name parametresi alan ve PhoneNumber döndüren ikinci bir public salt okunur dizinleyici daha ekleyin. } } .. IndexOf yöntemi bir dizi boyunca arama gerçekleştirir ve eşleşen dizideki ilk öğenin dizinini döndürür.. belirtilen telefon numarasıyla eşleşen adı bulmaktır. else return new Name(). if (i != -1) return this. } } . get erişimcisini aşağıdaki gibi geliştirin.. name).

Varsa sözdizimi hatalarını düzeltip yeniden oluşturun. Window1. Search by Name düğmesi tıklandığında bu yöntem çağrılır. 1. Form üzerindeki phoneNumber metin kutusuna.Text = phoneBook[new Name(text)]. Dizinleyicileri çağırın 1. Form üzerindeki name metin kutusundan Text özelliğinin değerini okuyun. Aşağıdaki görevleri gerçekleştirmek için. Bu yöntem şu an boştur. yüklemeler aynı imzaya sahip olacaklar ve derlenmeyeceklerdir. . Bu. findPhoneClick yönteminin altındadır. dizeden bir Name nesnesi oluşturmak ve bunu PhoneBook dizinleyicisine bir parametre olarak geçirmek. Code and Text Editor penceresinde. PhoneBook’ta o ada karşılık gelen telefon numarasını bulmak için.Text. 1. Dize bir değere sahipse true. findPhoneClick yöntemi şu şekilde görünmelidir: private void findPhoneClick(object sender.cs dosyasını görüntüleyin ve daha sonra findPhoneClick yöntemini bulun. 2.IsNullOrEmpty(text)) { phoneNumber. kullanıcının yazdığı adı içeren bir dizedir.xaml.xaml. Text dizesi boş değilse.Text.3. aşağıdaki örnekteki kodu ekleyin: 1.1. Name ve PhoneNumber yapılarını birer dize ile değiştirirseniz. RoutedEventArgs e) { string text = name. sahip değilse false döndürür. Window1. if (!String. } } İpucu Bir dizenin boş olup olmadığını hesaplamak için statik String yöntemi IsNullOrEmpty kullanıldığına dikkat edin. bir dizinleyici kullanarak arama yapmak (Form1’in phoneBook adlı özel bir PhoneBook alanı olduğuna dikkat edin).2. Build menüsünde Build Solution’ ı tıklayın. Bir dizenin değer içerip içermediğini hesaplamak için tercih edilen yöntemdir. dizinleyiciden dönen PhoneNumber yapısının Text özelliğini yazmak.cs dosyasında findNameClick yöntemini bulun. 4.306 Kısım III Bileşenler Yaratmak Bu aşırı yüklenmiş dizinleyicilerin aynı anda var olduklarına çünkü imzalarının farklı olduğuna da dikkat edin.

aşağıdaki gibi uygulanması gerekir.Bölüm 16 Dizinleyicileri Kullanmak 307 findName_Click yöntemi Search by Phone düğmesi tıklandığında çağrılır. } } 3. Metin kutularına adınızı ve telefon numaranızı girip Add düğmesini tıklayın.Text.Text = phoneBook[new PhoneNumber(text)]. yazdığınız telefon numaralarını ve adları denetlemez ve siz aynı adı ve telefon numarasını birden fazla yazmış olabilirsiniz. Text dizesi boş değilse. Bu yöntem şu anda boştur.1. RoutedEventArgs e) { string text = phoneNumber. 3. Form üzerindeki name metin kutusuna. 2. Bu karmaşıklıktan kaçınmak için. Add düğmesini tıkladığınızda Add yöntemi girdileri telefon defterine koyar ve arama için hazır duruma gelmeleri için metin kutularını temizler. farklı adlar ve telefon numaraları girdiğinizden emin olun.2. 2. Bir hata oluşursa düzeltin. if (!String. dizinleyiciden dönen Name yapısının Text özelliğini yazmak. Build menüsünde Build Solution’ ı tıklayın. dizinleyici kullanarak arama yapmak.) 2. Bu değer. o telefon numarasına PhoneBook’ta karşılık gelen adı bulmak için. Name metin kutusuna ikinci adımda kullandığınız adı girip Search by Name’ i tıklayın. 4. İkinci adımı farklı adlarla ve farklı telefon numaralarıyla birkaç kez yineleyin ki telefon defteri birkaç giriş içersin. Uygulamayı çalıştırın 1.Text. kullanıcının yazdığı telefon numarasını içeren bir dizedir. . (Kod.IsNullOrEmpty(text)) { name. İkinci adımda girdiğiniz telefon numarası telefon defterinden bulunup Phone Number metin kutusunda görüntülenir. 2. aşağıdaki örnekte koyu harflerle gösterilmiştir. phoneNumber metin kutusundan Text özelliğinin değerini okumak. Tamamlanmış yöntem şu şekilde görünmelidir: private void findNameClick(object sender.3. Debug menüsünde Start Without Debugging’i tıklayın. Not Uygulama.

308 Kısım III Bileşenler Yaratmak 5.. Name kutusuna tümüyle yeni bir ad girip Search by Name’ i tıklayın. } Bir arabirimde bir dizinleyici tanımlamak Dizinleyiciyi get ve/veya set anahtar sözcükleri ile tanımlayın. Ad telefon defterinden bulunup Name metin kutusunda görüntülenir. } . Phone Number metin kutusuna bir telefon numarası yazın ve daha sonra Search by Phone’u tıklayın. bunun anlamı adın telefon defterinde bulunamadığıdır. Örneğin: interface IRawInt { bool this [ int index ] { get. Bu kez Phone Number kutusu boştur... } } . Bölüm 16 Hızlı Başvuru Bunun İçin Bir sınıf ya da yapı için dizinleyici yaratmak Şunu Yapın Dizinleyicinin türünü bildirin. 6. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 17’e geçin. Örneğin: struct RawInt { . Dizinleyicinin gövdesi bir get ve/veya set erişimcisi içerebilir.. Save iletişim kutusu görünürse.. ardından anahtar sözcük this’i ve köşeli parantez arasında dizinleyici bağımsız değişkenlerini ekleyin. public bool this [ int index ] { get { . } set { .. } set. 7.. Formu kapatın ve Visual Studio 2008 programlama ortamına dönün..

ancak dizinleyici erişilebilirliğini belirtmeyin....... bool IRawInt. Örneğin: struct RawInt : IRawInt { .this [ int index { get { . } ] Bir sınıf ya da yapıda açık arabirim geliştirmesi kullanarak bir arabirim dizinleyicisi geliştirmek Arabirimi geliştiren sınıf ya da yapıda arabirimi açıkça adlandırın... } set { . } ] .. Örneğin: struct RawInt : IRawInt { . } } ....Bölüm 16 Dizinleyicileri Kullanmak 309 Bir sınıf ya da yapıda bir arabirim dizinleyicisi geliştirmek Arabirimi geliştiren sınıf ya da yapıda dizinleyiciyi tanımlayın ve erişimcileri geliştirin. public bool this [ int index { get { .... } } . } set { ..

.

Bir form. Çağrılan bir temsilci sıradan bir yöntem gibi görünür ve davranır. Belirli bir yönteme başvurmak için temsilcilerin örneklerini yaratmak. bir temsilciyi çağıran kod aslında her 311 . Bir temsilci kullanarak bir olayı işlemek. Bu yaygın bir senaryo olsa da bazen çalışma sırasına müdahale etmenin ve başka. Bir temsilci kodunu belirtmek için. Önce temsilcilere bakacağız. Ancak. Bu tür bir işlem yalnızca grafik arabirimler için değil. ifadelerin sıralı olarak çalıştığını varsaymaktaydı. nükleer santralin aşırı ısınması durumunda reaktörün kapatılması gibi). Bir olay alanı bildirmek. düğme ve metin kutusu gibi denetimler içerir. dolayısıyla. Bir olayı başlatmak. Bir düğmeyi tıkladığınızda ya da metin kutusuna metin yazdığınızda formun hemen yanıt vermesini beklersiniz. Temsilciler Bildirmek ve Kullanmak Temsilci bir yöntemi işaret eder ve bir yöntemi çağırdığınız gibi çağırabilirsiniz. Bu tür bir uygulamayı işlemek için çalışma zamanı iki şey sağlamak zorundadır: Acil bir şeyin olduğunu göstermenin bir yolu ve bu olduğunda çalışan bir yöntem. Olayların ve temsilcilerin görevi budur. bir lambda deyimi tanımlamak. Görev tamamlanınca program bıraktığı yerden devam edebilir. Şu ana dek kitaptaki çeşitli alıştırmalarda yazdığınız kodun büyük bölümü.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n n n Bir yöntem imzasının soyutlamasını yaratmak için bir temsilci bildirmek. bir temsilciyi çağırdığınızda çalışma zamanı aslında temsilcinin başvurduğu yöntemi çalıştırır. Bu tür programın klasik örneği Microsoft Windows Presentation Foundation (WPF) formudur. Uygulama geçici olarak yaptığı şeyi durdurmak ve sizin girdinizi işlemek durumundadır. daha önemli bir görevi yapmanın gerekli olduğunu görürsünüz. bir işlemin acil olarak gerçekleştirilmesinin gerektiği her uygulama için geçerlidir (örneğin. Temsilcinin başvurduğu bir yöntemi dinamik olarak değiştirebilirsiniz. Bir temsilci üzerinden bir yöntem çağırmak.

Her makinenin güvenle kapanmak için kendine özgü bilgisayar denetimli bir süreci (API) vardır. bu yüzden gelin bir örnek üzerinde çalışalım. private WeldingMachine welder. işlev işaretçilerinin aksine. FinishWelding(). // makineyi şekillendirmek // makineyi kaynaklamak // makineyi boyamak Temsilci Kullanmadan Fabrika Senaryosunu Uygulamak Denetim programında kapatma işlevini uygulamanın basit bir yöntemi aşağıda gösterilmiştir: class Controller { // farklı makineleri temsil eden alanlar private FoldingMachine folder. PaintOff(). Her makine uzman kişilerce üretilip kurulmuştur. . Ancak. temsilciler tür güvenlidir. birbirine kaynak yapan.NET Framework’u bir API’ler topluluğu olarak düşünebilirsiniz çünkü .. Fabrika. Bir yazılımı denetleyebilmeniz için yazılım tarafından sağlanan bir yöntem ya da yöntemler topluluğudur. . gibi) farklı görevler gerçekleştirilen birçok farklı makine içerir. Sizin göreviniz. “Application Programming Interface”in kısaltmasıdır. boyayan vb. gerektiğinde tüm makineleri kapatacak bir yöntem sağlamaktır! Not API.312 Kısım III Bileşenler Yaratmak çalıştığında farklı bir yöntem çalıştırabilir.. Makinelerin tümü bilgisayar denetimli olup her dağıtıcı makinelerini denetlemeniz için bir dizi API (Uygulama Programlama Arabirimi) sağlamıştır. Temsilcileri anlamanın en iyi yolu onları işbaşında görmektir. private PaintingMachine painter. Otomasyonlu Fabrika Senaryosu Otomasyonlu bir fabrika için denetim sistemlerini yazdığınızı varsayalım. makineler tarafından kullanılan farklı sistemleri tek bir denetleme programında birleştirmektir.NET çalışma zamanı katmanı ve Microsoft Windows işletim sistemini denetlemenizi sağlayan yöntemler sağlar. Bunlar aşağıda özetlenmiştir: StopFolding(). işlev işaretçisine benzer. Odaklanmaya karar verdiğiniz yönlerden birisi. bir temsilcinin yalnızca temsilcinin imzasıyla eşleşen bir yönteme başvurmasını sağlayabilirsiniz ve geçerli bir yönteme başvurmayan bir temsilciyi çağıramazsınız. Not C++ biliyorsanız bir temsilci. üretimde (metal folyoları biçimlendiren ve büken. .

} .Bölüm 17 public void ShutDown() { folder. private stopMachineryDelegate stopMachinery.. Bir temsilciyi aşağıdaki gibi bildirirsiniz: delegate void stopMachineryDelegate(). Bu şekille eşleşen bir temsilci makine kapatma yöntemlerinden herhangi birine başvurmak için kullanılabilir.PaintOff(). parametre almazlar ve bir değer döndürmezler (durum böyle olmadığı zaman ne olduğunu sonra göreceğiz. Temsilci Kullanarak Fabrika Senaryosunu Uygulamak Her yöntemin adı farklı olsa da aynı “şekle” sahiptirler. controller sınıfının kurucusunda aşağıdaki gibi yapabilirsiniz: class Controller { delegate void stopMachineryDelegate(). welder. Siz dönüş türünü (bu örnekte.stopMachinery += folder.StopFolding. temsilci adını (stopMachineryDelegate) ve varsa parametreleri (burada yoktur) belirtirsiniz. void). Fabrika yeni bir makine alsa bu kodu değiştirmeniz gerekir. } Program Akışını Kesmek ve Olayları İşlemek 313 Bu yaklaşım çalışsa da çok genişletilebilir ya da esnek değildir. public Controller() { this.StopFolding()... } . } . Temsilciyi tamamladıktan sonra örneği yaratabilir ve += işlecini kullanarak eşleşen yönteme başvurmasını sağlayabilirsiniz. Dolayısıyla. her yöntemin genel biçimi aşağıdaki gibidir: void methodName(). Bunu. Controller (Denetleyici) sınıfıyla makineler sıkı sıkıya eşleşmiştir. painter. sabırlı olun!).FinishWelding()... İşte temsilci burada işe yarar. Aşağıdaki noktalara dikkat edin : n n Bir temsilci bildirirken delegate anahtar sözcüğünü kullanın.. Bir temsilci başvurabileceği yöntemlerin şekillerini tanımlar. // an instance of the delegate .

StopFolding. tek bir özel yöntemle açıkça başlatabilirsiniz: this.stopMachinery += folder.stopMachinery(). Yalnızca yöntemin adını belirttiğinize ve herhangi bir parantez ya da parametre eklememeniz gerektiğine dikkat edin. bu aşamada yöntemi çağırmanız söz konusu değildir. -= işlecini kullanarak bir yöntemi temsilciden silebilirsiniz: this.StopFolding). } Controller sınıfının Shutdown (Kapat) yöntemindeki this. Başlatılmamış temsilci üzerinde += işlecini kullanmak güvenlidir.stopMachinery += welder. aşağıdaki gibi new anahtar sözcüğünü kullanarak bir temsilciyi. this.stopMachinery -= folder. Temsilciye yöntemi eklersiniz. Bir temsilci kullanmanın asıl yararı birden çok yönteme başvurabilmesidir.. . Not Başlatılmamış bir temsilciyi çalıştırmaya çalışırsanız bir NullReferenceException özel durumu oluşur. Otomatik olarak başlatılacaktır. this. Shutdown yönteminin kaç adet makine bulunduğunu ya da yöntemlerin adlarının ne olduğunu bilmesi gerekmez. Ayrıca.stopMachinery = new stopMachineryDelegate(folder.stopMachinery()’yi çalıştırmak otomatik olarak her yöntemi sırayla çağırır.StopFolding. } Bir temsilciyi çalıştırma bir yöntem çağrısı yapmayla aynı sözdizimini kullanır.PaintOff.FinishWelding. Bunları aşağıdaki gibi temsilciye eklemek için += işlecini kullanmanız yeterlidir: public Controller() { this. Temsilciyi aşağıdaki gibi çalıştırarak yöntemi çağırabilirsiniz public void ShutDown() { this..314 Kısım III Bileşenler Yaratmak Bu sözdizimine alışmak biraz zaman alabilir. Temsilcinin başvurduğu yöntem parametre alıyorsa bunları bu aşamada belirtmeniz gerekir. .stopMachinery += painter. Temsilcilerle kullanıldığında + işleci bu yeni anlamı taşımak için aşırı yüklenmiştir (İşleçler hakkında daha fazla bilgiyi Bölüm 21’de bulabilirsiniz).

stopMachinery += stopMethod. public stopMachineryDelegate StopMachinery { get { return this. stopMachineryDelegate türünü genel yapmanız ve Controller dışındaki sınıfların temsilciye yöntem eklemesinin bir yolunu bulmanız gerekir. } } n Ayrı Add ve Remove yöntemleri uygulayarak tam bir kapsülleme sağlayın. Ancak. Birkaç seçeneğiniz vardır: n stopMachinery temsilci değişkenini genel yapın: public stopMachineryDelegate stopMachinery. Controller sınıfinı çeşitli makinelerden tam bağımsız kılmak için. makine yöntemlerini Controller kurucusundaki temsilciye ekler.stopMachinery = value. . ..Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 315 Geçerli düzen.stopMachinery.stopMachinery -= stopMethod. } public void Remove(stopMachineryDelegate stopMethod) { this. } Nesne yönelimli programcılıktan ödün vermeyenlerdenseniz büyük olasılıkla Add/Remove yaklaşımını benimseyeceksiniz. (Bir temsilci türü kullanarak bir yöntemi parametre olarak belirttiğinize dikkat edin): public void Add(stopMachineryDelegate stopMethod) { this. diğerleri de sık kullanılan alternatifler olduğundan burada gösterilmektedirler. } set { this. ancak buna erişim sağlamak için bir okuma/yazma özelliği sağlayın: public delegate void stopMachineryDelegate().. Add yöntemi bir yöntemi parametre olarak alıp temsilciye eklerken Remove yöntemi belirtilen yöntemi temsilciden kaldırır. n stopMachinery temsilci değişkenini özel olarak tutun.

Bir dijital saat gösteren form görünür. control. saat yanlış zamanı göstermektedir. Bu sınıf bir olay (olaylar ileride açıklanmaktadır) kullanarak titreşimi yakalar ve sonra bir temsilci çağırarak görüntünün güncelleştirilmesini sağlar. Proje oluşturulur ve çalıştırılır. bir WPF form üzerinde dijital saat olarak davranan bir metin kutusunda zamanı gösteren bir yöntemi kapsüllemek için bir temsilci yaratacaksınız.PaintOff). diğer makineleri temsil eden bir Controller ve nesneleri aşağıdaki gibi başlatabilirsiniz (bu örnekte Add/ Remove yaklaşımı kullanılmıştır): Controller control = new Controller(). . 3. Start’ı. 2.Add(welder.. Sizin göreviniz bu yöntemleri geliştirmektir 5. . Hiçbir şey olmaz. control. her saniye bağlı temsilciyi çağıran Ticker adında bir sınıfa bağlayacaksınız. Ticker. . Start ve Stop yöntemleri henüz geliştirilmemiştir.Add(folder.. Temsilciler Kullanmak Şimdiki alıştırmada. Saat o anki saati “00:00:00” olarak gösterir. 6. Formu kapatın ve Visual Studio 2008 ortamına geri dönün. control. FoldingMachine folder = new FoldingMachine().Timer nesnesi kullanır..316 Kısım III Bileşenler Yaratmak Hangi tekniği seçerseniz seçin makine yöntemlerini temsilciye ekleyen kodu Controller kurucusundan kaldırmanız gerekir. sonra da Stop’u tıklayın. Her saniye bir titreşim göndermeyi sağlayan ticking adlı bir System. PaintingMachine painter = new PaintingMachine(). Bu dosya bir saatin iç çalışma düzenini modelleyen Ticker adlı bir sınıf içerir.cs kaynak dosyasını açıp Code and Text Editor penceresinde görüntüleyin.Timers.FinishWelding). Bu temsilci nesnesini. WeldingMachine welder = new WeldingMachine(). Microsoft Visual Studio 2008’i başlatın.StopFolding)... Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 17\ Delegates klasöründe yer alan Delegates projesini açın. 4. . Bu bölümü gece yarısı okumuyorsanız.. Dijital saat uygulamasını tamamlayın 1.Add(painter. Debug menüsünde Start Without Debugging’ i tıklayın. Daha sonra.ShutDown(). control.

dakika ve saniye) tarafından belirtilen zamanı göstermek için bir dizeyi biçimlendiren ve sonra bunu display adlı TextBox alanında görüntüleyen RefreshTime adlı bir yöntemi vardır. . int mm. } . Başlatıldıklarında saatin çalışmasını başlatan ve durduran Start ve Stop adlı yöntemleri ve üç parametre (saat. } public void Remove(Tick oldMethod) { this.. public void Add(Tick newMethod) { this.NET Framework. System. } ... Tick temsilcisi.Timer adında başka bir zamanlayıcı sınıfı sağlar. eşleşen yöntemleri tickers temsilci değişkenine ekleyip kaldırabilirsiniz. 7. Bu TextBox alanı kurucuda başlatılır. bu türe bağlı tickers adlı bir temsilci değişkeni vardır. üç tamsayı parametresi alan ancak bir değer döndürmeyen bir yönteme başvurmak için kullanılabilir. class Ticker { .. Clock sınıfı saat görüntüsünü modeller. görüntülenen zamanın ne zaman güncelleştirileceğini saate bildirir: class Clock { .tickers -= oldMethod..Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 317 Not . Bu sınıf. Sınıfın sonunda. int ss).. Bu sınıftaki Add ve Remove yöntemleri kullanarak (aşağıdaki kod örneğinde gösterilmiştir).. Clock.Timers.. } 8. public Clock(TextBox displayBox) { this. Code and Text Editor penceresinde Tick temsilcisinin bildirildiği yeri bulun. Sınıf ayrıca pulsed adlı özel bir Ticker alanı içerir ve bu.tickers += newMethod. DispatcherTimer sınıfı ile aynı işlevselliği sağlar fakat bir WPF uygulamasında kullanmak için uygun değildir.display = displayBox.cs kaynak dosyasını açıp Code and Text Editor penceresinde görüntüleyin. Neredeyse dosyanın en üstündedir ve aşağıdaki gibi görünür: public delegate void Tick(int hh. private Tick tickers.

Start yöntemi aşağıdaki gibi görünür: public void Start() { pulsed. Window1. bunun çıktısını bu TextBox denetiminde görüntüleyecektir. pulsed temsilcisi çağrılır ve bu ifade RefreshTime yönteminin uygulanmasına neden olur.Stop yöntemini çağırıyor olmasıdır. Ticker. Debug menüsünde Start Without Debugging’i tıklayın. private TextBox display. Clock sınıfı.Remove yöntemini kullanarak pulsed nesnesindeki Clock.Remove(this. WPF form üzerinde Start’ı tıklayın.318 Kısım III Bileşenler Yaratmak private void RefreshTime(int hh.RefreshTime). Stop yöntemi aşağıdaki gibi görünür: public void Stop() { pulsed. Stop düğmesinin artık RefreshTime yöntemini Ticker temsilcisinden ayıran Clock. Ticker. } 9. } 11.cs kaynak dosyasına dönün. Görüntü tepki vermeyi keser ya da “donar”. 13. clock = new Clock(digital).Format(“{0:D2}:{1:D2}:{2:D2}”. parametre olarak digital adlı bir TextBox alanından geçen Clock sınıfı için yeni bir örnek yarattığına dikkat edin: public Window1() { .Add yöntemini kullanarak pulsed nesnesindeki Clock. Clock.. Kurucunun. ss). Form şimdi doğru zamanı görüntüler ve her saniye güncellenir. 10.RefreshTime yöntemini temsilciye eklemesi için Clock. Diğer bir deyişle.Stop yöntemini başlatın.Text = string. } Dijital alan formda görüntülenen TextBox denetimidir.Add(this. artık RefreshTime her saniye çağrılmaz.Start yöntemini aşağıdaki gibi geliştirin.RefreshTime yöntemini temsilciden kaldırması için Clock. mm.. } private Ticker pulsed = new Ticker(). Bir an geçtiğinde.display. int ss ) { this. . 14. hh. int mm. Bunun nedeni.xaml.RefreshTime). } 12. Stop’ u tıklayın.cs kaynak dosyasının kodunu Code and Text Editor penceresinde görüntüleyin.

Start düğmesinin artık RefreshTime yöntemini Ticker temsilcisine bağlayan Clock. Tekrar Start’ı tıklayın. Bir Yöntem Bağdaştırıcısı Yaratmak Bu problemi çözmenin yolu. Bunun nedeni. Örneğin. aynı sözdizimini kullanarak. 16. daha önce gösterilen otomasyonlu fabrika senaryosuna dönersek.Start yöntemini çağırıyor olmasıdır.FinishFolding. Saat durmadan önce bu başvuruların tümünü kaldırmanız gerekir. temsilciye RefreshTime yöntemine bir başvuru eklersiniz. Formu kapatın ve Visual Studio 2008 ortamına geri dönün. // Belirlenen saniyeler içinde kapat Bu şimdi FinishWelding ve PaintOff yöntemlerinden farklı olduğundan tüm üç yöntemi işlemek için aynı temsilciyi kullanamayız. Start’ı her tıkladığınızda. Görüntü işlemeye devam eder ve zamanı her saniye güncelleştirir. folder nesnesinin StopFolding (DurdurKatlama) yöntemini stopMachinery (durdurMekanizma) temsilcisine eklemek için aşağıdakini yaptık: this. 15. // Hemen kapat } Daha sonra.StopFolding(0). . Stop’u da aynı sayıda tıklamanız gerekir.stopMachinery += folder.StopFolding. ancak ya durum bu değilse? StopFolding yönteminin gerçekte aşağıdaki imzaya sahip olduğunu düşünün: void StopFolding(int shutDownTime). stopMachinery temsilcisine StopFolding yöntemi yerine FinishFolding yöntemini ekleyebilirsiniz: this.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 319 Not Start’ı birden çok tıklarsanız. aşağıdaki gibi. Temsilcinin imzasıyla eşleşen uygun bir yöntem varsa bu yaklaşım çok yararlıdır. Lambda Deyimler ve Temsilciler Şu ana dek gördüğünüz bir temsilciye bir yöntem eklemeyle ilgili tüm örnekler yöntemin adını kullanır. StopFolding’i çağıran ama kendisi hiçbir parametre almayan başka bir yöntem yaratmaktır: void FinishFolding() { folder.stopMachinery += folder.

stopMachinery += () => { folder. Bunun için aşağıdaki ifadeyi kullanabilirsiniz: this. Lambda deyimler karmaşık değildir ve sözdiziminin kullanımını anladıktan sonra. Bir lambda deyimi bu öğelerin iki tanesini içerir: parametre listesi ve yöntem gövdesi. => işleci. Johnson ve Vlissides’in yazdığı Design Patterns: Elements of Reusable Object Oriented Architecture (Addison-Wesley Professional. Yöntem gövdesi. 1994) adlı kitapta belgelendirilmiştir Birçok durumda. parametre almayan bir bağdaştırıcı yaratmanız gerekmesidir. Not FinishFolding yöntemi bağdaştırıcıya klasik bir örnektir. FoldingMachine sınıfının StopFolding yönteminde problem. Bununla birlikte. Helm. C#’da şimdiye kadar gördüğünüz deyimlerin çoğu bir değer döndürdüğünden. }. parantezleri yazmanız gerekir. tek bir ifade içerir. çok yararlı olduklarını göreceksiniz. stopMachinery temsilcisine eklenen yöntemi tanımlar.320 Kısım III Bileşenler Yaratmak stopMachinery temsilci çağrıldığında. C# bunun gibi durumlar için lambda (adsız) deyimler sağlar. yöntem adı. Üstelik ShopFolding yönetimini temsilcinin kullanımı için bağdaştırmaları dışında başka bir yerde çağrılmaları pek düşük bir olasılıktır. bir lambda deyiminin gövdesi birden fazla ifade içeren bir yöntem gövdesi olabilir ya da gerçekten tek bir deyim olabilir.StopFolding(0). lambda deyiminin kullanıldığı içerikten çıkarılır. tanımladığınız yöntem (önceki alıştırmadaki gibi) bir parametre almıyorsa da. bu kavram da size yabancı gelmez. özellikle büyük bir sınıf içinde. Bölüm 3’te. Bir lambda deyiminin gövdesi tek . Lambda deyimleri bir yöntem adı tanımlamaz ve dönüş türü (eğer varsa). bunun gibi bağdaştırıcı yöntemler küçük olup bir yöntemler denizinde kaybolmaları olanaklıdır. stopMachinery temsilcisine ekleyebileceğiniz. bu yöntemin şimdi iki parametre alması. += işlecinin sağ tarafındaki metnin tümü bir lambda deyimidir. Burada gösterilen örnek oldukça basittir. Bu kalıp çok yaygın olup Gamma. Sıradan bir yöntemde olduğu gibi. Lambda Deyimini Bağdaştırıcı Olarak Kullanmak Lambda deyimi. bu biraz garip gelebilir. Sadece her ifadeden sonra noktalı virgül eklemeyi unutmayın. n n Açık konuşmak gerekirse. bir lambda deyimi birden fazla ifade içerebilir ve bu ifadeleri istediğiniz biçimde yazabilirsiniz. bu nedenle. yöntem döndüren bir deyimdir. parametre listesi ve yöntem gövdesi. Haskell gibi işlevsel programlama dillerine aşina iseniz. C# derleyicisine bunun bir lambda deyimi olduğunu gösterir. farklı bir imza vermek için bir yöntemi dönüştüren (ya da bağdaştıran) bir yöntem. Aşağıdaki sözdizimi kurallarını izler: n Parametre listesi küme parantezi içinde yer alır. 0 parametresini geçiren ve StopFolding yöntemini çağıran FinishFolding yöntemi çağrılır. tipik bir yöntemin dört öğe içerdiğini gördünüz: dönüş türü.

StopFolding(0) . x => { return x * x . } // // // // // (ref int x.StopFolding(0) // // // // (x. lambda deyimlerinin uygulanmasında. lambda deyimi tarafından tanımlanan kod çalışacaktır. Parametre x değeri tarafından geçirilir. stopMachinery temsilcisini çağırdığınızda. derleyici parametre türleri çıkarır. bir değer döndüren yöntem olarak düşünebilirsiniz) tanımlamak için bir gösterim sağlayan Lambda Calculus adı verilen matematiksel bir gösterimin parçasıdır. Lambda Deyimlerinin Biçimi Lambda deyimler. Birden çok parametre açık türlere sahip Parametre x başvuru tarafından geçirilir böylece ++ işleminin etkisi kalıcıdır. böylece ++ işlemi ifade ile kısıtlı kalır. ama döndürmeyebilir de. küme parantezlerini ve noktalı virgülü kullanmayabilirsiniz (ifadeyi tamamlamak için yine de bir noktalı virgül gerekmektedir): this. C#’da bulunan lambda deyiminin farklı biçimleri aşağıda gösterilmiştir: x => x * x // Parametrenin karesini döndüren basit bir ifade // Parametre x türü bağlamdan çıkarılır. Bir yöntem çağırma ifade hiçbir parametre almıyor. işlevleri (işlevi. C# dili. Birden çok parametre. birçok orijinal ilke yine de uygulanır. return x / y. } // Semantik olarak önceki ifadeyle aynı // ama gövde olarak basit bir ifade yerine // C# ifade bloku kullanır (int x) => x / 2 // Parametrenin 2’ye bölünen değerini // döndüren basit bir ifade // Parametre x türü açık şekilde belirtilir. () => folder. int y) { x++. Lambda deyimler aslında.stopMachinery += () => folder. return x / y. } // // // // // Lambda deyiminin bilmeniz gereken bazı özellikleri aşağıda özetlenmiştir: . çok sayıda farklı biçim alabilir. Lambda Calculus sözdizimini ve anlam bilimini geliştirmiş olmakla birlikte. ifade bir değer döndürebilir.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 321 bir deyim içeriyorsa. y) => { x++.

}. parametreleri başvuru yoluyla (ref anahtar sözcüğünü kullanarak) geçirebilirsiniz. Bu özelliğe çok dikkat edin! n n n n Kitabın sonraki bölümlerinde. Lambda Deyimler ve Anonim Yöntemler Lambda deyimler.StopFolding(0). Lambda deyiminin gövdesi. gerekli parametreler delegate anahtar sözcüğünden sonra küme parantezi içinde belirtilir.0 sürümünde. parametreleri => işlecinin solunda parantez içinde yazarsınız. anonim yöntemlerinin sözdiziminden daha kısa ve öz sözdizimi olduğunu ve C#’ın ileri seviye yaklaşımlarının birçoğunda yaygınlaştığını göreceksiniz. temsilci yerine bir anonim yöntemi parametre olarak geçirebilirsiniz: control. fakat bu önerilmez. Örneğin: control. adlandırılmış bir yöntem yaratmak zorunda kalmadan temsilciler tanımlayabilmeniz için eklenmiştir. } ). dönüş değerlerinin ekleneceği temsilciyle eşleşmesi gerekir. benzer bir görev gerçekleştiren fakat lambda deyimler gibi esnek olmayan anonim yöntemler sunulmuştu. C# diline 3. Bir anonim yöntemi yazarken önce delegate anahtar sözcüğünü yazmanız gerektiğine dikkat edin. C# 2.322 Kısım III n Bileşenler Yaratmak Lambda deyimi parametre alıyorsa. parametreler alan ve değerler döndüren daha fazla örnek göreceksiniz. Genel anlamda. değişken bildirimleri bulunan bir C# kod bloğu olabilir. }).Add(delegate { folder. tanımlandığı kapsam dışındaki değişkenlerin tümüne erişebilir ve değiştirebilir. Lambda deyimleri değerler döndürebilir fakat dönüş değerlerinin türünün. string param2) { /* code that uses param1 and param2 */ .0 sürümünde eklenen yeni bir eklentidir. Ayrıca aşağıdaki gibi. Anonim yöntemler öncelikle.Add(delegate(int param1.. Lambda deyimi yönteminde tanımlanan değişkenler. aşağıdaki gibi basitçe yöntem adı yerine yöntem gövdesinin tanımını sağlarsınız: this. lambda deyimleri hakkında daha fazla bilgi bulacak. Lambda deyimi..stopMachinery += delegate { folder. Ayrıca. Parametre türlerini belirtmeyebilirsiniz. yöntem çağrıları.StopFolding(0). . C# derleyicisi lambda deyiminin içeriğinden çıkaracaktır. Lambda deyiminin değerlerini kapsam dışında da değiştirebilmesini istiyorsanız. basit bir deyim ya da birden fazla ifade. Lambda deyimlerinin. kodunuzda anonim yöntemlerden çok lambda deyimler kullanmalısınız. yöntem bittiğinde kapsam dışına çıkar.

Ayrıca kendi olaylarınızı da tanımlayabilirsiniz. Bir olay bildirmek için aşağıdaki sözdizimini kullanın: event delegateTypeName eventName Örneğin. bir makine aşırı ısındığında stopMachinery temsilcisini başlatmak ve makineyi durdurmak önemli olabilir. olay kaynağı olarak düşünülmüş bir sınıfta bildirirsiniz. Çağrılan olay bir yöntemler listesi barındırır..Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 323 Bildirimleri Olaylarla Etkinleştirmek Bir önceki bölümde. olay için Controller sınıfından daha mantıklı bir yerdir): class TemperatureMonitor { public delegate void StopMachineryDelegate(). . işte otomasyonlu fabrikadaki StopMachineryDelegate temsilcisi. yani makineleri kapatmaya hazır olmalıdır. Bir olay kaynağı genellikle çevresini izleyen ve önemli bir şey olunca bir olay çağıran bir sınıftır.NET Framework’deki birçok sınıf. bu hikayenin yarısıdır. } . Bir Olay Bildirmek Bir olayı. Bir makinenin ısı sınırını geçtiğini (makinenin aşırı sıcak olduğunu) belirleyen ısı izleyici sınıfı bir “machine overheating” (makine aşırı ısınması) olayı çağırır. olaylar sergiler. her makinenin ısısını izleyen bir sınıf olabilir. temsilcinin nasıl çağrıldığını ve temsilci örneklerinin nasıl yaratıldığını gördünüz. Bu yöntemler “makine aşırı ısınması” olayını işlemeye ve gerekli önlemi almaya. Ancak. önemli bir şey olduğunda temsilciyi otomatik olarak çalıştırmak yararlı olur. Bu yöntemlere bazen aboneler denir.. olaylar temsilcilerle kullanılmak üzere tasarlandıklarından bir olayın türü bir temsilci olmalıdır ve siz bildirimin önüne event anahtar sözcüğünü koymalısınız.NET Framework’te olaylar önemli eylemleri tanımlayıp yakalamanıza ve durumu işlemek için bir temsilci ayarlamanıza olanak verir. . Bir olayı. Otomasyonlu fabrikada bir olay kaynağı. Örneğin. makinelerin ısısını izleyen çeşitli elektronik algılayıcılara bir arabirim sağlayan TemperatureMonitor adlı yeni bir konuma yerleştirilmiştir (burası. otomasyonlu fabrika senaryosunda. bir alanı bildirir gibi bildirirsiniz. Ancak. Bir WPF formu üzerine yerleştirebileceğiniz denetimlerin çoğu ve Windows sınıfının kendisi. Bu. bir temsilci türünün nasıl bildirildiğini. Birçok durumda. örneğin kullanıcı bir düğmeyi tıkladığı ya da bir alana bir şey yazdığında kodu çalıştırmanız için olayları kullanır. . Temsilciler herhangi bir sayıda yöntemi dolaylı olarak başlatmanıza izin verse de temsilciyi açık biçimde başlatmanız gerekir.

324 Kısım III Bileşenler Yaratmak stopMachineryDelegate temsilcisini çağıracak olan MachineOverheating olayını şu şekilde tanımlayabilirsiniz: class TemperatureMonitor { public delegate void StopMachineryDelegate(). olaylar da += işleciyle hazır olarak gelirler. public event StopMachineryDelegate MachineOverheating. . }.MachineOverheating olayı çalışınca abone olan tüm yöntemleri çağırır ve makineleri kapatır.. TemperatureMonitor tempMonitor = new TemperatureMonitor()... Otomasyonlu fabrikada her makineyi denetleyen yazılım.StopFolding(0). yöntemleri olayın dayandığı temsilciye eklemek yerine olayın kendisine eklersiniz (olaya subscribing (abone olmak) olarak bilinen işlem). Bu eyleme genellikle bir olay aboneliğini iptal etmek denir. tempMonitor. tempMonitor.MachineOverheating += () => { folder.. tempMonitor. aşağıdaki gibi kapatma yöntemlerinin çağrılmasını sağlayabilir: class TemperatureMonitor { public delegate void StopMachineryDelegate().. tempMonitor. Sözdiziminin bir temsilciye bir yöntem eklemekle aynı olduğuna dikkat edin. olayın içindeki bağlı temsilciler koleksiyonundan çıkarır.PaintOff. } TemperatureMonitor sınıfındaki mantık (burada gösterilmemiştir) otomatik olarak MachineOverheating olayını gerektiği gibi çağırır. } . Bir Olaya Abone Olmak Temsilciler gibi. MachineOverheating olayı çağrıldığında.. Ayrıca..MachineOverheating += welder. public event StopMachineryDelegate MachineOverheating.MachineOverheating += painter. Bir Olay Aboneliğini İptal Etmek Bir temsilciyi bir olaya bağlamak için += işlecinin kullanıldığını bilerek. .. .FinishWelding. Bir olaya abone olmak için bu += işlecini kullanırsınız. Hatta bir lambda deyimi kullanarak da abone olabilirsiniz. bir temsilciyi bir olaydan ayırmak için -= işlecinin kullanılacağını tahmin edebilirsiniz. -= işlecini çağırmak temsilciyi. “Bir Olayı Çağırmak” başlıklı bir sonraki bölümde bir olayı nasıl kaldıracağınızı göreceksiniz. .

bir olay da bir yöntem gibi çağrılabilir. RoutedEventHandler temsilcisi iki parametre ister. Olayı tanımlayan temsilci parametre isterse. .. public event StopMachineryDelegate MachineOverheating. Yöntemi sınıf dışında çağırma girişimleri bir derleyici hatasıyla sonuçlanır. WPF Kullanıcı Arabirimi Olaylarını Anlamak Daha önce söz edildiği gibi. aşağıda MachineryOverheating olayını çağıran bir özel Notify yöntemi ile TemperatureMonitor sınıfını görebilirsiniz: class TemperatureMonitor { public delegate void StopMachineryDelegate.. çünkü bir olay alanı dolaylı olarak null’dur ve yalnızca bir yöntem += işlecini kullanarak ona abone olunca null olmaz. Bir null olayı çağırmaya çalışırsanız bir NullReferenceException özel durumu oluşur. Bir olayı çağırdığınızda bağlı olan bütün temsilciler sırayla çağrılır.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 325 Bir Olayı Çağırmak Tıpkı bir temsilci gibi. RoutedEventHandler türünde Click adlı bir genel olay devralarak türer. olayın çağrılmasına neden olan nesneye bir başvuru ve olayla ilgili ek bilgi içeren bir RoutedEventArgs nesnesi: public delegate void RoutedEventHandler(Object sender. RoutedEventArgs e). null denetimi gereklidir.MachineOverheating != null) { this.NET Framework sınıfları ve denetimleri olayları bolca kullanırlar.. Bu kitabın ikinci yarısında GUI olaylarını birçok yerde görecek ve kullanacaksınız. Örneğin. Genel bir olay (MachineOverheating gibi) yalnızca sınıf (TemperatureMonitor sınıfı) içinde tanımlı yöntemler tarafından çağrılabilir. olayı çağırdığınızda uygun bağımsız değişkenler sağlanmalıdır. Button sınıfı ButtonBase sınıfından. private void Notify() { if (this. } } . Örneğin. Bunun bazı örneklerini ileride göreceksiniz. . Önemli Olaylar çok yararlı bir yerleşik güvenliğe sahiptir. Genel Benzersiz Tammlayıcı) oluşturmak için kullanılan ..MachineOverheating(). GUI (Globally Unique Identifier. } Bu yaygın bir deyimdir.

Controls..Windows. System. Olaylar. } Bu kod genellikle sizden saklanır.. .. seçilen bir yöntem için temsilci yaratma ve bu temsilciyi gerekli bir olaya bağlama işini kolaylaştırır.. } Ekrandaki düğmeyi tıkladığınızda Button sınıfı otomatik olarak Click olayını başlatır (bunun nasıl olduğu kitabın kapsamı dışındadır).Windows.Window..okayClick)... Visual Studio 2008 bu kodu sizin için üretir. Visual Studio 2008’te Design View kullandığınızda ve formun Extensible Application Markup Language (XAML) tanımında. okay adlı bir düğme.Windows. . private void okayClick(object sender. . okayClick’e okay düğmesinin Click özelliğini atadığınızda. olay işleme yöntemi.Click += new System.xaml. } .Button okay..Windows.Connect(. uygulama mantığınızı.IComponentConnector { internal System...Markup.. public partial class Example : System.Windows. this.Markup.. İlk bağımsız değişken her zaman .Window { . } public class Button: ButtonBase { .. void System. okayClick’de yazmaktır. okayClick adlı bir yöntem ve okay düğmesi içindeki Click olayını okayClick yöntemine bağlayan kodu içeren bir WPF formunu gösteriyor: public partial class Example : System.cs dosyasında erişmeniz gereken kod parçasında.Windows. imzası bir void dönüş türü ve iki bağımsız değişkeni olan bir temsilci türüdür. { public event RoutedEventHandler Click..RoutedEventHandler(this. Aşağıdaki örnek. Example..... Bu düzenleme.) { . Yapmanız gereken.IComponentConnector. RoutedEventArgs args) { // your code to handle the Click event } } GUI sınıflarının oluşturduğu olaylar her zaman aynı yapıdadır.okay.326 Kısım III Bileşenler Yaratmak Button sınıfı şunun gibi görünür: public class ButtonBase: .

Örneğin.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 327 olayın göndericisi. Click olayını iki düğmeye abone yapmak için (aynı yöntemi iki farklı olaya eklersiniz) aynı yöntemi kullanabilirsiniz. int mm. Delegates projesini görüntüleyen Visual Studio 2008’e dönün. 2. Artık geçersiz olan aşağıdaki tickers temsilci değişkenini Ticker sınıfının sonunda açıklama satırı haline getirin. int mm.. Ticker sınıfına Tick türünde tick adlı bir genel olay ekleyin. ilk alıştırmada tamamladığınız programı basitleştirmek için olayları kullanacaksınız. 3. Stop yöntemlerini değiştireceksiniz. Bölüm 22’de. Temsil edilen yöntem. ikinci bağımsız değişkense EventArgs bağımsız değişkenidir (ya da EventArgs’dan türetilmiş bir sınıf). Dijital saat uygulamasıyla yeniden çalışın 1. Ticker sınıfı şimdi şöyle görünür: class Ticker { public delegate void Tick(int hh. birden çok olay için tek temsilciyi tekrar tekrar kullanmanızı sağlar.. Olay çağrılınca yöntemdeki kod hangi düğmenin tıklandığını belirlemek için gönderici bağımsız değişkenini inceler. . Ekleme ve kaldırma işlevleri otomatik olarak. gönderici bağımsız değişkenini inceler ve ona göre yanıt verir. Ticker sınıfından Add ve Remove yöntemlerini açıklama satırı haline getirin. Ayrıca. // private Tick tickers. olay nesnesinin += ve -= işleçleri tarafından sunulacaktır. Bu dosya Ticker sınıfındaki Tick temsilci türünün bildirimini içerir: public delegate void Tick(int hh. WPF denetimleri için olayları nasıl işleyeceğinizi göreceksiniz. her saniyede bir titreşim almak için Ticker sınıfı tarafından kullanılan Timer nesnesini inceleyeceksiniz. } 4. . int ss). 5. Code and Text Editor penceresinde Ticker. public event Tick tick. Daha sonra olaya abone olmak için Clock. Olayları Kullanmak Aşağıdaki alıştırmada. int ss). Sender (Gönderici) bağımsız değişkeni.cs dosyasını görüntüleyin.Start ve Clock. Ticker sınıfına bir olay alanı ekleyecek ve Add ve Remove yöntemlerini kaldıracaksınız.

minutes. 1). Interval özelliğini TimeSpan’e ayarlarmak.Minutes.Tick += new EventHandler(this. OnTimedEvent yöntemine başvuran ve Tick olayına abone olan bir örneğini yaratır. bu temsilcinin. Notify yöntemi üzerinden tick olayını başlatmak için bu bilgiyi kullanır. Bu yöntem önceden. Minute ve Second gibi birkaç alana sahiptir. seconds). Bu yüzden tick olayını çağıran ifade.ticking. Zamanlayıcı. Ticker kurucu. } DispatcherTimer sınıfı. DispatcherTimer sınıfı. Ticker. Bu yapı. daha önce tanımlanan EventHandler temsilcisi ile aynı imzaya sahiptir. Hour. int minutes.tick != null) this. now. Tick olayının saniyede bir çağrılmasına neden olur. statik DateTime. Now özelliği bir DateTime yapısı döndürür. EventHandler temsilcisinin imzası ile eşleşmelidir. Notify yöntemi aşağıdaki gibi görünür: private void Notify(int hours. Tick olayına abone olan yöntemler. 7. int seconds) { if (this. Ticker sınıfı için kurucuyu inceleyin: public Ticker() { this. bu parametrelerin her biri için bağımsız değişken belirtmelidir.Interval = new TimeSpan(0. Olayı çağırmadan önce tick’in null olup olmadığını denetlemeyi unutmayın. . } Tick temsilcisinin parametreler belirttiğine dikkat edin. DateTime yapısı. Tick temsilcisinin tickers adında bir örneğini başlatmıştı. 0. now.Start(). EventHandler temsilcisi.Now özelliğini inceleyerek o anki saati elde eder. EventArgs args) now = DateTime. Sınıfın sonundaki ticking değişkenini inceleyin: private DispatcherTimer ticking = new DispatcherTimer(). siz Start yöntemini çağırınca başlar. belirli aralıklarla bir olayı tekrar tekrar çağırmaya programlanabilir.Hour. // 1 seconds this.Now.ticking. Bunun yerine tick olayını çağıracak biçimde değiştirin.tick(hours. Interval özelliğinin değerine göre düzenli aralıklarla çağrılabilen Tick olayını gösterir. 8.NET Framework sınıf kütüphanesinin parçasıdır. Ticker sınıfındaki OnTimedEvent yöntemi.Notify yöntemini bulun. .328 Kısım III Bileşenler Yaratmak 6.ticking.OnTimedEvent). this. private void { DateTime int hh = int mm = OnTimedEvent(object source. OnTimedEvent yöntemi.

temsilci += işlecini kullanarak pulsed alanının tick olayına bağlanacak biçimde değiştirin: Clock. Notify(hh.Start yöntemi aşağıdaki gibi görünmelidir: public void Start() { pulsed.RefreshTime. Örneğin: delegate void myDelegate(). Dijital saat formu doğru zamanı gösterir ve her saniye güncellenir. temsilci türünün adını ve parametre türlerini ekleyin. Debug menüsünde Start Without Debugging’ i tıklayın. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 18’e geçin.Bölüm 17 int ss = now.Stop yöntemini.Seconds. Save iletişim kutusu görünürse.RefreshTime. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.Start yöntemini.cs dosyasını görüntüleyin. ss). Formu kapatın ve Visual Studio 2008’e dönün.tick += this. Clock. .Stop yöntemi aşağıdaki gibi görünmelidir: public void Stop() { pulsed. } Program Akışını Kesmek ve Olayları İşlemek 329 9. 10. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. 14. Clock. n Bölüm 17 Hızlı Başvuru Bunun İçin Bir temsilci türü bildirmek Şunu Yapın delegate anahtar kelimesini yazın. } 11. mm. temsilci -= işlecini kullanarak pulsed alanının tick olayından ayrılacak biçimde değiştirin. Start’ ı tıklayın. 13. ardından dönüş türünü. Code and Text Editor penceresinde Clock. } 12. Code and Text Editor penceresinde Clock. 15.tick -= this. Stop’u tıklayın ve saatin durduğunu doğrulayın.

eventHandlingMethod. Örneğin: delegate void myEvent(). } . abonelik yöntemini belirterek derleyicinin yeni temsilciyi otomatik olarak oluşturmasını sağlayabilirsiniz: public void Start() { myClass. Bağımsız değişken imzası tam olarak temsilcinin imzasına uyan bir yöntem olmalıdır. tek bir özel yöntemle başlatılan bir örneğini yaratmak Bir sınıf ya da yapı için kullandığınız sözdiziminin aynısını kullanın: new anahtar sözcüğünü yazın.MyEvent += new myDelegate (this. . } Ayrıca. private void myMethod() { .eventHandlingMethod). } . } Bir olaya abone olmak Bir temsilci örneği yaratın (olayla aynı türden) ve temsilci türünü olaya += işlecini kullanarak bağlayın. } private MyClass myClass = new MyClass(). del()... ardından türün adını (temsilcinin adını) ve parantez içinde bağımsız değişkeni ekleyin. public void Start() { myClass. Örneğin: class MyEventHandlingClass { .. Bir temsilciyi çağırmak Bir yöntem çağrısıyla aynı sözdizimini kullanın. class MyClass { public event myDelegate MyEvent. Örneğin: delegate void myDelegate().myMethod)..330 Kısım III Bileşenler Yaratmak Temsilcinin....MyEvent += this.. Bir olay bildirmek event anahtar sözcüğünü yazın. ardından türün adını (tür bir temsilci türü olmalıdır) ve olayın adını ekleyin. Örneğin: myDelegate del.. myDelegate del = new myDelegate(this. } private void eventHandlingMethod() { ..

} .MyEvent -= new myDelegate (this. Örneğin: class MyClass { public event myDelegate MyEvent. } } .MyEvent != null) { this. } Bir olayı başlatmak Olay bir yöntemmiş gibi parantezleri kullanın. } Ya da: public void Stop() { myClass.... Olayın null olup olmadığını denetlemeyi unutmayın. } private MyClass myClass = new MyClass().MyEvent -= this. } private void eventHandlingMethod() { .MyEvent().. private void RaiseEvent() { if (this.eventHandlingMethod.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 331 Bir olay aboneliğini iptal etmek Bir temsilci örneği yaratın (olayla aynı türden) ve temsilci türünü olaydan -= işlecini kullanarak ayırın...eventHandlingMethod).. .. public void Stop() { myClass. Örneğin: class MyEventHandlingClass { . Olayın türünü eşleştirmek için bağımsız değişkenleri sağlamalısınız.

.

Bu bölümde. Bölüm 8’de herhangi bir sınıfın bir örneğine başvurmak için object türünün nasıl kullanıldığını gördünüz.Collections. System. object türünü herhangi bir türün değerini depolamak için kullanabilirsiniz. Tüm başvuru türleri otomatik olarak (doğrudan ya da dolaylı olarak) . Bir yönteme herhangi bir tür değer geçirmeniz gerektiğinde object türünü kullanarak parametreler tanımlayabilirsiniz.Queue sınıfında şunu fark edersiniz: Hemen her şeyi içerebilen kuyruklar yaratabilirsiniz. Bu bilgiyi oldukça genelleştirilmiş sınıf ya da yöntemler yaratmak için kullanabilirsiniz. Örneğin. Bu uygulama çok esnek olsa da ne tür bilgi kullanıldığını anımsama sorumluluğunu programcıya verir ve programcı bir hata yaparsa çalışma zamanı hatalarına yol açabilir. özellikle object türünü kullanırken oluşan sorunlara yakından bakmak yararlıdır.Bölüm 18 Generics’e Giriş Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n Generic kullanarak tür-güvenli bir sınıf tanımlamak. Nesnelerle İlgili Sorunlar Generics’i anlamak için bunların çözmeyi amaçladığı. Generic bir arabirim uygulamak. Aşağıdaki kod parçası Circle nesnelerinin bir kuyruğunu oluşturup yönetmeyi göstermektedir: 333 . Parametre olarak belirtilen türlere dayanarak bir generic sınıfı örneklerini yaratmak. (Bölüm 10’da koleksiyon sınıflarını gördünüz) Ayrıca.NET Framework’teki System. bu tür hataları önlemenize yardımcı olması için tasarlanmış bir özellik olan Generic’i öğreneceksiniz.Object sınıfından kalıtımla alırlar. object türünü herhangi bir değer ya da değişkene başvuru olarak kullanabilirsiniz. Üzerinde çalıştığı verinin türünden bağımsız bir algoritma uygulayan bir generic yöntem tanımlamak. Collection ad alanındaki sınıfların birçoğu herhangi bir tür koleksiyon oluşturmanıza olanak vermek için bu gerçekten yararlanır. System.

. Bu yöntemler aşağıdaki gibi tanımlanır: public void Enqueue( object item ). // çalışma zamanı hatası Bu kod derlense de geçerli değildir ve çalışma zamanında bir System.InvalidCastException oluşturur. Aşağıdaki gibi bir kod yazmak çok kolaydır: Queue myQueue = new Queue().Enqueue(myInt). .. Bu açık dönüştürme (explicit cast) gerekliliği object türünün sağladığı esnekliğin büyük bir bölümünü alıp götürmektedir. bir Clock değişkeninde bir Circle’a başvuru depolamaya çalışmaktan kaynaklanır ve bu iki tür uyumlu değildir. çalışma zamanının bir object’i bir değer türüne ve ardından önceki durumuna dönüştürmesi gerekirse. myInt = (int)myQueue. // int’i bir nesneye kutular ..Collections. . Kuyruktan çıkarılan (dequeued) nesnenin gerçek türü yalnızca kod çalıştığında belirlenebilir.. çünkü derleyici. myCircle = (Circle)myQueue. myQueue. myQueue. Döndürülen değeri dönüştürmezseniz aşağıdaki kod parçasında görüldüğü gibi. Circle myCircle = new Circle(). Circle myCircle = new Circle(). myQueue. int myInt = 99. Ancak. “Cannot implicitly convert type ‘object’ to ‘Circle’” (Nesne türü Circle’a örtülü olarak dönüştürülemiyor) derleyici hatasını alırsınız. Genelleştirilmiş sınıflar ve yöntemler yaratmak için object yaklaşımını kullanmanın başka bir kötü yanı. nesne türünden bu dönüştürmeyi otomatik olarak gerçekleştirmez. PhoneBooks. Bu hata çalışma zamanına dek anlaşılmaz çünkü derleyici bu denetimi yapacak yeterli bilgiye sahip değildir. ek bellek ve işleme zamanı kullanmasıdır.Dequeue(). Clocks ya da önceki alıştırmalarda gördüğünüz başka sınıflar üzerinde işlem yapabilirsiniz. Clock myClock = (Clock)myQueue..334 Kısım III Bileşenler Yaratmak using System. Queue myQueue = new Queue().Enqueue(myCircle)..Enqueue(myCircle). Enqueue yöntemi object’i kuyruğun başına ekler ve Dequeue yöntemi object’i kuyruğun diğer ucundan kaldırır. Dequeue yöntemi tarafından döndürülen değeri uygun türe dönüştürmeniz gerektiğine dikkat edin. // nesnenin int’e olan kutulamasını kaldırır . Hata.Dequeue().. . public object Dequeue().. Enqueue ve Dequeue yöntemleri object’leri yönettiğinden Circles.Dequeue(). Bir int kuyruğunu yöneten aşağıdaki kod parçasını düşünün: Queue myQueue = new Queue().

Generics Çözümü C#. circleQueue’den Clock nesnesine bir öğe geçirmeye çalışırsanız. Örneğin. Kutulama ve kutulamayı kaldırma şeffaf bir biçimde gerçekleşse de dinamik bellek ayırmayı gerektirdiklerinden performansı yavaşlatırlar. . Ayrıntılı bilgi için Bölüm 8’deki “Kutulamak” ve Kutulamayı Kaldırmak” başlıklı bölümlere bakın. <Circle>. int gibi bir değer türünü kuyruğa koymak için bir başvuru türüne dönüştürülmesi. üzerinde çalıştıkları nesne türlerini belirten type parameters (tür parametreleri) kabul eder.Collections. yani kutulanmasını gerektirir. Dequeue yöntemini kullanırken bir dönüştürme işleminin olmaması.Bölüm 18 Generics’e Giriş 335 Queue (Kuyruk) veri türü tuttuğu öğelerin başvuru türü olmasını bekler.Generic. Circle myCircle = new Circle().Enqueue(myCircle). bir int’i kuyruktan çıkarmak için yeniden bir değer türüne dönüştürülmesi yani öğenin kutulamasının kaldırılması gerekir. object yerine bu türü kullanmayı bekler ve Dequeue yöntemini Circle türüne dönüştürme işlemini gereksiz kılar. .Generic ad alanında birçok koleksiyon sınıfı ve arabiriminin generic sürümlerini içerir.. Generic sınıflar ve yöntemler. çalışma zamanı yerine derleme zamanında bir hata oluşturarak türlerin yanlışlıkla karışmamasını sağlar.Dequeue(). Aşağıdaki kod.. Circle nesnelerinin bir kuyruğunu yaratmak için bu ad alanında bulunan generic Queue sınıfının kullanımını göstermektedir: using System.. Yukarıdaki örnek kodda dikkat edilmesi gereken iki yeni şey vardır: n myQueue değişkenini bildirirken tür parametresinin. Collections. gerekli kutulama miktarını azaltmak ve genelleştirilmiş sınıf ve yöntemler yaratmayı kolaylaştırmak için generic’leri sağlar. dönüştürme gerekliliğini ortadan kaldırmak.NET Framework Class Library System. . . Bu kuyruktaki yöntemlere yönelik tüm başvurular otomatik olarak. Microsoft Visual Studio 2008 belgelerindeki generic Queue sınıfının açıklamasını incelerseniz bunun aşağıdaki gibi tanımlandığını görürsünüz: public class Queue<T> : . Benzer biçimde. myQueue. n Açılı parantezler içindeki tür parametresi kuyruk tarafından kabul edilen nesnelerin türlerini belirtir. tür güvenliğini artırmak. açılı parantezler içinde kullanımı. bir program çok sayıda değer türü kuyruğu yaratınca artar.... Queue<Circle> myQueue = new Queue<Circle>(). Her öğe için bu yavaşlama küçük olsa da. myCircle = myQueue.

İlk iki örnek değer türü kuyrukları yaratırken üçüncüsü kuyrukların (int’lerin) bir kuyruğunu yaratır. Queue<Person> personQueue = new Queue<Person>().. anahtar/tür çiftlerinin bir koleksiyonunu sağlar. tür parametresini tanımlar ve derleme zamanında gerçek bir tür için yer tutucu görevi görür. uygulamayı oluşturduğunuzda sıkı tür denetimi yapmak için yeterli bilgiye sahiptir ve tür eşleşme hatalarını önceden yakalayabilir. public int Dequeue().. Bu tanımları önceki bölümdeki generic olmayan Queue sınıfının tanımlarıyla karşılaştırın.Generic. Generic sınıfından türetilen yöntemlerde item parametresi Enqueue’ye kutulama gerektirmeyen bir değer türü olarak geçirilir. Queue<Queue<int>> queueQueue = new Queue<Queue<int>>(). } .. Bunun yerine. Generic bir sınıfın birden çok türde parametresinin olması da olanaklıdır. Queue<int> intQueue = new Queue<int>(). derleyici şimdi.. Tür parametresi T. Dequeue tarafından döndürülen değer de kutulamasının kaldırılması gerekmeyen bir değer türüdür. TValue> Bir sözlük. Generic bir Queue’yu temsil edecek bir kod yazdığınızda.336 Kısım III Bileşenler Yaratmak Burada T. Aşağıdaki tanım birden çok türde parametre belirtmeyi gösterir: public class Dictionary<TKey. Üstelik Queue<T> sınıfının yöntemlerine bakarsanız Enqueue ve Dequeue gibi bazıları T’yi bir parametre türü ya da dönüş değeri olarak belirtir: public void Enqueue( T item ). derleyici Enqueue ve Dequeue yöntemlerinin aşağıdaki sürümlerini de oluşturur: public void Enqueue( int item ). belirtilen bir tür için T ile bu yer değiştirme basit bir metin değiştirme düzeneği değildir.Collections. derleyici tam bir anlambilimsel yer değiştirme gerçekleştirir ve T için herhangi bir geçerli tür belirtmenize olanak verir. Dictionary . sizin kuyruğu bildirirken belirttiğiniz türle yer değiştirir. Benzer biçimde. Üstelik. generic System.Dictionary sınıfı iki tür parametre bekler: bir tür anahtarlar için ve bir tane de değerler için. public T Dequeue(). T’nin yerine geçecek türü sağlamanız gerekir (Circle’ı belirten bir önceki örnekte olduğu gibi). Örnek olarak intQueue değişkenini alırsak. İşte başka örnekler: struct Person { . Ayrıca. Değerleri (TValue türü) ilgili bir anahtarla (TKey türü) depolarsınız ve sonra aranacak anahtarı belirterek alırsınız. Örneğin.

Person author = directory[“John”]. Person>(). Generic sınıfın bu türe özel sürümleri (Queue<int>. string anahtarlarıyla tanımlanan Person değerlerini içeren directory adlı bir sözlük yaratmak ve kullanmak için aşağıdaki kodu kullanabilirsiniz: struct Person { . Bu aşağıdaki gibi tanımlanır: public virtual TValue this[ TKey key ] { get. . Person> directory = new Dictionary<string. derleyici Person yapıları dışındaki değerleri depolama girişimlerini yakalar ve anahtarın her zaman bir string türü olduğunu garantiler.. işlevselliği generic sınıf tarafından tanımlanan tamamen yeni bir sınıf yaratmasına neden olursunuz.Collections. Not Generic sınıflarla aynı sözdizimini kullanarak generic yapı ve arabirimleri de tanımlayabilirsiniz.. Dictionary sınıfıyla ilgili ayrıntılı bilgi için Visual Studio 2008 belgelerini okumalısınız. anahtar ya da TKey türü kullanarak TValue türü değerlere eriştiğine dikkat edin.Generic. Bu sınıfı bir tür parametresiyle (Queue<int> ya da Queue<string> gibi) kullandığınızda aslında derleyicinin.Queue sınıfı genelleştirilmiş bir sınıftır. istek üzerine yeni türe özel sınıflar yaratmak için derleyici tarafından kullanılan bir şablonu tanımlayan bir sınıf olarak düşünebilirsiniz. Örneğin. Bu sınıfı int. Queue<string> vb. Bu sınıfın tek bir uygulaması vardır ve yöntemleri object parametreleri alıp object türleri döndürür.. directory[“John”] = john.) constructed types (yapılı türler) olarak adlandırılır ve bu türleri belirgin biçimde farklı türler olarak ele almalısınız (her ne kadar benzer yöntemler ve özelliklere sahip olsalar da). . Collections. string ve diğer birçok türle kullanabilirsiniz. System. Dictionary<string. öğelere dizi gösterim biçimini kullanarak erişmenize olanak veren bir dizinleyici sağlar.... Generic bir sınıfı. ancak bunların tümü aynı sınıfın örnekleridir. Generics ve Genelleştirilmiş Sınıflar Tür parametreleri kullanan generic bir sınıfın farklı türlere dönüştürülebilen parametreler alan generalized (genelleştirilmiş) bir sınıftan farklı olduğunu bilmek önemlidir. Person john = new Person().Queue<T> sınıfıyla karşılaştırın.Bölüm 18 Generics’e Giriş 337 (Sözlük) sınıfı. Bunu System. Generic Queue sınıfında olduğu gibi. } . } Dizinleyicinin. set.

Ayrıca kendi generic sınıflarınızı da tanımlayabilirsiniz. kullanımınıza hazır bazı generic sınıflar içerir. derleyici T için kullanılan türün gerçekten IPrintable arabirimini kullandığını denetleyecek ve kullanmıyorsa bir derleme hatasıyla duracaktır. recursive (özyinelemeli. Bunu yapmadan önce.Generic ad alanında eksik olan sınıftır. Bunun yerine. bir generic sınıfın tür parametrelerini belirli arabirim kümeleri uygulayanlarla sınırlandırabilir ve dolayısıyla bu arabirimlerce tanımlanan yöntemler sağlayabilirsiniz. ya boş olan ya da üç öğe içeren. Örneğin. bir ikili ağaç gösteren bir sınıf tanımlayıp kullanacaksınız. Bu iki alt ağaca genel olarak left subtree (sol alt ağaç) ve right subtree (sağ alt ağaç) denir çünkü bunlar sırasıyla düğümün solunda ve sağında gösterilir. Şekil 18-1 küçük bir ikili ağacın yapısını göstermektedir. Bu çok pratik bir alıştırmadır çünkü bu sınıf System. tüm yapı sonsuza dek sürebilir. biraz arka plandaki teoriyi görelim. Her sol ya da sağ alt ağaç ya boştur ya da bir düğümle başka alt ağaçlar içerir. Bu koşulu bir constraint (sınırlama) kullanarak belirtebilirsiniz. kendi kendine başvuran) bir veri yapısıdır: node (düğüm) olarak adlandırılan bazı verilerle. Kuramsal olarak. İkili ağaçların incelikleri üzerine yazılmış ciltler dolusu kitap vardır. Bir ikili ağaç. bir PrintableCollection sınıfı tanımlıyorsanız. . kendileri de ikili ağaç olan iki alt ağaç. İkili ağaç.NET Framework sınıf kütüphanesi. Örneğin. ancak ikili ağaçları ayrıntılı biçimde anlatmak bu kitabın amacı değildir. IPrintable arabirimi Print yöntemini içerirse PrintableCollection sınıfını aşağıdaki gibi tanımlayabilirsiniz: public class PrintableCollection<T> where T : IPrintable Bir tür parametresi ile bu sınıfı oluşturduğunuzda.Collections. Bu bölümde de bunu yapacaksınız. İkili Ağaçlar Kuramı Aşağıdaki alıştırmalarda. sınıf içinde depolanan tüm nesnelerin bir Print yöntemi olduğundan emin olmak isteyebilirsiniz. veri içinde hızla sıralama ve arama yapmak da dahil çeşitli işlemlerde kullanılan çok yararlı bir veri yapısıdır. ilgili ayrıntılara bakmakla yetineceğiz. Bir sınırlama kullanarak. Bir Generic Sınıf Yaratmak .338 Kısım III Bileşenler Yaratmak Generics ve Sınırlamaları Bazen generic bir sınıf tarafından kullanılan tür parametresinin belirli yöntemler sağlayan bir türü tanımladığından emin olmak isteyeceğiniz durumlar olacaktır.

geçerli düğmünün. değerini incele N’in değeri yeni yeni öğe I’nınkinden büyükse Then T’nin sol altağacı boşsa Then Düğüm olan öğe I ile T’nin yeni sol altağacını kur ve sol ve sağ altağaçları boşalt Else T’nin sol altağacına I ekle End If Else T’nin sağ altağacı boşsa Then Düğüm olan öğe I ile T’nin yeni sağ altağacını kur ve sol ve sağ altağaçları boşalt Else T’nin sağ altağacına I ekle End If End If End If . Bir I öğesini sıralı bir T ikili ağacına eklemek için algoritma aşağıda gösterilmiştir: T ağacı boş ise Then Düğüm olan yeni öğe I ile yeni ağaç T’yi kur ve sağ ve sol altağaçlara boşalt Else Ağacın. N. T. bunları sıralı bir ikili ağaç oluşturmak için kullanabilir ve ardından ağaçta gezinerek her düğümü sıralı bir biçimde ziyaret edebilirsiniz.Bölüm 18 Generics’e Giriş 339 ŞEKİL 18-1 Bir ikili ağaç. Aynı türde sırasız nesneler dizisiyle başlarsanız. İkili ağaçların gerçek güçleri bunları veri sıralamak için kullandığınızda açığa çıkmaktadır.

Sayısal veriler için büyüktür ifadesi basit bir aritmetik karşılaştırma olabilir. her düğümü sırayla ziyaret ederek ve bulunan veriyi yazdırarak içeriğini görüntüleyebilirsiniz. Bu görevi gerçekleştirmek için gerekli algoritma da özyinelemelidir: Sol altağaç boş değilse Then Sol altağacın içeriğini görüntüle End If Düğümün değerini görüntüle Sağ altağaç boş değilse . sıralanmamış dizi boyunca yineleme yapabilir ve algoritmayı kullanarak her birini ikili ağaca ekleyebilir ve sıralı bir ağaç elde edebilirsiniz. beş tamsayıdan bir ağaç oluşturma işlemindeki adımları göstermektedir. Sıralı bir ikili ağaç oluşturduktan sonra. metin için bu bir dize karşılaştırması olabilir. Boş bir ikili ağaç ve sıralanmamış bir nesneler dizisiyle başlarsanız. “Generics Kullanarak Bir İkili Ağaç Sınıfı Oluşturmak” başlığı altında bu konu ayrıntılı biçimde anlatılmaktadır. Şekil 18-2. ancak diğer veri türlerine kendi karşılaştırma değerleri verilmelidir.340 Kısım III Bileşenler Yaratmak Algoritmanın özyinelemeli olduğuna dikkat edin. ŞEKİL 18-2 Sıralı bir ikili ağaç oluşturmak. öğeyi sol ya da sağ ağaca eklemek için kendini çağırır. Not Büyüktür ifadesinin tanımı öğe ve düğümdeki veri türüne bağlıdır. öğenin değerine ve ağaçtaki geçerli düğüme bağlı olarak. Sonraki bölümde.

dll” sonekli bir dosyadır. Bir sınıf dosyası. İkili ağaç sınıfı birçok farklı uygulamada yararlı bulacağınız bir sınıftır. ŞEKİL 18-3 Sıralı bir ikili ağaç yazdırmak. derlenmiş sınıflardan (yapı ve temsilci gibi diğer türlerden) oluşan ve bir birleşimde depolanan bir kümedir. Daha sonra bu sınıfı. bir sınıf kitaplığı olarak kullanacaksınız. Bir birleştirme genellikle “. hemen her tür veriyi tutabilen bir ikili ağaç sınıfı tanımlamak için generic kullanacaksınız. Generics Kullanarak İkili Ağaç Sınıfı Oluşturmak Aşağıdaki alıştırmada. sınıf kitaplığının birleşimine bir başvuru ekleyerek ve ardından using ifadeleriyle ad alanlarını kapsam içine alarak bu sınıftaki öğelerden yararlanabilir. Bu yüzden. Tek kısıtlama. Diğer proje ve uygulamalar. bunu kendi içinde bir uygulama değil. kaynak kodu kopyalamaya ve yeniden derlemeye gerek kalmadan başka yerlerde yeniden kullanabilirsiniz. Tamsayıların şimdi artan sırayla görüntülendiğine dikkat edin. .Bölüm 18 Then Sağ altağacın içeriğini görüntüle End If Generics’e Giriş 341 Şekil 18-3 daha önce oluşturulmuş ağacın çıktısını alma işlemindeki adımları göstermektedir. İkili ağaç sınıfını sınarken bunu yapacaksınız. veri türünün farklı örnekler arasındaki değerleri karşılaştırması için bir yöntem sağlaması gerektiğidir.

Area()) return 0. Değer 0’dan küçük 0 0’dan büyük Anlamı Geçerli örnek parametrenin değerinden küçüktür.IComparable<T> Arabirimleri Değerleri birtakım doğal (ve belki doğal olmayan) sıralamaya göre karşılaştırabilmenizi gerektiren bir sınıf yaratmanız gerekiyorsa. geçerli örnekle karşılaştırılacak nesneyi belirten tek bir parametre alır ve aşağıdaki tabloda görüldüğü gibi. IComparable arabirimini kullanmalısınız.PI * radius * radius.342 Kısım III Bileşenler Yaratmak System.. if (this.Area() > circObj. Örnek olarak.IComparable { . class Circle : System.IComparable arabirimini kullanarak ve CompareTo yöntemini sağlayarak Circle sınıfını “karşılaştırılabilir” kılabilirsiniz. public int CompareTo(object obj) { Circle circObj = (Circle)obj. Bu arabirim CompareTo adlı bir yöntem içerir. Bu yöntem. Bölüm 7’de anlatılan ve aşağıda yeniden gösterilen Circle sınıfını düşünün: class Circle { public Circle(int initialRadius) { radius = initialRadius. alanı daha küçük olan bir daireden büyüktür. } System. } public double Area() { return Math.. Geçerli örnek parametrenin değerinden büyüktür. Geçerli örnek parametrenin değerine eşittir. Alanı daha büyük olan bir daire. // parametreyi gerçek türüne dönüştür if (this.IComparable ve System.Area() == circObj. karşılaştırmanın sonucunu gösteren bir tamsayı döndürür. Gösterilen örnekte CompareTo yöntemi Circle nesnelerini alanlarına göre karşılaştırır. .Area()) return 1. } private double radius.

bool Equals(T other).Bölüm 18 return -1. .IComparable<T> arabirimini System. System ad alanı ayrıca aşağıdaki yöntemleri içeren generic IComparable<T> arabirimini tanımlar: int CompareTo(T other). Parametre bir Circle değil başka tür bir nesneyse bu dönüştürme başarısız olur.Area()) return 0. IComparable arabirimine tercih etmeniz gerekir.Area()) return 1. Ancak. } } Generics’e Giriş 343 System.IComparable arabiriminin Area yöntemine erişebilmesi bir dönüştürme kullanımını gerektirir. return -1. Ayrıca bu yöntemlerin bir nesne yerine bir tür parametresi (T) aldığına ve böylece arabirimin generic olmayan sürümünden çok daha güvenli olduğuna dikkat edin.Area() == other. Aşağıdaki kod bu arabirimi Circle sınıfında nasıl uygulayabileceğinizi göstermektedir: class Circle : System.NET Framework’teki birçok türün yaptığı gibi her ikisini de uygulayabilirsiniz. Ancak bu yaklaşım tür-güvenli değildir.. } public bool Equals(Circle other) { return (this. if (this. .Area() > other. Genel olarak. değilse false döndürmelidir. System. } } CompareTo ve Equals yönteminin parametreleri IComparable<Circle> arabiriminde belirtilen türle eşleşmelidir. Bu arabirimde Equals adlı ek bir yöntem bulunduğuna dikkat edin.IComparable<Circle> { . public int CompareTo(Circle other) { if (this. Bu yöntem. her iki örnek de eşitse true.CompareTo(other) == 0). System.IComparable arabirimini incelerseniz.. Ayrıca. parametresinin bir object olarak tanımlandığını görürsünüz. Bunun neden böyle olduğunu anlamak için Circle olmayan bir şeyi CompareTo yöntemine geçirmeye çalıştığınızda olacakları düşünün.

konumu Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step By Step\Chapter 18 klasörü olarak atayın.2.344 Kısım III Bileşenler Yaratmak Tree<TItem> sınıfını yaratın 1.2. Visual Studio’nun istendiğinde dosya adının yanı sıra sınıf adını da değiştirmesine izin verin. 3. Microsoft Visual C# 2008 Express Edition kullanıyorsanız. File menüsünde. Tree sınıfının tanımını aşağıda gösterildiği gibi Tree<TItem> olarak değiştirin: public class Tree<TItem> { } .4.8. yeni bir sınıf kütüphanesi projesi oluşturmak için şunları yapın: 3.6. Visual Studio projects location metin kutusunda. 2. cs olarak değiştirin. 3. 2. OK’i tıklayın. 3. New’ i işaret edin ve sonra Project’ i tıklayın.3.3. New Project iletişim kutusunda. Options iletişim kutusunda.7. sol bölmedeki ağaç görünümünde Projects and Solutions’ı tıklayın.5. 3. yeni bir sınıf kütüphanesi projesi oluşturmak için aşağıdaki görevleri gerçekleştirin: 2. 2.4. Code and Text Editor penceresinde. Class Library şablonunu seçin. 2. 5. Name olarak BinaryTree ve Location olarak Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step By Step\Chapter 18 klasörünü atayın. 3.cs’ i farenin sağ düğmesiyle tıklayın ve dosya adını Tree. New Project’i tıklayın. OK’ i tıklayın. Solution Explorer’da. Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Name alanına BinaryTree yazın.1. 3. Tools menüsünde Options’ı tıklayın. 4. New Project iletişim kutusunda Class Library simgesini tıklayın. Sağ bölmede. File menüsünde. Visual Studio 2008’i başlatın. 3. Class1.1. 3. OK’i tıklayın.

NodeData = nodeValue. Tree<TItem> değil Tree olarak adlandırılır. otomatik özellik ekleyin. ağaca TItem değerini ekleyecektir. public void Insert(TItem newItem) { } ..LeftTree = null. this. Tree<TItem> sınıfının değiştirilen tanımı aşağıdaki gibi görünür: public class Tree<TItem> where TItem : IComparable<TItem> { } 7. Yöntem tanımı şu şekilde olmalıdır: public class Tree<TItem> where TItem: IComparable<TItem> { .. } public Tree<TItem> LeftTree { get. kurucuda NodeData özelliğini nodeValue olarak ayarlayıp LeftTree ve RightTree özelliklerini null olarak atayın: public class Tree<TItem> where TItem : IComparable<TItem> { public Tree(TItem nodeValue) { this. set. } .. } } 8.. TItem tür parametresinin generic IComparable<TItem> arabirimini kullanan bir türü göstermesi gerektiğini belirtecek biçimde değiştirin. Code and Text Editor penceresinde Tree<TItem> sınıfının tanımını. this. Tree<TItem> sınıfına üç özel. NodeData adlı bir TItem özelliği ile LeftTree ve RightTree adlı iki Tree<TItem> özelliği: public class Tree<TItem> where TItem : IComparable<TItem> { public TItem NodeData { get. Aşağıda gösterildiği gibi. Aşağıda gösterildiği gibi.RightTree = null. } . set. 9. Tree<TItem> sınıfına nodeValue adlı tek bir TItem parametresi alan bir kurucu ekleyin. } public Tree<TItem> RightTree { get. Tree<TItem> sınıfına Insert adlı genel bir yöntem ekleyin. Bu yöntem. } Not Kurucunun tür parametresi içermediğine dikkat edin.Bölüm 18 Generics’e Giriş 345 6.. set..

geçerli düğümün değerinin yeni öğeden büyük olup olmadığını belirlemek için IComprable <T> arabiriminin CompareTo yöntemini kullanır: public void Insert(TItem newItem) { TItem currentNodeValue = this. ağacın boş olup olmadığını denetleyen kısmından sonraki bölümü aşağıda yeniden verilmiştir. Examine the value of the node. I Then If the left subtree of T is empty Then Construct a new left subtree of T with the item I as the node. Insert yönteminde. Aşağıda gösterildiği gibi. bu değişkeni ikili ağacın NodeData özelliğinin değerine atayın: public void Insert(TItem newItem) { TItem currentNodeValue = this. currentNodeValue değişkeninin tanımından sonra ekleyin. if (currentNodeValue..NodeData.NodeData. Bu ifade.LeftTree == null) { . } 11. T If the value of N is greater than that of the new item. // Insert the new item into the left subtree açıklamasını aşağıdaki kod bloğuyla değiştirin: if (this. Aşağıdaki if-else ifadesini Insert yöntemine.. currentNodeValue adlı TItem türü bir yerel değişken bildiren bir ifade ekleyin.CompareTo(newItem) > 0) { // Insert the new item into the left subtree } else { // Insert the new item into the right subtree } } 12.. sıralı ikili ağaç oluşturmak için daha önce anlatılan özyinelemeli algoritmayı izler.346 Kısım III Bileşenler Yaratmak Insert yöntemi. .. böylece Insert yöntemi ağacın boş olmadığını varsayabilir. of the tree. N. and empty left and right subtrees Else Insert I into the left subtree of T End If . Sonraki adımlarda yazacağınız kodu anlamanıza yardımcı olmak için algoritmanın. Programcı ilk düğümü ağaca eklemek için kurucuyu kullanır (varsayılan kurucu yoktur). 10.

ToString()). } Console. Bu yöntem ağaç boyunca ilerler. } 16.RightTree. Insert yönteminden sonra. WalkTree adlı başka bir genel yöntem ekleyin.RightTree != null) { this.RightTree. Tree<TItem> sınıfına.RightTree = new Tree<TItem>(newItem). Build menüsünde Build Solution’ı tıklayın.WalkTree().LeftTree = new Tree<TItem>(newItem). Sınıf sorunsuz olarak derlenmelidir.WalkTree().RightTree == null) { this. Aşağıdaki ifadeleri WalkTree yöntemine ekleyin. Boşsa.Insert(newItem). } Generics’e Giriş 347 Bu ifadeler sol alt ağacın boş olup olmadığını denetler.Insert(newItem). } 14. boş değilse yeni öğe Insert yöntemini özyinelemeli olarak çağırıp var olan sol alt ağaca eklenir. Yöntem tanımı aşağıdaki gibi görünür: public void WalkTree() { } 15. if (this.WriteLine(this. varsa bildirilen hataları düzeltin ve gerekirse çözümü yeniden oluşturun. } else { this.LeftTree != null) { this. Bu ifadeler bir ikili ağacın içeriğini yazdırmak için daha önce açıklanan algoritmayı kullanır: if (this. 13.Bölüm 18 this. // Insert the new item into the right subtree açıklamasını yeni düğümü sağ alt ağaca ekleyen eşdeğer kodla değiştirin: if (this.NodeData. } else { this. . her düğümü sırayla ziyaret eder ve değerini yazdırır. yeni bir öğe kullanılarak yeni bir sol alt ağaç yaratılır.LeftTree.LeftTree.

BinaryTree birleşimi. BinaryTree çözümünü farenin sağ düğmesiyle tıklayın. File menüsünde Save All’ ı tıklayın. Uygulamayı çalıştırdığınızda. Bu tekniği bu bölümdeki son alıştırmalarda kullanacaksınız. Add Reference iletişim kutusundaki Projects sekmesini tıklayın. sınıf kitaplıklarını sınamak için önerilen yoldur. Save Project iletişim kutusu belirirse Save’i tıklayın. sınıf kitaplığı projesine değil. Project menüsünden Set as Startup Project’i tıklayın. Visual C# 2008 Express Edition kullanıyorsanız. Solution Explorer’da BinaryTestTree projesinin hala seçili olduğundan emin olun. . Bu. Not BinaryTree projesini değil. çalıştırılacak olan asıl proje budur. 3.dll dosyası) bir başvuru eklemeniz gerekir. Solution Explorer’da BinaryTreeTest projesinin seçili olduğundan emin olun.348 Kısım III Bileşenler Yaratmak 17. Tree<TItem> sınıfını test edin 1. Not Bir Visual Studio 2008 çözümünün birden çok proje içerebileceğini hatırlayın. Location’a. Add’i işaret edin ve sonra New Project’i tıklayın. Bunu. Sonraki alıştırmada. Console Application şablonunu kullanarak yeni bir proje ekleyin. BinaryTree projesini seçin ve ardından OK’i tıklayın. 2. Tree<TItem> sınıfını sınamak için BinaryTree çözümüne ikinci bir proje eklemek için bu özelliği kullanıyorsunuz. Solution Explorer’da BinaryTestTree projesi vurgulanır. BinaryTree çözümünü farenin sağ düğmesiyle tıkladığınızdan emin olun. Şimdi BinaryTreeTest projesinde Tree<TItem> nesneleri yaratabilirsiniz. Solution Explorer’da. Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step By Step\Chapter 18 klasörünü atayın ve OK’i tıklayın. Projeyi BinaryTreeTest olarak adlandırın. Not Sınıf kitaplığı projesi bunu kullanan proje ile aynı çözümün bir parçası değilse. birleşime (. 4. Solution Explorer’da BinaryTreeTest için olan başvurular listesinde görünür. Project menüsünde Add Reference’i tıklayın. Add Reference iletişim kutusundaki Browse sekmesinden birleşimi seçerek yaparsınız. tamsayı ve dize ikili ağaçları yaratarak Tree<TItem> sınıfını test edeceksiniz.

10.. 8.WalkTree(). –8. System. 15 9.Insert(14). tree1. tree1. Program sınıfında Main yönteminin sonuna. tree1.Insert(11).Insert(8).Int32 türü bir yapı değişkeni bildirirsiniz. tree1. 5. 10. Aşağıdaki ifadeleri.Insert(-8). Insert ifadeleri düğümleri ağaca ekler ve WalkTree yöntemi ağacın içeriğini artan biçimde sıralı olarak yazdırır. .. 14.String için bir diğer addır ve bu da IComparable ve IComparable<T> arabirimlerini uygular. Program sınıfını görüntüleyen Code and Text Editor penceresinde aşağıdaki using yönergesini sınıfın üstündeki listeye ekleyin: using BinaryTree. tree1. tree1. 6. tree1. 7. Not C#’ta int anahtar sözcüğünün System. Visual Studio 2008’e dönmek için Enter’a basın.Insert(-12). Kurucu. 10. var olan koddan sonra yazın: static void Main(string[] args) { . Build menüsünde Build Solution’ı tıklayın. bu nedenle Tree<int> değişkenleri yaratabilirsiniz. 5.Insert(8).Bölüm 18 Generics’e Giriş 349 5. 8. Program çalışır ve aşağıdaki sırada değerleri görüntüler: –12. Aşağıda koyu harflerle gösterilen ifadeleri Main yöntemine ekleyin: static void Main(string[] args) { Tree<int> tree1 = new Tree<int>(10).Insert(5). tree1. } Bu ifadeler int’leri tutmak için yeni bir ikili ağaç yaratır. Benzer biçimde.Insert(5). Çözümün derlendiğini doğrulayın ve varsa hataları düzeltin. 10 değerini içeren bir ilk düğüm yaratır. tree1. string anahtar sözcüğü System. bir int değişkeni bildirdiğinizde aslında System.Insert(10). tree1. 0.Int32 türü için yalnızca bir diğer ad olduğunu unutmayın. 8.Int32 türü IComparable ve IComparable<T> arabirimlerini uygular.Insert(0).Insert(15). 11. tree1. Projeyi kaydedin ve daha sonra Debug menüsünde Start Without Debugging’ i tıklayın. tree1.

You 13.Insert(“Are”). Debug menüsünde Start Without Debugging’ i tıklayın. Bir generic yöntem ile tür parametresini bir generic sınıf tanımlarken kullanılana benzer bir şekilde kullanarak parametreler ve dönüş türü belirtebilirsiniz. 12. tree2. Program çalışınca tamsayı değerleri önceki gibi görüntülenir ve ardından dizeler aşağıdaki sırada görünür: !. Build menüsünde Build Solution’ ı tıklayın. onu bazı sınama verileriyle doldurur ve ardından ağacı yazdırır. ref T second) { .WalkTree(). Feeling.Insert(“Well”). 11. Are. tree2. I. tree2. You. tree2.350 Kısım III Bileşenler Yaratmak Tree<string> tree2 = new Tree<string>(“Hello”).Insert(“Are”). generic sınıfları tanımlarken kullandığınız türde parametre sözdizimini kullanarak tanımlarsınız (ayrıca sınırlamalar da tanımlayabilirsiniz). Visual Studio 2008’e dönmek için Enter tuşuna basın. aşağıda gösterilen generic Swap<T> yöntemi. tree2. Hello.Insert(“You”). World. tree2. Well. parametrelerdeki değerleri değiş tokuş etmek için kullanılabilir. Generic yöntemler genellikle generic sınıflarla birlikte kullanılır (bunlara parametre olarak generic bir sınıf alan yöntemler ya da dönüş türü generic bir sınıf olan yöntemler için gerek duyarsınız).NET Framework’ü generic yöntemler yaratmak için de kullanabilirsiniz.Insert(“World”). Hope. Bir Generic Yöntem Yaratmak Generic sınıflar tanımlamanın yanı sıra . Çözümün derlendiğini doğrulayın ve varsa hataları düzeltin. tree2. Are. tree2. tree2. tree2.Insert(“I”). Bu kez veri alfabetik olarak sıralanır.Insert(“Today”). Takas edilen veri türüne bakılmaksızın. tree2.Insert(“Feeling”).Insert(“!”).Insert(“You”). bu işlevsellik yararlı olduğundan onu generic bir yöntem olarak tanımlamak iyi olur: static void Swap<T>(ref T first.Insert(“Hope”). Bu şekilde tür güvenli genelleştirilmiş yöntemler tanımlayabilir ve dönüştürme (ve bazı durumlarda kutulama) zahmetinden kurtulabilirsiniz. } Bu ifadeler dizeleri tutmak için başka bir ikili ağaç yaratır. Generic yöntemleri. Örneğin. Today. tree2. How. tree2.Insert(“How”).

.dll’i ve ardından OK’i tıklayın. çok sayıda öğe eklemek isterseniz Insert yöntemine yapılan tekrarlayan çağrılar çok uygun değildir. Program. Add Reference iletişim kutusunda Browse sekmesini tıklayın. BinaryTree birleşimi Solution Explorer’da gösterilen başvuru listesine eklenir. yöntemin farklı bir sürümünü oluşturmasına neden olur. ref s2).Bölüm 18 T temp = first. Tree<TItem> sınıfı veri öğelerini ağaca eklemek için Insert yöntemini sağlar. Location’a Belgeler klasörünüz altındaki \Microsoft Press\Visual CSharp Step By Step\ Chapter 18 klasörünü atayın ve Solution açılır listesinden Create a new Solution seçeneğini seçin. } Generics’e Giriş 351 Yöntemi başlatmak için tür parametresi için uygun türü belirtirsiniz. second = temp.cs dosyasının en üstüne ekleyin: . ama farklı türler üzerinde. Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Not Bir generic sınıfı farklı tür parametrelerle göstermenin derleyicinin farklı türler oluşturmasına neden olması gibi. projeye BuildTree adını verin. string s1 = “Hello”. b = 2. Bu yöntemi. Swap<int> ile Swap<string> aynı yöntem değildir. bir karakterler ağacına karakterler listesi eklemek için kullanarak sınayacaksınız. s2 = “World”. Project menüsünde Add Reference’ı tıklayın. İkili Ağaç Oluşturmak İçin Bir Generic Yöntem Tanımlamak Önceki örnekte bir ikili ağacı uygulamak için bir generic sınıfın nasıl yaratıldığı gösterilmişti. ref b). BinaryTree. New Project iletişim kutusunda.cs dosyasını gösteren Code and Text Editor penceresinde. first = second.. Swap<string>(ref s1. Aşağıdaki örnekler iki int’i ve iki string’i değiş tokuş etmek için Swap<T>’yi nasıl kullanacağınızı göstermektedir: int a = 1. aşağıdaki using yönergesini Program. Swap<int>(ref a. Ancak. Aşağıdaki alıştırmada. InsertIntoTree yöntemini yazın 1. 3. her iki yöntem de aynı generic yöntem tarafından oluşturulmuş olduğundan aynı davranışı gösterirler. 2. Swap<T> yönteminin her farklı kullanımı derleyicinin. \Microsoft Press\Visual CSharp Step By Step\Chapter 18 \BinaryTree\ BinaryTree\bin\Debug klasörüne gidin. bir veri öğeleri listesinden yeni bir ikili ağaç yaratmanıza olanak veren InsertIntoTree adlı bir generic yöntem tanımlayacaksınız. Visual Studio 2008’de Console Application şablonunu kullanarak yeni bir proje yaratın..

Tree<TItem> üzerinde doğrudan InsertIntoTree yöntemini çağırabilmenizdir. İkili ağacı oluşturmak için kullanılan TItem türü. params TItem[] data) where TItem : IComparable<TItem> { } 6.. Yöntem tanımı aşağıdaki gibi görünür: static void InsertIntoTree<TItem>(Tree<TItem> tree. bu alıştırma için bazı şeyleri basit tutacağız.. dönüş değeri olarak geri döndürülür: static void InsertIntoTree<TItem>(Tree<TItem> tree.352 Kısım III Bileşenler Yaratmak using BinaryTree. InsertIntoTree adlı bir yöntem ekleyin. Tree<TItem> parametresinin önüne this anahtar sözcüğünü ekleyerek ve InsertIntoTree yöntemini bir statik sınıfta tanımlayarak. } . Ağaç. Yöntemin güncelleştirilmiş tanımı aşağıdaki gibi görünür: static void InsertIntoTree<TItem>(Tree<TItem> tree.. InsertIntoTree yönteminin tanımını değiştirin ve uygun where yantümcesini ekleyin. } Bu yaklaşımın başlıca avantajı. Bu. Tree<TItem> sınıfının genişletilmiş bir yöntemini yaratmaktır: public static class TreeMethods { public static void InsertIntoTree<TItem>(this Tree<TItem> tree. Bu ad alanı Tree<TItem> sınıfını içerir. Tree<TItem> nesnesini parametre olarak geçirmek yerine.. Bu ifadeler. ardından params listesi boyunca yineleme yapar ve Insert yöntemini kullanarak her öğeyi ağaca ekler. Program sınıfına. 5. params TItem[] data) where TItem : IComparable<TItem> . Aşağıda gösterilen ifadeleri InsertIntoTree yöntemine ekleyin. kullanıcının gerçekten yönteme bazı parametreler sağladığını denetler (data dizisi boş olabilir). 4. Main yönteminden sonra. params TItem[] data) { . params TItem[] data) { } İpucu Bu yöntemi uygulamanın alternatif bir yolu. IComparable<TItem> arabirimini kullanmalıdır. data adında TItem öğelerinden oluşan bir params dizisi ve bir Tree<TItem> değişkeni alan bir static yöntem olmalıdır. Ancak.

charTree. N. 3.Bölüm 18 { if (data. Program çalışır ve aşağıdaki sırada karakter değerlerini gösterir: A. InsertIntoTree<char>(charTree. ‘Z’. ‘X’. foreach (TItem datum in data) { tree. karakter verisini tutmak için yeni bir Tree yaratan.Length == 0) throw new ArgumentException(“Must provide at least one data value”). Build menüsünde Build Solution’ ı tıklayın. Z 4. } 2. } } Generics’e Giriş 353 InsertIntoTree yöntemini test edin 1. Çözümün derlendiğini doğrulayın ve varsa hataları düzeltin. Program sınıfının Main yönteminde. ‘M’.WalkTree(). ‘N’). ‘Z’. X. M. InsertIntoTree yöntemini kullanarak bunu bazı örnek verilerle dolduran ve ardından Tree’nin WalkTree yöntemini kullanarak görüntüleyen aşağıdaki ifadeleri ekleyin. M. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız . Debug menüsünde Start Without Debugging’ ı tıklayın. Z. Visual Studio 2008’e dönmek için Enter tuşuna basın. ‘A’. static void Main(string[] args) { Tree<char> charTree = new Tree<char>(‘M’). Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakın ve Bölüm 19’a geçin.Insert(datum).

.. Bir tür parametresi kullanarak sınıfı tanımlayın.. Örneğin: static void InsertIntoTree<TItem> (Tree<TItem> tree. Örneğin: Queue<int> myQueue = new Queue<int>().. Bölüm 18 Hızlı Başvuru Bunun İçin Bir generic tür kullanarak bir nesneyi göstermek Yeni bir generic tür yaratmak Şunu Yapın Uygun tür parametresini belirtin.. } Generic tür parametresinin yerini alabilecek türü sınırlandırmak Sınıfı tanımlarken bir where yan tümcesi kullanarak bir kısıtlama belirtin. Örneğin: public class Tree<TItem> { . Örneğin: InsertIntoTree<char>(charTree. ‘X’). ‘Z’. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.. params TItem[] data) { . Örneğin: public class Tree<TItem> where TItem : IComparable<TItem> { .354 Kısım III Bileşenler Yaratmak File menüsünde Exit’i tıklayın. . Save iletişim kutusu görünürse. } Bir generic yöntem tanımlamak Tür parametrelerinin her biri için türler sağlayın. } Bir generic yöntem tanımlamak Tür parametreleri kullanarak yöntemi tanımlayın.

yazmanız gereken kodu basitleştiren şık bir düzenek sağlar. foreach (int pin in pins) { Console. numaralandırılabilir koleksiyon tam olarak nedir? Bunun bir yanıtı. 7. Not C#’taki tüm dizilerin aslında System. öğeleri basit bir dizide listelemek için foreach ifadesini kullanmanın bir örneğini gördünüz. foreach ifadesini yalnızca bir koleksiyonun içeriğine erişmek için hızlı ve uygun bir yöntem olarak kullandınız. 3. Koleksiyondaki Öğeleri Numaralandırmak Bölüm 10’da. Bölüm 10’da ayrıca bir koleksiyondaki öğelerin içine girmek ya da bu öğelerde yineleme yapmak için kullanılan foreach ifadesini de gördünüz. Neyse ki. Peki. ancak artık bu ifadenin gerçekten nasıl çalıştığı konusunda biraz daha bilgi edinmenin zamanıdır. 355 .WriteLine(pin). Bir yineleyici yaratarak bir numaralandırıcıyı otomatik olarak uygulamak.Collections.Array sınıfının örnekleri olduğunu unutmayın. Orada. ancak bu yalnızca belirli koşullar altında yapılabilir (foreach yalnızca numaralandırılabilir bir koleksiyonun içine girmek için kullanılabilir). Array sınıfı. C#. Kod aşağıdakine benzemekteydi: int[] pins = { 9. System. n n Bölüm 10’da veri dizileri ya da kümelerini tutmak için kullanılan dizi ve koleksiyon sınıflarını öğrendiniz. Farklı dizilerdeki koleksiyon öğelerinin içine girebilen ek yineleyiciler sağlamak. Kendi koleksiyon sınıflarınızı tanımlamaya başladığınızda bu konu önem kazanır.Bölüm 19 Koleksiyonları Numaralandırmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n Bir koleksiyondaki öğeler boyunca yineleme yapmak için kullanılabilen bir numaralandırıcıyı elle tanımlamak. bu sürecin çoğunun otomatik olarak yapılmasına yardımcı olan yineleyiciler sağlar. 2 }. IEnumerable arabirimini kullanan bir koleksiyon sınıfıdır. } foreach yapısı.IEnumerable arabirimini kullanan bir koleksiyon olduğudur. System.

ancak IDisposable arabirimini genişletir. . Numaralandırıcıyı. Benzer biçimde. IEnumerator arabiriminin Current özelliğinin tür güvenli olmayan bir davranış sergilediğini. başka bir öğe varsa true. koleksiyon sınıfınızda IEnumerable arabirimini kullanmanız ve ayrıca koleksiyon sınıfının GetEnumerator yöntemi tarafından döndürülecek IEnumerator arabiriminin bir uygulamasını sağlamanız gerekir. işaretçiyi listedeki ilk öğenin öncesine geri döndürmek içinse Reset yöntemini kullanırsınız. bir listedeki öğeleri gösteren bir işaretçi gibi düşünün.IEnumerator arabirimini kullanan bir numaralandırıcı nesnesi döndürmelidir. void Reset(). Bir koleksiyonun GetEnumerator yöntemini kullanıp bir numaralandırıcı yaratarak ve numaralandırıcıyı kullanıp art arda MoveNext yöntemini çağırarak ve Current özelliğinin değerini alarak koleksiyondaki öğeler arasında tek tek ilerleyebilirsiniz. foreach ifadesi tam olarak bunu yapar.0 için uygulama geliştiriyorsanız numaralandırılabilir koleksiyonlar tanımlarken generic olmayan tanımları kullanmak yerine bu generic arabirimlerden yararlanmalısınız. kendi numaralandırılabilir koleksiyon sınıfınızı yaratmak istiyorsanız. bir Reset yöntemi içermez. System. bir Enumerator<T> nesnesi döndüren bir GetEnumerator yöntemi içeren IEnumerable<T> arabirimi vardır. Dolayısıyla. çünkü belirli bir tür yerine bir nesne döndürdüğünü fark etmişsinizdir. Önemli İlk bakışta. } bool MoveNext(). listede sonraki (ilk) öğeye taşımak için MoveNext yöntemini çağırırsınız. MoveNext yöntemi. İşaretçiyi aşağıya. ad benzerliklerinden dolayı. Ancak. .Collections. aşağıdaki özellik ve yöntemleri belirtir: object Current { get. İşaret edilmekte olan öğeye erişmek için Current özelliğini.NET Framework 2. IEnumerable<T> ve IEnumerator<T> arabirimlerini karıştırmak çok kolaydır.NET Framework sınıf kitaplığının da generic IEnumerator<T> arabirimini ve T döndüren bir Current özelliği sağladığını bilmek sizi memnun edecektir. Not IEnumerator<T> arabiriminin IEnumerator arabiriminden bazı başka farkları da vardır. Numaralandırıcı nesne koleksiyon nesnelerini adımlamak (numaralandırmak) için kullanılır. . İyi bir gözlemciyseniz. Başta işaretçi ilk öğeden öncesini gösterir. IEnumerator arabirimi. Birbirine karıştırmayın. GetEnumerator yöntemi. yoksa false döndürür.356 Kısım III Bileşenler Yaratmak IEnumerable arabirimi GetEnumerator adlı tek bir yöntem içerir: IEnumerator GetEnumerator().

Aşağıdaki gibi görünmelidir: class TreeEnumerator<TItem> : IEnumerator<TItem> where TItem : IComparable<TItem> { } . Class şablonunu seçin ve Name için TreeEnumerator.cs yazıp Add komutunu tıklayın.Bölüm 19 Koleksiyonları Numaralandırmak 357 Bir Numaralandırıcıyı Elle Uygulamak Sonraki alıştırmada. bir ikili ağaçtaki her öğeyi aynı sırada alan bir numaralandırıcıyı tanımlamanın basit bir iş olduğunu düşünebilirsiniz. 4. Bu gereksinimleri karşılamak için. generic IEnumerator<T> arabirimini kullanan bir sınıf tanımlayacak ve Bölüm 17’de oluşturduğunuz ikili ağaç sınıfı için bir numaralandırıcı yaratacaksınız. öncelikle ikili ağaçtaki bilgiyi daha yanıt verici bir veri yapısına (bir queue) dönüştürmek için ön işlemeden geçirmeli ve onun yerine bu veri yapısını numaralandırmalısınız. Bu çözüm. Microsoft Visual Studio 2008’i başlatın. IComparable<TItem> arabirimini uygulama ile kısıtlanmalıdır. TreeEnumerator sınıfı bir Tree<TItem> nesnesi için bir numaralandırıcı oluşturur. Bir ikili ağaçta dolaşırken kullanılanlar gibi özyinelemeli algoritmalar (recursive algorithms) yöntem çağrıları arasında durum bilgisini kolaylıkla erişilebilir bir biçimde tutmaya uygun değildir. tür parametresi sınıfın numaralandırdığı Tree<TItem> nesnesi için geçerli bir tür olmalıdır. Projeye yeni bir sınıf ekleyin: Project menüsünde Add Class’ı tıklayın. yanılırsınız. Dolayısıyla. Dolayısıyla. Ayrıca. bu dolambaçlı durum ikili ağacın öğelerinde yineleme yapan kullanıcıdan gizlenir! TreeEnumerator sınıfını yaratın 1. TreeEnumerator sınıf tanımını değiştirin. 3. Sınıfın tür güvenli olduğundan emin olmak için bir tür parametresi sağlamak ve IEnumerator<T> arabirimini uygulamak zorunludur. Asıl sorun bir numaralandırıcıyı tanımlarken yapının neresinde olduğunuzu anımsamanız gerektiğidir. Bölüm 17’de bir ikili ağaçta gezinip içeriğini görüntülemenin ne kadar kolay olduğunu gördünüz. 2. Bu nedenle. Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\Chapter 19\ BinaryTree klasöründeki BinaryTree çözümünü açın. Ne yazık ki. TreeEnumerator. Bölüm 8’de yarattığınız BinaryTree projesinin çalışan bir kopyasını içerir. Böylece. MoveNext yöntemine yapılan sonraki çağrılar durumu uygun biçimde güncelleştirebilir.cs dosyasını gösteren Code and Text Editor penceresinde. Kuşkusuz.

Temel fark olarak.LeftTree != null) { populate(enumQueue. Aşağıdaki populate adlı özel yöntemi. 6. } enumQueue. enumData kuyruğunu ağaçtaki düğümlerden alınan değerlerle dolduracaksınız.LeftTree). MoveNext yöntemi her öğeyi bu kuyruktan sırayla döndürür. if (tree. Kullanılan algoritma Bölüm 18’de anlatılan ve Tree<TItem> sınıfındaki WalkTree yöntemi tarafından kullanılana çok benzer. kurucudan sonra ekleyin: private void populate(Queue<TItem> enumQueue.RightTree != null) { populate(enumQueue. } } Bu yöntem bir ikili ağaçta gezinirken içerdiği veriyi kuyruğa ekler. tree.Enqueue(tree.. data adlı tek bir Tree<TItem> parametresi alan bir TreeEnumerator kurucusu ekleyin. tree.NodeData). } currentData değişkeni numaralandırılmakta olan ağaca yapılan bir başvuruyu tutmak için kullanılır ve currentltem değişkeni Current özelliği tarafından döndürülen değeri tutar . “Bir Tür Parametresi ile Tanımlanan Bir Değişken Başlatmak” başlıklı bölümde açıklanmıştır. private Queue<TItem> enumData = null.358 Kısım III Bileşenler Yaratmak 5. private TItem currentItem = default(TItem).. NodeData değerleri ekrana yazdırılmak yerine kuyrukta depolanır.RightTree). Aşağıdaki üç özel değişkeni TreeEnumerator<TItem> sınıfına ekleyin: class TreeEnumerator<TItem> : IEnumerator<TItem> where TItem : IComparable<TItem> { private Tree<TItem> currentData = null. Tree<TItem> tree) { if (tree. } . } 7. TreeEnumerator<TItem> sınıfına. . default anahtar sözcüğü. Kurucunun gövdesinde currentData değişkenine başlangıç değeri olarak data atayan bir ifade ekleyin: class TreeEnumerator<TItem> : IEnumerator<TItem> where TItem : IComparable<TItem> { public TreeEnumerator(Tree<TItem> data) { this.currentData = data.

enumData. Not IEnumerator<TItem> arabirimi lEnumerator ve IDisposable arabirimlerinden kalıtım yoluyla alır. İlerideki adımlarda bu kodu gerçek bir uygulamayla değiştireceksiniz. İlk çağrıldığında.currentItem = this. Current özelliğinin amacıdır. NotImplementedException özel durumunu oluşturan bir varsayılan uygulama içerir. Oluşturulan kodu inceleyin. this. Ayrıca. başlatma işlemi. Sınıf bildirimindeki IEnumerator<TItem> arabiriminde herhangi bir yeri farenin sağ düğmesiyle tıklayın. MoveNext ve Reset yöntemleri generic olmayan lEnumerator arabirimine aittir. MoveNext yönteminin gövdesini aşağıda koyu harflerle gösterilen kodla değiştirin: bool System. IDisposable arabirimi için Dispose yöntemini oluşturur. 9. bunların yöntemleri de görünür. kuyruk boşalana kadar öğeleri kuyruktan çıkarmalıdır. MoveNext’in aslında veri öğeleri döndürmediğine dikkat etmek önemlidir. MoveNext yöntemine yapılan sonraki çağrılar hiçbir öğe kalmayana dek veri öğeleri arasında hareket etmeli. Özelliklerin ve yöntemlerin gövdeleri. populate(this.enumData.currentData). Bu yüzden. MoveNext’in tüm yaptığı. } Bir numaralandırıcının MoveNext yönteminin aslında iki amacı vardır. IDisposable arabirimi Bölüm 14’te anlatılmıştır. IEnumerator<TItem> arabirimine ait tek öğe generic Current özelliğidir. bu örnekte.IEnumerator. numaralandırıcı tarafından kullanılan veriyi başlatmalı ve döndürülecek ilk veri parçasına atamalıdır. TreeEnumerator<TItem> sınıfının tanımına dönün. } if (this. return true. bu.Bölüm 19 Koleksiyonları Numaralandırmak 359 8.Collections. IEnumerator<TItem> ve IEnumerator arabirimlerinin yöntemleri için bilgi yordamları üretir ve bunları sınıfın sonuna ekler. Aslında.MoveNext() { if (this. Bu durumda. (MoveNext’i ilk kez çağırmadan önce Current özelliği tarafından döndürülen değer tanımlanmamıştır ve bir özel durum oluşturmalıdır). 10.enumData == null) { this.enumData.Dequeue().Count > 0) { this. } return false. kuyruğu gösterme ve veriyi ağaçtan alıp kuyruğu doldurmada kullanmak için populate yöntemini çağırmaktan ibarettir. Bu hareket.enumData = new Queue<TItem>(). Implement Interface’i işaret edin ve ardından Implement Interface Explicitly seçeneğini tıklayın. numaralandırıcıdaki iç .

12. özellik bir InvalidOperationException özel durumu oluşturur (Bu. Çözümü oluşturun ve varsa bildirilen hataları düzeltin. Current özelliği.Current { get { if (this. yoksa false döndürmektir (currentltem değişkeninin değeri kuyruktan alınan veri öğesine ayarlanır). aşağıda koyu harflerle gösterildiği gibi açıklama satırı haline getirin. currentltem değişkenini güncelleştirir. Current özelliğinin yapması gereken tek şey bu değişkendeki değeri döndürmektir.IEnumerator. Generic Current özelliğinin get erişimcisinin tanımını aşağıdaki gibi değiştirin: TItem IEnumerator<TItem>. MoveNext daha önce çağrılmışsa.NET Framework uygulamaları tarafından kullanılan geleneksel düzenektir).360 Kısım III Bileşenler Yaratmak durumu Current özelliğinin kullanımı için güncelleştirmek ve bir sonraki değer varsa true. MoveNext yönteminin çağrıldığından emin olmak için enumData değişkenini inceler (bu değişken MoveNext’ e yapılan ilk çağrıdan önce null’dur). } } Önemli Current özelliğinin doğru uygulamasına kodu eklediğinizden emin olun.Collections.Dispose() { // throw new NotImplementedException().enumData == null) throw new InvalidOperationException (“Use MoveNext before calling Current”).currentItem. yine de bulundurulmalıdır. void IDisposable. Ancak. Dispose yöntemiyle ilgili ayrıntılı bilgi için Bölüm 14’e bakın. IDisposable. Generic olmayan sürüm.Dispose yöntemini bulun. işlemin bu durumda gerçekleşmeyeceğini göstermek için . . return this. Durum bu değilse. varsayılan uygulaması ile bırakın. böylece. ifadesini. Numaralandırıcı açık bırakma gerektiren hiçbir kaynak kullanmadığından bu yöntemin bir şey yapması gerekmez. throw new NotImplementedException(). } 13. 11. System.Current’ı.

GetEnumerator ve IEnumerable. ifade çalıştırıldığında belirlenir. Implement Interface’i işaret edip Implement Interface Explicitly seçeneğini tıklayın. Solution Explorer’da. TItem bir başvuru türüyse default(TItem) null döndürür. Tree<TItem> sınıfını Code and Text Editor penceresinde görüntülemek için Tree. TItem yerini alacak gerçek tür bilinmiyor olabilir (bu sorun yalnızca kod çalıştırılınca çözülür). TItem bir sayıysa default(TItem) 0 döndürür ve TItem bir boolean ise default(TItem) false döndürür. Değişkeni başlatmak için kullanılan değer. 3. GetEnumerator yöntemi bir TreeEnumerator<TItem> nesnesi döndürür. IEnumerable Arabirimini Uygulamak Aşağıdaki alıştırmada IEnumerable arabirimini uygulamak için ikili ağaç sınıfını değiştireceksiniz.GetEnumerator yöntemlerinin uygulamalarını oluşturur ve bunları sınıfa ekler. Başka olasılıklar da vardır: örneğin. TItem bir boolean olabilir. Bu. default anahtar sözcüğü bu sorunu çözer. Bu işlem IEnumerable<TItem>. Program yazılıp derlenince. TItem yerini alan tür bir değer türüyse bu geçersiz bir atama olur (değer türlerini null olarak ayarlayamazsınız. TItem bir struct ise. Sınıf tanımındaki IEnumerable<TItem> arabirimini farenin sağ düğmesiyle tıklayın. sayısal alanlar 0 ve boolean alanlar false olarak ayarlanır). değişkenin başlatılma biçimini belirtmeyi zorlaştırır. Bununla birlikte. Buradaki eğilim bunu null olarak ayarlamaktır. yapıdaki bağımsız alanlar aynı biçimde başlatılır (başvuru alanları null. Aşağıdaki gibi.cs dosyasını çift tıklayın. Tree<TItem> sınıfındaki IEnumerable<TItem> arabirimini uygulayın 1. türün bir sayı olacağını düşünerek bunu 0 olarak ayarlarsanız.Bölüm 19 Koleksiyonları Numaralandırmak 361 Bir Tür Parametresiyle Tanımlanan Bir Değişken Başlatmak currentltem değişkenini tanımlayan ve başlatan ifadenin default anahtar sözcüğünü kullandığını fark etmiş olmalısınız. . currentltem değişkeni TItem parametresi kullanılarak tanımlanır. yalnızca başvuru türlerini atayabilirsiniz). çünkü IEnumerable<TItem> arabirimi IEnumerable’dan kalıtımla alır. tür gerçekte bir başvuru türü olduğunda bu da geçersiz olur. Tree<TItem> sınıfının tanımını IEnumerable<TItem> arabirimini başlatacak biçimde değiştirin: public class Tree<TItem> : IEnumerable<TItem> where TItem : IComparable<TItem> Sınırlayıcıların her zaman sınıf tanımının sonuna yerleştirildiğine dikkat edin. 2. Benzer biçimde. Generic olmayan IEnumerable arabirim yöntemi uygulanır.

2. Proje sorunsuz derlenmelidir. Çözümü oluşturun. Add Reference iletişim kutusunda Projects sekmesini tıklayın. Solution Explorer’da EnumeratorTest projesinin başvurular listesinde görünür. Bu durumda yapmamız gereken tek şey. varsa bildirilen hataları düzeltin ve gerekirse çözümü yeniden oluşturun.362 Kısım III Bileşenler Yaratmak 4. BinaryTree çözümünü farenin sağ düğmesiyle tıklayın.GetEnumerator yöntemini bulun. . aşağıdaki using yönergesini dosyanın üstündeki listeye ekleyin: using BinaryTree.GetEnumerator() { return new TreeEnumerator<TItem>(this). 5. } GetEnumerator yönteminin amacı koleksiyon boyunca yineleme yapması için bir numaralandırıcı nesne oluşturmaktır. Projeyi EnumeratorTest olarak adlandırın. Önce BinaryTree projesini ve ardından OK’i tıklayın. BinaryTree birleşimi. Program sınıfını görüntüleyen Code and Text Editor penceresinde. GetEnumerator() yönteminin gövdesinde var olan throw ifadesini aşağıdaki şekilde değiştirin: IEnumerator<TItem> IEnumerable<TItem>. 3. Numaralandırıcıyı test edin 1. Şimdi. Add’i işaret edin ve daha sonra New Project’i tıklayın. ikili bir ağacın içeriğini görüntülemek için bir foreach ifadesi kullanarak değiştirilmiş Tree<TItem> sınıfını test edeceksiniz. ağaçtaki veriyi kullanarak yeni bir TreeEnumerator<TItem>nesnesi oluşturmaktır. Project menüsünden Add Reference’ı tıklayın. Solution Explorer’da. Solution Explorer’da. Console Application şablonunu kullanarak yeni bir proje ekleyin. Sınıfın sonuna yakın bir yerde IEnumerable<TItem>. Location olarak Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step By Step\Chapter 19 klasörünü atayın ve daha sonra OK’i tıklayın. EnumeratorTest projesini farenin sağ düğmesiyle tıklayın ve sonra Set as Startup Project’i tıklayın. 4.

Yineleyici. 15 9. Numaralandırıcının değer döndürmek için kullandığı diziyi belirtir. } 6.Insert(-12).WriteLine(item). 5. foreach (int item in tree1) Console. tree1. 14.Insert(15).. 8. tree1. Program çalışınca değerler aşağıdaki sırayla görüntülenir: –12.Insert(10). tree1. tree1. yineleyici aslında numaralandırılabilir sınıfın bir üyesi değildir.Bölüm 19 Koleksiyonları Numaralandırmak 363 5. 11. tree1. 5.. Bir Yineleyici Kullanarak Numaralandırıcı Uygulamak Gördüğünüz gibi. Debug menüsünde Start Without Debugging’i tıklayın. Başka bir deyişle. bu sürecin büyük bir bölümünü otomatikleştiren yineleyiciler içerir.Insert(14).Insert(5). tree1. Çözümü oluşturun ve varsa hataları düzeltin. Hayatı kolaylaştırmak için C#. C# derleyicisinin kendi numaralandırıcısını yaratmak için kullanabildiği numaralandırma dizisinin bir betimlemesidir . 0. } 7. bir koleksiyonu numaralandırılabilir yapmak karmaşık ve hatalara açık bir süreç olabilir. –8. sıralı bir değer dizisi veren bir kod bloğudur.Insert(0). Visual Studio 2008’e dönmek için Enter tuşuna basın. 10. tree1.Insert(11).Insert(5).Insert(-8). bir yineleyici. Ağacın içeriğini numaralandıran ve sonuçları görüntüleyen bir foreach ifadesi ekleyin: static void Main(string[] args) { . tree1. 10. Tamsayılardan oluşan bir ikili ağacı yaratıp dolduran aşağıdaki ifadeleri Main yöntemine ekleyin: static void Main(string[] args) { Tree<int> tree1 = new Tree<int>(10). tree1. Buna ek olarak.

Sınıf. bir yineleyici uygulamanın temel ilkelerini göstermektedir.Add(datum). Bu noktada yineleme tamamlanmıştır. Çağıran sonraki değeri istediğinde GetEnumerator yöntemi yield’in bıraktığı yerden devam eder ve döngüye girerek sonraki değeri verir. Bunun yerine. . using System. döngü durur ve GetEnumerator yöntemi sonlanır. Önemli nokta. Sonuçta. class BasicCollection<T> : IEnumerable<T> { private List<T> data = new List<T>().Collections. Bu kavramı düzgün biçimde anlamak biraz düşünmeyi gerektirdiğinden ikili ağaçlara ve özyinelemeye dönmeden önce temel bir örneği ele alalım. yield ifadesini yöntemi geçici olarak durduran ve çağırana bir değer geçiren bir çağrı gibi düşünebilirsiniz. using System. Ve her öğeyi sırayla döndürür. yield anahtar sözcüğü her yinelemenin döndürmesi gereken değeri gösterir. } IEnumerator IEnumerable. } IEnumerator<T> IEnumerable<T>. data dizisindeki öğeler içinde döner. Basit Bir Yineleyici Aşağıda gösterilen BasicCollection<T> sınıfı. veri tutmak için bir List<T> kullanır ve bu listeyi doldurmak için FillList yöntemini kullanır.Generic. GetEnumerator yöntemi bir yineleyici kullanılarak uygulanır: using System. Dikkat etmeniz gereken ilk şey bir IEnumerator<T> türünü döndürmediğidir. public void FillList(params T [] items) { foreach (var datum in items) data. BasicCollection<T> sınıfının IEnumerable<T> arabirimini uyguladığına da dikkat edin. veri tükenir.GetEnumerator() { // Bu örnekte uygulanmaz } } GetEnumerator yöntemi oldukça açık görünmektedir.Collections. yield anahtar sözcüğünün kullanımıdır.GetEnumerator() { foreach (var datum in data) yield return datum.364 Kısım III Bileşenler Yaratmak yalnızca. ancak daha yakından bakmayı gerektirir.

Örneğin. “slithy”. Aslında oluşturulan bu kodu görmezsiniz (derlenmiş kodu içeren birleşimin derlemesini kaldırmadığınız sürece). Bu kod bc nesnesinin içeriğini ters sırada yazdırır: toves.FillList(“Twas”. foreach (string word in bc) Console. “brillig”. i--) yield return data[i]. bc. “and”. “brillig”.WriteLine(word). and. } } Bu özelliği aşağıdaki gibi başlatabilirsiniz: BasicCollection<string> bc = new BasicCollection<string>(). “the”. “toves”). Bu kod bc nesnesinin içeriğini aşağıdaki sırada yazdırır: Twas.1. and. toves Veriyi farklı sırada sunacak alternatif yineleme düzenekleri sağlamak isterseniz IEnumerable arabirimini uygulayan ve veri döndürmek için bir yineleyici kullanan ek özellikler kullanabilirsiniz. ancak yazmanız gereken kodun sağladığı rahatlığı ve kodun kısalığını düşününce bu ödediğiniz küçük bir bedeldir.FillList(“Twas”.Reverse) Console. GetEnumerator yöntemindeki kod bir iterator (yineleyici) tanımlar.Count . aşağıda gösterilen BasicCollection<T> sınıfının Reverse özelliği listedeki veriyi ters sırada sunar: public IEnumerable<T> Reverse { get { for (int i = data. brillig. slithy. slithy. brillig. bc. “and”.WriteLine(word). Derleyici.Bölüm 19 Koleksiyonları Numaralandırmak 365 Bu genel anlamıyla normal bir yöntem değildir. the. the. Bu uygulama GetEnumerator yöntemi tarafından belirtilen işlevsellikle tam olarak eşleşir. “slithy”. Twas . “toves”). foreach (string word in bc. “the”. i >= 0. yineleyici tarafından oluşturulan numaralandırıcıyı her zamanki gibi başlatabilirsiniz: BasicCollection<string> bc = new BasicCollection<string>(). Aşağıdaki kod bloğunda görüldüğü gibi. bu kodu bir Current ve bir MoveNext yöntemi içeren IEnumerator<T> sınıfının bir uygulamasını oluşturmak için kullanır.

Tree<TItem> sınıfının tanımını IEnumerable<TItem> arabirimini geliştirecek biçimde değiştirin: public class Tree<TItem> : IEnumerable<TItem> where TItem : IComparable<TItem> { . MoveNext yöntemi tarafından ağaçtaki verinin bir kuyruğa önceden işlenmesinin gerektiği önceki alıştırmaların aksine. Implement Interface’i işaret edin ve ardından Implement Interface Explicitly seçeneğini tıklayın. } 3.LeftTree) { yield return item. . Visual Studio 2008’i kullanarak.GetEnumerator() { if (this. GetEnumerator yönteminin içeriğini aşağıda gördüğünüz gibi değiştirin: IEnumerator<TItem> IEnumerable<TItem>. } } yield return this..NodeData. Sınıf tanımındaki IEnumerable<TItem> arabirimini farenin sağ düğmesiyle tıklayın.GetEnumerator ve IEnumerable. Code and Text Editor penceresinde Tree. 2.LeftTree != null) { foreach (TItem item in this. IEnumerable<TItem>.366 Kısım III Bileşenler Yaratmak Bir Yineleyici Kullanarak Tree<TItem> Sınıfı İçin Bir Numaralandırıcı Tanımlamak Sonraki alıştırmada bir yineleyici kullanarak Tree<TItem> sınıfı için bir numaralandırıcı uygulayacaksınız.. Belgeler klasörünüzdeki \Microsoft Press \Visual CSharp Step by Step\Chapter 19\IterarorBinaryTree klasöründe yer alan BinaryTree çözümünü açın. Bölüm 18’de oluşturduğunuz BinaryTree projesinin bir başka kopyasını içerir.cs dosyasını görüntüleyin. Bu çözüm. IEnumerable<TItem>. Tree<TItem> sınıfına bir numaralandırıcı ekleyin 1. 4.GetEnumerator yöntemini bulun. Bölüm 17’de açıklanan WalkTree yöntemine benzeyen daha doğal özyinelemeli düzeneği kullanarak ağaç boyunca ilerleyen bir yineleyici tanımlayabilirsiniz.GetEnumerator yöntemleri sınıfa eklenir.

ancak bu kod özyinelemelidir. Not Bu iki adım EnumeratorTest projesinin BinaryTree birleşiminin önceki sürüme değil. Solution Explorer’da. daha önce elle oluşturduğunuz numaralandırıcıyı sınamak için yarattığınız projedir. NodeData özelliğini yazdırarak ve sağ alt ağacını inceleyerek üst düğüme geri döner. Bu. \Microsoft Press\Visual CSharp Step By Step\Chapter 19\EnumeratorTest klasörünü bulun. Project menüsünde Add Reference’ı tıklayın. BinaryTree projesini seçin ve ardından OK’i tıklayın. Add Reference iletişim kutusunda Projects sekmesini tıklayın.Bölüm 19 if (this. Sağ alt ağaç tükenince bu işlem. 3. BinaryTree birleşimini farenin sağ düğmesiyle tıkladıktan sonra Remove komutunu tıklayın. hiç sol alt ağacı kalmayan bir düğüm bulunana dek sürer. Bu eylem BinaryTree birleşimine yapılan başvuruyu (Bölüm 18’den) projeden kaldırır. Bu işlem döngüsü tüm ağaç numaralandırılıncaya ve tüm düğümler yazdırılana kadar devam eder. numaralandırıcısını oluşturmak için yineleyiciyi kullanan sürümüne başvurduğunu garantiler. } } } Koleksiyonları Numaralandırmak 367 İlk bakışta öyle değilmiş gibi görünebilir. LeftTree boş değilse ilk foreach ifadesi GetEnumerator yöntemini (şu anda tanımladığınız) dolaylı olarak onun üzerinden çağırır. Solution Explorer’da EnumeratorTest projesini farenin sağ düğmesiyle tıklayın ve ardından Set as Startup Project’i tıklayın. Bu noktada. Add’i işaret edin ve sonra Existing Project’i tıklayın. NodeData özelliğindeki değer verilir ve sağ alt ağaç aynı biçimde incelenir. 4. Solution Explorer’da EnumeratorTest projesinin References düğümünü genişletin. BinaryTree çözümünü farenin sağ düğmesiyle tıklayın. 2. EnumeratorTest proje dosyasını seçin ve Open’ı tıklayın.RightTree != null) { foreach (TItem item in this. Add Existing Project iletişim kutusunda. . Bu işlem. Yeni numaralandırıcıyı test edin 1. Yeni BinaryTree birleşimi Solution Explorer’da EnumeratorTest projesinin başvurular listesinde görünür.RightTree) { yield return item.

n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Bölüm 19 Hızlı Başvuru Bunun İçin foreach yapısını desteklemesini sağlamak için bir sınıfı numaralandırılabilir yapmak Şunu Yapın IEnumerable arabirimini uygulayın ve bir IEnumerator nesnesi döndüren bir GetEnumerator yöntemi sağlayın.cs dosyasındaki Main yöntemini gözden geçirin. Program çalışınca değerler öncekiyle aynı sırada görüntülenir: –12. –8. 0. 6. 15 8. 11. Örneğin: public class Tree<TItem> : IEnumerable<TItem> { .. 5. Save iletişim kutusu görünürse. Program. 5. 7. 14. Visual Studio 2008’e dönmek için Enter’a basın. EnumeratorTest projesi için Program. Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 20’ye geçin..368 Kısım III Bileşenler Yaratmak 5. } } . 10. Debug menüsünde Start Without Debugging’i tıklayın.. Bu yöntemin bir Tree<int> nesnesi gösterdiğini. IEnumerator<TItem> GetEnumerator() { ..cs dosyasını Code and Text Editor penceresinde görüntüleyin. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. bunu bazı verilerle doldurduğunu ve ardından içeriğini görüntülemek için bir foreach ifadesi kullandığını hatırlayın. 10. Çözümü oluşturun ve varsa hataları düzeltin.

} } Bir yineleyici kullanarak bir numaralandırıcı tanımlamak Hangi öğenin hangi sırayla döndürüleceğini (yield ifadesini kullanarak) göstermek için numaralandırıcıyı uygulayın. } ... TItem Current { get { .. } } bool MoveNext() { . Örneğin: public class TreeEnumerator<TItem> : IEnumerator<TItem> { ..Bölüm 19 Koleksiyonları Numaralandırmak 369 Bir yineleyici kullanmadan bir numaralandırıcı uygulamak IEnumerator arabirimini uygulayan ve Current özelliği ile MoveNext (ve Reset ) yöntemlerini sağlayan bir numaralandırıcı sınıf tanımlayın... Örneğin: IEnumerator<TItem> GetEnumerator() { for (.) yield return .....

.

Veriyi modellemek için yapılar ve sınıflar tanımlayabileceğinizi ve veriyi geçici olarak bellekte saklamak için koleksiyonlar ve diziler kullanabileceğinizi gördünüz. Tümleşik Sorgu Dili (LINQ) Nedir? Tüm uygulamaların veri işlemesi gerekir. Tümleşik Sorgu Dili (Language Integrated Query ya da LINQ) olarak adlandırılır. C#’ın veri sorgulama için sağladığı destekten bahsetmedik. n n C# dilinin birçok özelliğini gördünüz. 371 . Tarihsel olarak. bu konularda uzun sure düşündüler ve bir uygulamanın veriyi kodun kendisinden sorgulaması için kullanacağı bazı özellikler sağlayarak. veri sorgulama ve işleme için. bu strateji. birçok uygulama tarafından kullanılabilen önemli bir yaklaşımdan. veriyi işleyen kodda da çok sayıda değişiklik yapmanız gerekebilir. birçok uygulama bu işlemleri gerçekleştirmek için kendi mantığına sahiptir.NET Framework tasarımcıları. yazmak zorunda olduğunuz kod miktarını en az tutmak için. Veri yapısı değişirse. bir LINQ sorgusunun sonuçlarını önbelleğe nasıl alabileceğinizi açıklamak. Bununla birlikte. belirli kriterlerle eşleşen bir koleksiyondaki öğeleri aramak gibi yaygın görevleri nasıl yerine getirirsiniz? Örneğin. Bu özellikler. C# dilinin bu ileri seviye özelliklerini nasıl kullanacağınızı öğreneceksiniz. bir uygulamadaki kodun işlenen verinin yapısına oldukça sıkı bağlı hale gelmesine neden olabilir. uygulama geliştirme sürecini kolaylaştırmaya karar verdiler. Microsoft . LINQ genişletilmiş yöntemler ve sorgu işleçleri kullanmak. Bu bölümde. Customer nesnelerinin bir koleksiyonuna sahipseniz. C#’ın bazı özellikler içermesine karar vermişlerdir. Bununla birlikte. Londra’da bulunan müşterileri ya da müşterilerinizin çoğunun hangi şehirde olduğunu nasıl bulursunuz? Bir koleksiyon üzerinde yinelemek ve her nesnedeki alanları incelemek için kendiniz kod yazabilirsiniz fakat bu tür görevler çok sık gerektiğinden C# tasarımcıları.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak Bu bölümü tamamladıktan sonra öğrenecekleriniz : n Numaralandırılabilir koleksiyonların içeriğini incelemek için Language Integrated Query (LINQ) (Tümleşik Sorgu Dili) sorguları tanımlamak. Ancak. LINQ’nun bir sorguyu ertelemesini ve hemen uygulanmasını nasıl sağlayacağınızı.

SQL) ifadelerini veritabanı yönetim sistemine dağıtırlar. SQL ifadeleri çağıran bir uygulama veritabanının veriyi nasıl depoladığı ya da veriyi nasıl bulduğu ile ilgilenmez. LINQ dili SQL’e oldukça benzer olmakla birlikte. Bir C# Uygulamasında LINQ Kullanmak LINQ’yu destekleyen C# özelliklerini nasıl kullanacağınızı açıklamanın en basit yolu aşağıdaki müşteri adları ve adres bilgilerine dayalı basit örnekler üzerinden çalışmak olacaktır: Müşteri Bilgisi CustomerID 1 2 3 4 5 6 7 8 9 10 FirstName Orlando Keith Donna Janet Lucy David Donald Jackie Elsa Eric LastName Gee Harris Carreras Gates Harrington Liu Blanton Blackwell Leavitt Lang CompanyName A Bike Store Bike World A Bike Store Fitness Hotel Grand Industries Bike World Grand Industries Fitness Hotel Grand Industries Distant Inn . Microsoft SQL Server gibi ilişkisel veritabanı yönetim sistemlerini ele alarak. sözdizimi ve anlambilimi bakımından SQL’e oldukça benzer ve aynı avantajları sağlar. daha esnektir ve daha fazla çeşitte mantıksal veri yapılarını işleyebilir. Sorgulama işlemlerini gerçekleştiren kodu değiştirmeniz gerekmeden. bir XML belgesinde bulunan veri gibi hiyerarşik olarak organize edilmiş veriyi işleyebilir. LINQ. Bu ayrıntılar veritabanı yönetim sisteminin kendisi tarafından denetlenir. LINQ. yeni bir sürüm yayınlandığında). Yapısal Sorgu Dili (Structured Query Language. fakat yazılım geliştiricinin uygulama tarafından kullanılan SQL ifadelerini değiştirmesi gerekmez. Veritabanı yönetim sistemi tarafından kullanılan biçim değişebilir (örneğin. bu bölümde ilişkisel anlamda LINQ kullanımına yoğunlaşılmıştır. veritabanındaki verinin içsel biçiminden ayırır. SQL. fakat veritabanı yönetim sisteminden nasıl alacağını tam olarak bilmediği verinin.372 Kısım III Bileşenler Yaratmak LINQ dili tasarımcıları. Bu nedenle. sorgulanan verinin temel yapısını değiştirebilirsiniz. yazılım geliştiricinin veritabanından almak istediği. veritabanını sorgulamak için kullanılan dili. Bununla birlikte. Örneğin. Bir SQL Server veritabanına erişen yazılım geliştiriciler. ileri seviye tanımını sağlar.

Ancak. FirstName = “Eric”. FirstName = “Janet”. aşağıdaki kod örneğinde gösterildiği gibi. CompanyName = “Bike World” }. LastName = “Lang”. FirstName = “Elsa”. LastName = “Gee”. new { CustomerID = 9. CompanyName = “Grand Industries” }. var customers = new[] { new { CustomerID = 1. new { CustomerID = 4. new { CustomerID = 7. IEnumerable arabirimini geliştiren bir veri yapısında saklanmasını ister. veriyi bir dosya ya da veritabanından okuyarak bu dizileri yerleştireceksiniz. Queue ya da başka bir koleksiyon türü ve hatta kendi tanımladığınız bir tür) kullandığınız önemli değildir. new { CustomerID = 3.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 373 Adres Bilgisi CompanyName A Bike Store Bike World Fitness Hotel Grand Industries Distant Inn City New York Chicago Ottawa London Tetbury Country United States United States Canada United Kingdom United Kingdom LINQ verinin. CompanyName = “Fitness Hotel” }. CompanyName = “Distant Inn” } }. new { CustomerID = 2. CompanyName = “A Bike Store” }. Not Gerçek dünya uygulamasında. LastName = “Gates”. bir veritabanından bilgiyi elde etmek için . new { CustomerID = 5. LastName = “Liu”. NET Framework tarafından sağlanan özellikler hakkında daha fazlasını öğreneceksiniz. LastName = “Blackwell”. LastName = “Harrington”. müşteri ve adres bilgisinin customers ve addresses dizilerinde tutulduğunu varsayar. FirstName = “Keith”. new { CustomerID = 10. Numaralandırılabilir olduğu sürece ne tür yapı (bir dizi. new { CustomerID = 6. FirstName = “Lucy”. FirstName = “Jackie”. . Bölüm 19’da açıklandığı gibi. FirstName = “Donna”. LastName = “Carreras”. FirstName = “Donald”. CompanyName = “Bike World” }. bu bölümdeki örnekler. FirstName = “Orlando”. new { CustomerID = 8. LastName = “Blanton”. “Veriyi Yönetmek” başlıklı Kısım V’te. HashTable. FirstName = “David”. CompanyName = “Fitness Hotel” }. CompanyName = “A Bike Store” }. LastName = “Harris”. CompanyName = “Grand Industries” }. CompanyName = “Grand Industries” }. LastName = “Leavitt”.

new { CompanyName = “Fitness Hotel”. Sözdizimi biraz karmaşık gelebilir.WriteLine(name). Bu görevi gerçekleştirmek için kendi yönteminizi tanımlayabilirsiniz. Nasıl çalışır? Select yönteminin parametresi. Şu üç önemli noktayı iyi anlamalısınız: n cust türü. City = “Chicago”. customers dizisinden bir satırı alarak. new { CompanyName = “Bike World”. fakat en basit mekanizma. City = “Tetbury”. Country = “Canada”}.374 Kısım III Bileşenler Yaratmak var addresses = new[] { new { CompanyName = “A Bike Store”. cust türünü. . diziden belirli bir veriyi bulmanızı sağlar (bu örnekte. new { CompanyName = “Distant Inn”. önceki örnekte gösterildiği gibi bir anonim yöntem tanımlamak için bir lambda deyimi kullanmaktır. yönteme geçirilen parametrenin türüdür. ”Veriyi Sıralamak. Gruplamak ve Toplamak” ve “Veriyi Birleştirmek” başlıklı aşağıdaki bölümler. “Sorgu İşleçlerini Kullanmak” başlıklı bölümde sözdiziminin nasıl çalıştığını tümüyle bilmenizin gerçekten gerekli olmadığını göreceksiniz. Veriyi Seçmek customers dizisindeki her müşterinin ilk adını kapsayan bir listeyi görüntülemek istediğinizi varsayın. sadece dizideki her öğenin FirstName alanındaki değeri). ”Veriyi Filtrelemek”. City = “Ottawa”. Bununla birlikte. Aşağıdaki kod ile bu görevi gerçekleştirebilirsiniz: IEnumerable<string> customerFirstNames = customers. foreach (string name in customerFirstNames) { Console.FirstName). bunu customers dizisi üzerinde Select yöntemini çağırmanız gerçeğinden ortaya çıkarır. customers dizisindeki her satırın türü için bir takma ad olarak düşünebilirsiniz. Select yöntemi. Country = “United States”}. Country = “United States”}. } Bu kod bloğu oldukça kısa olmakla birlikte. Country = “United Kingdom”} }. City = “New York”. C# tarafından sağlanan sorgu işleçlerinin görevlerini nasıl gerçekleştirdiğini tam olarak anlamak için aşağıdaki bölümlere en azından göz atmanız yararlı olacaktır. City = “London”. Country = “United Kingdom”}. LINQ yöntemlerini kullanarak veriyi sorgulamak için bazı özellikleri ve sözdizimini gösterir.Select(cust => cust. o satırdan seçilen veriyi döndüren bir başka yöntemdir. cust yerine herhangi bir geçerli C# tanımlayıcıyı kullanabilirsiniz. Not “Veriyi Seçmek”. new { CompanyName = “Grand Industries”. customers dizisinin Select yönteminin kullanımından başlayarak çok sayıda açıklama gerektirir. Derleyici.

n Önceki örnek. yani source parametresi gerçekte genişletilen türe bir başvurudur (örneğimizde IEnumerable arabirimini uygulayan customer nesnelerinin generic koleksiyonu). Select yönteminin bir generic yöntem olduğu ve source ve selector adında iki sıradan parametrenin yanısıra. . Microsoft Visual Studio 2008 tarafından sağlanan belgelerdeki System. TResult> selector ) Bu tanımlamanın tam olarak söylediği.Select yönteminin tanımını incelerseniz.) selector parametresi tarafından başvurulan yöntem.Bölüm 20 n Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 375 Select yöntemi bu defa veriyi gerçekten bulmaz. TSource.Linq ad alanında yer alır ve generic IEnumerable<T> arabirimini uygulayan sorgu nesnelerinin statik yöntemlerinin önemli bir kümesini sağlar. numaralandırılabilir sonuç kümesindeki verinin türüdür (örneğimizde. “LINQ ve Ertelenmiş Değerlendirme” başlıklı bölümde ele alacağız. TResult> ( IEnumerable<TSource> source. customerFirstNames adında bir IEnumerable<string> (Select yöntemi. Func<TSource. Enumerable sınıfı.) nesnesi üretmek için customers dizisinin Select yöntemini kullanır. aşağıdaki sırada müşterilerin ilk adlarının çıktısını verir: Orlando Keith Donna Janet Lucy David Donald Jackie Elsa Eric Şimdi her müşterinin ilk adını görüntüleyebilirsiniz. string türündeki müşterilerin ilk adlarının numaralandırılabilir koleksiyonunu döndürdüğünden IEnumerable<string> türündedir. Her müşterinin ilk adını ve soyadını nasıl elde edersiniz? Bu. bir generic yöntemi kapsüllemek için kullanabileceğiniz. Enumerable sınıfının genişletilmiş yöntemidir. aşağıdaki gibi olduğunu görürsünüz: public static IEnumerable<TResult> Select<TSource. Select yönteminin genişletilmiş yöntem olduğunu hatırlayın. Select yöntemi. bulunan alanları tanımlayan bir generic yöntemi belirtir. bir numaralandırılabilir sonuç kümesi için ürettiğiniz koleksiyonun türüdür (örneğimizde. System. string nesneleri). customer nesneleri) ve TResult da.Linq ad alanında Enumerable. foreach ifadesi bu dize koleksiyon üzerinden yinelenir. (Func. gerçekte bir Array türü yöntemi değildir. Select yöntemi tarafından tanımlanan veriyi bulup getirecek olan bir numaralandırılabilir nesne döndürür. selector parametresi. TSource ve TResult adında iki tür parametresi aldığıdır. daha sonra üzerinden yineleme yapacağınız. .NET Framework’deki bir generic temsilci türünün adıdır. Bu yaklaşımı. biraz ince bir iştir.

her müşterinin ilk adı ve soyadı gibi birden fazla veri öğesi döndürmesini istiyorsanız. Select yöntemi tarafından döndürülen değer. string) nesnelerinin numaralandırılabilir koleksiyonudur. tek bir işlem için yeni bir tür tanımlamak yerine bir anonim tür kullanmayı tercih edebilirsiniz: var customerName = customers.LastName).FirstName.376 Kısım III Bileşenler Yaratmak TSource (bu örnekte.LastName } ). set. bunun için en az iki seçeneğiniz var: n İlk ad ve soyadları aşağıdaki gibi. yani koleksiyondaki nesneler için özel bir tür belirleyemezsiniz.FirstName. customer) parametresi alır ve TResult (bu örnekte. Bölüm 12’ye tekrar bakın.FirstName + " " + cust. LastName = cust. Select yönteminin. Select yönteminde tek bir dize içinde birleştirebilirsiniz: IEnumerable<string> customerFullName = customers.. . tek bir türe dayalı numaralandırılabilir bir koleksiyon döndürdüğüdür. string) nesnelerinin bir koleksiyonunu verir. Not Genişletilmiş yöntemlerin nasıl çalıştığını ve ilk parametrenin genişletilmiş yönteme etkisini yeniden gözden geçirmeniz gerekirse.Select(cust => cust. Numaralandırıcının.Select(cust => new { FirstName = cust. } public string LastName{ get. TResult (yine.Select(cust => new Names { FirstName = cust. Önceki paragrafta anlaşılması gereken önemli bir nokta. IEnumerable<Names> customerName = customers. set. ilk ad ve soyadları paketleyen yeni bir tür tanımlayabilir ve bu türün örneklerini oluşturmak için Select yöntemini kullanabilirsiniz: class Names { public string FirstName{ get..LastName } ). İkinci seçenek tercih edilir fakat burası uygulamanızın Names türünü kullandığı tek yer ise. } } . Koleksiyondaki nesnelerin türü anonimdir. n Aşağıdaki gibi. Numaralandırılabilir koleksiyon türünü tanımlamak için var anahtar sözcüğü kullanımına dikkat edin. LastName = cust.

Country alanının “United States” dizesi ile eşleştiği tüm satırları döndürür.Where(addr => String.Equals(addr. aşağıdaki gibi Where yöntemini kullanabilirsiniz: IEnumerable<string> usCompanies = addresses. Where yöntemi. foreach (string name in usCompanies) { Console. .WriteLine(name). “United States”)) . daha sonra bu satırlara numaralandırılabilir koleksiyondan sadece CompanyName alanını almak için Select yöntemi uygulanır. Bunun için. numaralandırılabilir koleksiyonda içermek istediğiniz alanları belirlemenize ya da planlamanıza imkan sağlar. } Sözdizimi açısından. orijinal koleksiyondan her alanı içeren satırların numaralandırılabilir koleksiyonunu döndürür. (usComp türü. Belirlediğiniz ölçüte uygun olarak veriyi filtreleyen bir yöntem tanımlayan bir parametre alır. lambda deyiminin kullanımının başka bir örneğidir. Bu yöntem. Where yöntemi ilk olarak satırları filtrelemek için uygulanır. ayrıca numaralandırılabilir koleksiyonun içerdiği satırları kısıtlamak isteyebilirsiniz. Örneğin. aşağıdaki şirketleri görüntüler: A Bike Store Bike World Veriyi Sıralamak. OrderBy yöntemi de bağımsız değişken olarak bir yöntem alır. Where yöntemi Select yöntemine benzer. addr türü. Veriyi belirli bir sırada almak için. OrderBy yöntemini kullanabilirsiniz. Gruplamak ve Toplamak SQL dilini biliyorsanız.CompanyName). bir ya da daha fazla anahtar alana uygun dönen satırları gruplayabilir ve her gruptaki satırlara dayalı özet değerleri hesaplayabilirsiniz. Where yöntemi tarafından döndürülen numaralandırılabilir koleksiyondaki her satırın türünün bir başka adıdır. SQL’in basit planlama ve filtrelemeden başka geniş çeşitlilikte ilişkisel işlemler gerçekleştirmenize olanak tanıdığını da biliyorsunuzdur. verinin belirli bir sırada dönmesini istediğinizi belirleyebilir. LINQ da benzer işlevselliği sağlar. Bununla birlikte. İşlemlerin bu sırasını anlamak gerekir. Bu. Select ve Where yöntemleri gibi. Bu koleksiyon üzerinden tekrarlanan foreach ifadesi.Country. addresses dizisindeki satırın bir başka adıdır ve lambda deyimi.Select(usComp => usComp. bu tam deyimin sonucunun türü IEnumerable<string>’dir. Örneğin. sadece United States’de bulunan addresses dizisindeki şirketlerin adlarını listelemek istediğinizi varsayın. string nesnelerinin başka bir numaralandırılabilir koleksiyonunu döndürmek için.) Bu nedenle. ardından bu alanları belirtmek için Select yöntemi uygulanır.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 377 Veriyi Filtrelemek Select yöntemi.

foreach (var companiesPerCountry in companiesGroupedByCountry) { Console. } } Şimdiye kadar. OrderBy ya da OrderByDescending yönteminden sonra ThenBy ya da ThenByDescending yöntemini kullanabilirsiniz. Diğer bir deyişle. her biri bir numaralandırılabilir satır kümesi olan grupların numaralandırılabilir kümesidir.WriteLine(“Country: {0}\t{1} companies”. Sonraki örnek.378 Kısım III Bileşenler Yaratmak veriyi sıralamak için kullanmak isteyeceğiniz deyimi tanımlar. GroupBy yönteminin sonucu. aşağıdaki gibi. Biraz önce gösterilen örnekte.WriteLine(name). Bir ya da daha fazla alandaki ortak değerlere uygun veriyi gruplamak için. Birden fazla anahtar değeri sıralamak isterseniz.Key. companiesPerCountry. } Bu kod bloğu.Country). veriyi gruplamak için alanları belirleyen bir yöntem içerir. GroupBy tarafından belirlenen yöntem tarafından tanımlanan alana bağlı bir numaralandırılabilir koleksiyon kümesinde sıralanmıştır. companies.CompanyName). numaralandırılabilir küme . modeli anlamış olmalısınız! GroupBy yöntemi.CompanyName).CompanyName). foreach (string name in companyNames) { Console. GroupBy yöntemini kullanabilirsiniz. GroupBy yöntemi ile şimdiye kadar gördüğünüz diğer yöntemler arasında bazı ince farklar vardır. sonucu oluşturan alanları seçmek için Select yöntemini kullanmanız gerekmemesidir.GroupBy(addrs => addrs. foreach (var companies in companiesPerCountry) { Console. companiesPerCountry. adres tablosundaki şirketleri alfabetik sırada görüntüler: A Bike Store Bike World Distant Inn Fitness Hotel Grand Industries Veriyi azalan sırada numaralandırmak isterseniz. orijinal kaynak koleksiyondaki tüm alanları içerir fakat satırlar. Örneğin. addresses dizisindeki her şirketin adını artan bir sırada görüntüleyebilirsiniz: IEnumerable<string> companyNames = addresses.WriteLine(“\t{0}”. GroupBy yöntemi tarafından döndürülen numaralandırılabilir küme. En önemlisi. OrderByDescending yöntemini kullanabilirsiniz.Count()).OrderBy(addr => addr. addresses dizisindeki şirketleri ülkeye göre nasıl gruplayacağınızı gösterir: var companiesGroupedByCountry = addresses.Select(comp => comp.

Her ülkedeki şirketi gösteren kod.Count().Count(). Bu kümedeki öğeler. Bu kod bloğunun sonucu şu şekilde olur: Number of companies: 5 Burada bir noktayı vurgulamalıyız.Select(addr => addr.Count(). Console.WriteLine(“Number of countries: {0}”. Max. sırayla her ülke için şirketleri içeren numaralandırılabilir koleksiyonlardır.WriteLine(“Number of companies: {0}”.Select(addr => addr. Bu yöntemlerin sonucunun. Bu hesaplama yöntemleri. aşağıdaki gibi bir kod bloğunu kullanabilirsiniz: int numberOfCompanies = addresses.Country). numberOfCompanies). ülkelerin bir kümesidir.Select(addr => addr. size sadece addresses dizisinde kaç adet satırın CompanyName alanında bir değer olduğunu gösterir.CompanyName). Bu tabloda kaç farklı ülkenin bulunduğunu bilmek isterseniz. numberOfCountries). tek bir sayısal değer olduğuna dikkat edin. Console. her öğenin Key alanını kullanarak grupladığınız değere erişebildiğinize ve ayrıca Count. her ülkedeki şirketler üzerinden tekrarlanan bir başka foreach döngüsü kullanır. Max ve Min gibi hesaplama yöntemlerinin birçoğunu kullanabilirsiniz.Country). Sonuç şu şekilde görünür: Number of countries: 5 Aslında. satırlarda yinelenen değerleri ayırt etmez.Distinct(). . addresses dizisinde sadece üç farklı ülke vardır. Min gibi yöntemleri kullanarak her grup için özet veriyi hesaplayabildiğinize dikkat edin.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 379 companiesGroupedByCountry. numaralandırılabilir koleksiyon değil. addresses dizisinde kaç adet şirket olduğunu bilmek isterseniz. Bunun anlamı şudur: Önceki örnek. Örnek kod tarafından üretilen çıktı şu şekilde görünür: Country: United States 2 companies A Bike Store Bike World Country: Canada 1 companies Fitness Hotel Country: United Kingdom 2 companies Grand Industries Distant Inn Select yönteminin sonuçları üzerinden doğrudan Count. Dışardaki foreach döngüsünde. sırayla her ülkeyi görüntülemek için companiesGroupedByCountry kümesi üzerinden tekrarlanan bir foreach döngüsü ve bu döngü içinde yuvalanmış. şunu denemelisiniz: int numberOfCountries = addresses. United States ve United Kingdom iki defa geçmektedir. Aşağıdaki gibi. Distinct yöntemi kullanarak hesaplamadan tekrarları çıkarabilirsiniz: int numberOfCountries = addresses.

citiesAndCustomers koleksiyonundaki veri çıktısını veren kod.CompanyName }) . Select yöntemi tarafından tanımlanmış verideki ortak anahtar alanları tanımlayan bir yöntem. bulundukları ülke adı ile birlikte nasıl görüntüleyeceğinizi gösterir: var citiesAndCustomers = customers . iki veri kümesi birleştirilir. addrs) => new {custs. (custs. n n Bu örnekte.FirstName.FirstName. foreach (var row in citiesAndCustomers) { Console. Join yöntemi. Country = United States } . addrs => addrs. customers dizisinde ilgilenilen alanları (FirstName ve LastName). bir ya da birden fazla ortak anahtar alan üzerinde birleştirmenize imkan tanır. customers dizisindeki FirstName. addrs.Select(c => new { c.Country }).CompanyName. } Müşterilerin ilk adı ve soyadı customers dizisinde mevcuttur fakat müşterilerin çalıştığı şirketlerin bulunduğu ülke. customers dizisi ve addresses dizisi arasındaki ortak anahtar şirket adıdır. Join yöntemi tarafından döndürülen numaralandırılabilir sonuç kümesinde istediğiniz sütunları belirleyen bir yöntem. custs => custs. customers dizisinin FirstName ve LastName alanları ile addresses dizisinin Country alanını içeren satırlardan meydana gelir.380 Kısım III Bileşenler Yaratmak Console. addresses dizisindeki satırlarla birleştirir. addresses dizisinde saklanır. Select yöntemi. custs. her müşterinin ilk adı ve soyadını. Country = United States } { FirstName = Keith.CompanyName. Başka bir numaralandırılabilir koleksiyon ile Select yöntemi tarafından tanımlanan veriyi birleştirmek için Join yöntemini kullanırsınız. aşağıdaki bilgiyi görüntüler: { FirstName = Orlando. LINQ da birden fazla veri kümesini. customers dizisinin CompanyName alanındaki veri ile addresses dizisinin CompanyName alanındaki veri eşleştiğinde. c. LastName = Gee.Join(addresses. LastName = Harris. LastName ve CompanyName alanlarını içeren numaralandırılabilir koleksiyonu.WriteLine ifadesi şimdi istenilen sonucu verecektir: Number of countries: 3 Verileri Birleştirmek SQL’de olduğu gibi. Sonuç kümesi. Seçilen veriyi birleştirmek için ortak anahtar alanları tanımlayan bir yöntem. c. ortak anahtarı içeren alan (CompanyName) ile birlikte belirtir.LastName. Join yöntemi parametreleri şunlardır: n n Birleştirilecek numaralandırılabilir koleksiyon. Aşağıdaki örnek.WriteLine(row).LastName.

SQL biliyorsanız. LastName = Blanton.FirstName). LastName = Leavitt. Country = United States } Donald. yani addresses dizisinde var olmayan bir şirket müşterisine sahip olabilirsiniz ve hatta bir şirket addresses dizisinde birden fazla adresde yer alabilir. deyimi uygun Select yöntemine dönüştürür. Country = Canada } Lucy. LastName = Lang. . birkaç ileri seviye C# dili özelliklerini kullanılır hale getirmiştir ve sonuç olarak bazen kodun anlaşılması ve bakımı oldukça zor olabilir. from işleci kaynak koleksiyon için bir başka ad tanımlar ve select işleci bu takma adı kullanarak elde edecek şekilde alanları belirler. Bu ifadeyi. Country = Canada } Elsa. Bu bölümde önceki örneklerde gördüğünüz gibi. Country = United Kingdom } Eric.Linq ad alanında tanımlanan Enumerable sınıfı için genişletilmiş yöntemler kullanarak bellekteki veriyi sorgulamak için kullanılan birçok özellik gösterildi.Select(cust => cust. LastName = Blackwell. Koleksiyonlar aynı seviyede veri bütünlüğü sağlamaz. Country = United Kingdom } David. Sizi bu sıkıntıdan kurtarmak için. birleştirdiğiniz veri arasındaki ilişkileri tam olarak anladığınızda çalışır. Country = United States } Janet. from işlecinin select işlecinden önce gerçekleştiğine dikkat edin. Sonuç. her müşterinin uygun şirkete sahip olduğu ve her şirketin de benzersiz bir adrese sahip olduğu varsayılabilir. Sorgu İşleçlerini Kullanmak Önceki bölümlerde. elde ettiğiniz sonuç kesin fakat beklenmeyen bir sonuç olabilir. aşağıdaki gibi başka bir şekilde ifade edebilirsiniz: var customerFirstNames = from cust in customers select cust. LastName = Harrington. İlişkisel veritabanında. her müşterinin ilk adını elde edebilirsiniz: IEnumerable<string> customerFirstNames = customers. Country = United Kingdom } Jackie. müşteri ilk adlarının numaralandırılabilir koleksiyonudur. Birleştirme işlemleri en iyi şekilde. C# derleyicisi.FirstName. Country = United Kingdom } Not Bellekteki koleksiyonların ilişkisel veritabanındaki tablolarla aynı olmadığını ve koleksiyonların içerdiği verinin aynı veri bütünlüğü kısıtlamalarına bağlı olmadığını unutmayın.Bölüm 20 { { { { { { { { FirstName FirstName FirstName FirstName FirstName FirstName FirstName FirstName = = = = = = = = Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 381 Donna. from ve select sorgu işleçlerini kullanarak. System. C# tasarımcıları. SQL’e çok benzeyen bir sözdizimi kullanarak LINQ özelliklerini kullanmanızı sağlayabilmek için C# diline sorgu işleçleri eklediler. Sözdizimi. LastName = Carreras. Bu durumlarda. LastName = Gates. Derleme zamanında. LastName = Liu.

companiesPerCountry.Country.Count(). Veriyi sıralamak için. companies. } } Bir numaralandırılabilir koleksiyon tarafından döndürülen koleksiyon üzerinde. Veriyi nasıl gruplayacağınızı gösteren önceki örnekte olduğu gibi.Country). group işlecini kullanarak veriyi gruplayabilirsiniz: var companiesGroupedByCountry = from a in addresses group a by a.CompanyName).Key.Country. addresses dizisinden United States’de bulunan şirketlerin adını nasıl elde edeceğinizi gösterir: var usCompanies = from a in addresses where String.Distinct(). Kopya olan değerleri ihmal etmek isterseniz. (Aynı ifadenin Select genişletme yöntemine dayalı önceki örneğine başvurmak isteyebilirsiniz. Distinct yöntemini kullanın: int numberOfCountries = (from a in addresses select a. .LastName }. Aşağıdaki örnek.Count().Equals(a. aşağıdaki gibi orderby işlecini kullanın: var companyNames = from a in addresses orderby a. companiesPerCountry.WriteLine(“\t{0}”. “United States”) select a.CompanyName select a. select işleci sağlamadan. aşağıdaki gibi.CompanyName).CompanyName. ) var customerNames = from c in customers select new { c. c.Count()).WriteLine(“Country: {0}\t{1} companies”. Deyimin parantezler içinde yazıldığına dikkat edin. Veriyi filtrelemek için where işleci kullanırsınız.CompanyName. önceki örnekteki kodun aynısını kullanarak sonuçlar üzerinden yineleme yapabilirsiniz: foreach (var companiesPerCountry in companiesGroupedByCountry) { Console.FirstName.382 Kısım III Bileşenler Yaratmak Her müşterinin ilk adını ve soyadını elde etmek için aşağıdaki ifadeyi kullanabilirsiniz. Count gibi hesaplama işlevlerini çağırabilirsiniz: int numberOfCompanies = (from a in addresses select a. foreach (var companies in companiesPerCountry) { Console.

Bu bölümde sadece en yaygın özellikler ele alınmıştır. Ortak bir anahtarda iki koleksiyonu birleştirmek için join işlecini kullanabilirsiniz. veriyi gruplamak. c. var citiesAndCustomers = from a in addresses join c in customers on a.Count(). veri üzerinde arama yapmak. Intersect ve Union yöntemleri sağlar. IEnumerable arabirimini uygulayan herhangi bir koleksiyon sınıfı için tam olarak aynı tekniği kullanabilirsiniz. Take ve Skip yöntemleri kullanarak numaralandırılabilir koleksiyondaki değerleri ayırabilirsiniz. LINQ. Aşağıdaki alıştırmada.LastName. bu defa başka şekilde yazılmış join işleci kullanarak. Birleştirdiğiniz öğeyi (from yan tümcesindeki koleksiyon verisine başvuran) equals işlecinin soluna. koleksiyondaki tüm satırlar boyunca bir alandaki değerlerin sayısı yerine sadece koleksiyondaki satır sayısını saymak isteyebilirsiniz. veriyi birleştirmek ve özet bilgi elde etmek için çok sayıda başka yöntemler de sağlar.FirstName. Başlangıç olarak LINQ genişletme yöntemlerini doğrudan kullanacaksınız fakat daha sonra sorgu işleçlerini kullanmak için kodunuzu düzenleyeceksiniz. İki koleksiyonun ilişkisini belirlemek için equals işleci ile on yan tümceciğini kullanırsınız. koleksiyonda en az bir öğenin ya da her öğenin belirlenen koşula uyup uymayacağını belirlemek için kullanabileceğiniz Any ve All gibi yöntemleri sağlar. birleşeceği öğeyi de ( join yan tümcesindeki koleksiyon verisine başvuran) sağına yerleştirmeniz gerekir. genişlik atama (setwide) işlemlerini gerçekleştirmek için kullanabileceğiniz. LINO. Ayrıca. bir LINQ deyiminin on yan tümceciğindeki deyimlerin sırası önemlidir. bir dizideki veriyi nasıl sorgulayacağınızı göstermiştir. a. orijinal koleksiyon üzerinde doğrudan Count yöntemini çağırabilirsiniz: int numberOfCompanies = addresses. .Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 383 İpucu Birçok durumda. Employee nesnelerinin bir koleksiyonunu içeren bir BinaryTree nesnesi yaratacak ve daha sonra bu bilgiyi sorgulamak için LINQ kullanacaksınız. Not SQL’in tersine. bir şirketin çalışanlarını modellemek için yeni bir sınıf tanımlayacaksınız. Örneğin.Country }. Aşağıdaki örnek.CompanyName select new { c.CompanyName equals c. Visual Studio 2008 tarafından sağlanan belgelere bakın. Daha fazla bilgi için. Bu durumda. Tree<TItem> Nesnelerinde Veri Sorgulamak Bu bölümde şimdiye kadar gördüğünüz örnekler. her koleksiyondaki CompanyName sütunu üzerindeki adresler ve müşterileri döndüren sorguyu gösterir.

this. öğelerini “karşılaştırılabilir” olmak zorunda olarak belirlediğinden bu basamak gereklidir. } { get. this. bu yöntemi kullanarak bir nesneyi dize gösterimine çevirir. public override string ToString() { return String.Format(“Id: {0}. Console.LastName. this. Employee sınıfına. } } 6.cs yazın ve daha sonra Add’i tıklayın. class Employee { . önceki alıştırmalarda gördüğünüz Main ve Entrance yöntemleri ile Program sınıfını tanımlayan Program.. Implement Interface’i işaret edin ve daha sonra Implement Interface Explicitly’i tıklayın. set. 2. this. IComparable<Employee> arabirimini uygulamak için Employee. Add New Item—Query BinaryTree iletişim kutusunda. } 5. set. Name: {1} {2}. Dept: {3}”.cs dosyasındaki Employee sınıf tanımını düzenleyin: class Employee : IComparable<Employee> { } BinaryTree sınıfı.. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 20\ QueryBinaryTree klasöründe yer alan QueryBinaryTree çözümünü açın. 3. Add’i işaret edin ve daha sonra Class’ı tıklayın. Employee sınıfına. Proje. Visual Studio 2008’i başlatın. Name bölümüne Employee.WriteLine ifadesini kullanarak nesneyi görüntülediği gibi. 7. set. Aşağıda gösterildiği gibi. } LastName { get. QueryBinaryTree projesini farenin sağ düğmesiyle tıklayın. . } Department { get.Id.384 Kısım III Bileşenler Yaratmak Genişletilmiş yöntemleri kullanarak Binary Tree’den veri elde edin 1. Solution Explorer’da. set.NET Framework’deki sınıflar. aşağıda koyu harfle gösterilen otomatik özellikleri ekleyin: class Employee { public string public string public string public int Id } FirstName { get.Department).FirstName. . Sınıf tanımındaki IComparable<Employee> arabirimini farenin sağ düğmesiyle tıklayın. aşağıda koyu harfle gösterilen ToString yöntemini ekleyin. 4.cs dosyasını içerir.

CompareTo yönteminin bu uygulaması. Belgeler klasörünüzdeki Microsoft Press\Visual CSharp Step By Step\Chapter 20\BinaryTree klasörüne gidin.Linq. . Program. Solution Explorer’da. CompareTo yönteminin varsayılan uygulamasını oluşturur.cs dosyasının en üstündeki listeye aşağıdaki using ifadesini ekleyin: using BinaryTree. öğeleri karşılaştırması gerektiğinde bu yöntemi çağırdığını hatırlayın. 8. Add Reference iletişim kutusunda.CompareTo(Employee other) { if (other == null) return 1. Solution Explorer’da. int IComparable<Employee>.cs dosyasını açın ve dosyanın en üstündeki using ifadeleri listesinin aşağıdaki kod satırını içerdiğini doğrulayın: using System. if (this. if (this. 10.Id) return -1. Solution Explorer’da. QueryBinaryTree projesini farenin sağ düğmesiyle tıklayın ve sonra Add Reference’ı tıklayın. ağaca öğeleri eklerken. Add Existing Project iletişim kutusunda. } Not IComparable arabiriminin tanımı için Bölüm 18’e başvurun. QueryBinaryTree çözümünü farenin sağ düğmesiyle tıklayın. 12.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 385 Bu eylem. 9. Add’i işaret edin ve daha sonra Existing Project’i tıklayın. BinaryTree sınıfının. Program. BinaryTree ad alanını kapsama almak için. 11.Id) return 1. CompareTo yönteminin gövdesini.Id < other. BinaryTree projesini seçin ve daha sonra OK’i tıklayın. BinaryTree projesi. Bölüm 19’da gerçekleştirdiğiniz numaralandırılabilir BinaryTree sınıfının bir kopyasını içerir. return 0. Id alanının değerine dayalı Employee nesnelerini karşılaştırır. aşağıda koyu harflerle gösterilen kod ile değiştirin. BinaryTree projesini tıklayın ve daha sonra Open’ı tıklayın.Id > other. Projects sekmesini tıklayın.

FirstName = “David”. empTree. Department = “Sales” }).WriteLine(“List of departments”). İlk bölüm.Insert(new Employee { Id = 5. FirstName = “Janet”. Start Without Debugging’i tıklayın. LastName = “Harrington”. Program sınıfındaki Entrance yöntemine aşağıda koyu harfle gösterilen ifadeleri yazın: static void Entrance() { Tree<Employee> empTree = new Tree<Employee>(new Employee { Id = 1.386 Kısım III Bileşenler Yaratmak 13. FirstName = “Lucy”. Department = “Marketing” }).Select(d => d. LastName = “Liu”. LastName = “Lang”. empTree. LastName = “Harris”. LastName = “Gee”. Bu kod. Department = “IT” }). Bölümlerin sırası. . static void Entrance() { .. empTree. } 15. Debug menüsünde. FirstName = “Orlando”. Visual Studio 2008’e dönmek için Enter tuşuna basın. Id değeri 1 olan çalışan için. FirstName = “Keith”. Uygulama aşağıdaki listenin çıktısını vermelidir. Department = “Marketing”}). List of departments Department: IT Department: Marketing Department: Sales Department: IT Department: Marketing Department: Sales Her bölümde iki çalışan olduğundan. Department = “Sales” }). FirstName = “Eric”.Insert(new Employee { Id = 4. } 14. Department = “IT”}). BinaryTree sınıfının bir örneğini kurmak ve doldurmak için. Employee sınıfının veriyi sıralamak için her çalışanın Id özelliğini kullanan CompareTo yöntemi tarafından belirlenir.WriteLine(“Department: {0}”.Insert(new Employee { Id = 6. empTree. her bölüm iki defa yer almaktadır. LastName = “Gates”..Insert(new Employee { Id = 2. empTree. foreach (var dept in depts) Console.Insert(new Employee { Id = 3. Entrance yönteminin sonuna aşağıdaki ifadeleri yazın. 16. Console. ikinci bölüm Id değeri 2 olan çalışan içindir ve böyle devam eder.Department). var depts = empTree. ikili ağaçta bulunan bölümleri listelemek için Select yöntemini kullanır. dept).

WriteLine(“Department: {0}”. Entrance yönteminin sonuna aşağıdaki ifadeleri ekleyin. emp. Console. çifte satırları kaldırır. İçteki foreach ifadesi.WriteLine(“\nEmployees in the IT department”).WriteLine(“\t{0} {1}”.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 387 17. Bölümlerin numaralandırılabilir koleksiyonunu oluşturan ifadeyi aşağıdaki gibi değiştirin: var depts = empTree.Distinct(). var ITEmployees = empTree. Console. Select yöntemi. Entrance yönteminin sonuna.Key). numaralandırılabilir koleksiyondan. foreach (var dept in employeesByDept) { Console. Bu kod bloğu.WriteLine(“\nAll employees grouped by department”).Department.Select(d => d. belirli sütunlar yerine tüm satırı döndürür. 20. Her bölümün sadece bir defa görüntülendiğini doğrulayın: List of departments Department: IT Department: Marketing Department: Sales 19. ikili ağaçta bulunan çalışanları bölümlerine göre gruplandırmak için GroupBy yöntemini kullanır. bölüm adını görüntüler.GroupBy(e => e.FirstName. Dıştaki foreach ifadesi her grup üzerinde yinelenir. dept. Aşağıdaki kodu.Equals(e. çalışanları filtrelemek için Where yöntemini kullanır ve sadece IT bölümü çalışanlarını döndürür. foreach (var emp in dept) { Console. Visual Studio 2008’e dönmek için Enter tuşuna basın. 18. emp. } } . foreach (var emp in ITEmployees) Console. 21.Select(emp => emp). Start Without Debugging’i tıklayın. Debug menüsünde.Department). “IT”)). Bu kod.LastName). her bölümdeki çalışanların adını görüntüler. Distinct yöntemi.WriteLine(emp). var employeesByDept = empTree. önceki basamaktan sonrasına ekleyin.Where(e => String.Department).

Debug menüsünde. 3. Visual Studio 2008’e dönmek için Enter tuşuna basın. Start Without Debugging’i tıklayın. .Department). bölümlerin numaralandırılabilir koleksiyonunu oluşturan ifadeyi açıklama satırına çevirin ve yerine aşağıdaki from ve select sorgu işleçlerini içeren ifadeleri yazın: //var depts = empTree.Department. Dept: IT Id: 4.Equals(e. Uygulama sonucunun daha önceki ile aynı olduğunu doğrulayın. var depts = (from d in empTree select d. Entrance yönteminde. Visual Studio 2008’e dönmek için Enter tuşuna basın. var ITEmployees = from e in empTree where String.Department.Department. 5.Select(emp => emp). Name: Janet Gates. “IT”)).Department).Equals(e.Distinct(). var employeesByDept = from e in empTree group e by e. “IT”) select e. Dept: IT All employees grouped by department Department: IT Janet Gates Keith Harris Department: Marketing Orlando Gee David Liu Department: Sales Eric Lang Lucy Harrington 23. Start Without Debugging’i tıklayın. Uygulamanın sonucunun aşağıdaki gibi olduğunu doğrulayın: List of departments Department: IT Department: Marketing Department: Sales Employees in the IT department Id: 1.Distinct(). Çalışanları bölümüne göre gruplandıran numaralandırılabilir koleksiyonu oluşturan ifadeyi açıklama satırına çevirin ve yerine aşağıdaki ifadeyi yazın: //var employeesByDept = empTree.GroupBy(e => e. 4. Debug menüsünde. 2.Where(e => String. Sorgu işleçlerini kullanarak BinaryTree’den veri elde edin 1. IT bölümündeki çalışanların numaralandırılabilir koleksiyonunu üreten ifadeyi açıklama satırına dönüştürün ve yerine aşağıda koyu harflerle gösterilen kodu yazın: //var ITEmployees = // empTree.Select(d => d.Department). Name: Keith Harris.388 Kısım III Bileşenler Yaratmak 22.

LINQ ayrıca. orijinal verinin bir kopyasıdır ve koleksiyondaki veri değişse de değişmez. Bu koleksiyon.Country. deferred evaluation (ertelenmiş değerlendirme) olarak adlandırılır. QueryBinaryTree projesini görüntüleyin ve Program. şirketi eklerseniz.S şirketlerinin bir numaralandırılabilir koleksiyonunu tanımlar: var usCompanies = from a in addresses where String. LINQ sorgusunun ertelenmiş ve ön belleğe alınmış değerlendirmesinin etkilerini inceleyin 1. Bunun anlamı şudur: Orijinal koleksiyondaki veri bir LINQ sorgusunu çalıştırmak ve sorgunun tanımladığı veriyi bulmak arasındaki sürede değişebilir.Country.WriteLine(name). Visual Studio 2008’e dönün. LINQ. LINQ genişletilmiş yöntem çalıştığı sırada uygulamanın gerçekten koleksiyonu oluşturmadığını unutmamalısınız. } usCompanies koleksiyonunu tanımlama ile koleksiyon üzerinde yineleme arasında addresses dizisindeki veriyi değiştirirseniz (örneğin. . addresses dizisine daha fazla U. Bu yöntemi şu şekilde kullanırsınız: var usCompanies = from a in addresses. aşağıdaki sorgu. bu yeni veriyi de görürsünüz.S. verinin ön belleğe alınmış bir kopyasını içeren bir statik List nesnesi oluşturmak için ToList yöntemini sağlar. ister LINQ genişletilmiş yöntemleri kullanarak ister sorgu işleçlerini kullanarak numaralandırılabilir bir koleksiyon tanımladığınızda.cs dosyasını düzenleyin. usCompanies koleksiyonu üzerinden siz yineleme yapana kadar değerlendirilmez: foreach (string name in usCompanies) { Console. sorgu tanımladığınızda şirketlerin listesi sabitlenir.ToList() where String. “United States”) select a. usCompanies koleksiyon üzerinde yineleme yaptığınızda eklediğiniz şirketleri göremezsiniz.CompanyName. ön belleğe alınmış bir koleksiyon üretmek ile LINQ sorgusunun gecikmeli değerlendirmesini kullanmanın etkilerini karşılaştıracaksınız. “United States”) select a. Bu bölümdeki son alıştırmada. Örneğin. ön belleğe alınan koleksiyonu dizi olarak saklamak için ToArray yöntemini sağlar.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 389 LINQ ve Ertelenmiş Değerlendirme LINQ kullandığınızda. koleksiyon sadece koleksiyon üzerinde yineleme yaptığınızda numaralandırılır. addresses dizisindeki veri geri alınmaz ve Where filtresinde belirtilen durumlar. Bu strateji. ön belleğe alınmış koleksiyonu üretebilirsiniz.Equals(a.CompanyName.Equals(a. LINQ sorgusunun değerlendirilmesini zorlayarak statik. her zaman en güncel veriyi alırsınız. U. United States’de bulunan yeni bir şirket eklerseniz). Bu defa.

LastName = “Harrington”. foreach (var emp in allEmployees) Console. // comment out the rest of the method .390 Kısım III Bileşenler Yaratmak 2. var allEmployees = from e in empTree select e. Department = “Marketing” }).Insert(new Employee { Id = 5. 4.Insert(new Employee { Id = 7. empTree ağacına yeni bir çalışan ekler ve daha sonra allEmployees koleksiyonu üzerinden yeniden tekrarlar. kod bloğunu açıklama satırına dönüştürebilirsiniz. Department = “Marketing” }). empTree ikili ağacını oluşturduktan sonra. empTree. FirstName = “David”. LastName = “Liu”. } İpucu Code and Text Editor penceresinde tüm kod bloğunu seçerek ve daha sonra araç çubuğu üzerindeki Comment Out The Selected Lines düğmesini tıklayarak ya da Ctrl+E ve arkasından da C’ye basarak. Department = “IT” }). allEmployees adında çalışanların numaralandırılabilir bir koleksiyonunu üretir ve daha sonra bu koleksiyon üzerinden yineleyerek her çalışanın ayrıntılarını görüntüler. foreach (var emp in allEmployees) Console.WriteLine(emp). açıklama satırına dönüştürün: static void Entrance() { Tree<Employee> empTree = new Tree<Employee>(new Employee { Id = 1. LastName = “Blanton”. Bu kod. Console. FirstName = “Orlando”. empTree. FirstName = “Donald”. empTree ikili ağacı oluşturan ifadeden ayrı olarak. FirstName = “Eric”. empTree. Entrance yöntemine aşağıdaki ifadeleri ekleyin: Console. Department = “IT” }). Department = “Sales” }). Bu ifadeler.WriteLine(“All employees”).Insert(new Employee { Id = 6.WriteLine(“\nEmployee added”). LastName = “Gates”. LastName = “Harris”. LastName = “Gee”. Bir önceki basamakta yazdığınız ifadelerden hemen sonrasına aşağıdaki kodu ekleyin: empTree. Entrance yönteminin içeriğini. . FirstName = “Janet”. Aşağıda gösterildiği gibi. FirstName = “Keith”. empTree. Department = “Sales” }).Insert(new Employee { Id = 2. LastName = “Lang”. 3. empTree.Insert(new Employee { Id = 3.Insert(new Employee { Id = 4. FirstName = “Lucy”.WriteLine(“All employees”)..WriteLine(emp).. Department = “IT” }). Console.

Dept: IT 5. Name: Keith Harris. Uygulamanın çıktısının aşağıdaki gibi olduğunu doğrulayın: All Id: Id: Id: Id: Id: Id: employees 1. Name: Lucy Harrington. Uygulama çıktısının aşağıdaki gibi olduğunu doğrulayın: All Id: Id: Id: Id: Id: Id: employees 1. Dept: IT 2. veriyi tanımlamak ve hemen ön belleğe almak için allEmployees koleksiyonunu üreten ifadeyi aşağıdaki gibi değiştirin: var allEmployees = from e in empTree. Name: Donald Blanton. Dept: Marketing 6. LINQ. allEmployees koleksiyonu. Dept: Marketing Id: 3. Dept: Marketing 3. Generic olmayan ToList yöntemini belirlerseniz. 8. Dept: IT 2. Dept: Sales Id: 4. Dept: Sales Id: 7. görüntülenen listenin. Debug menüsünde Start Without Debugging’i tıklayın.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 391 5. Donald Blanton adını kapsadığına dikkat edin. Name: Lucy Harrington. object türlerinin bir List ’i olur. Name: Keith Harris. 6. Dept: IT Uygulamanın allEmployees koleksiyonu üzerinde ikinci yinelemesinde. Name: Orlando Gee. Dept: Marketing 3. Dept: IT Id: 2. Debug menüsünde. Name: Lucy Harrington. allEmployees koleksiyonu tanımlandıktan sonra eklenmiş olsa da. Sonucun tür güvenliğinden emin olmak için bu yöntemlerin mümkünse generic biçimlerini kullanmak en iyisidir. Name: Eric Lang. Dept: Sales 4. Name: Orlando Gee. Dept: Marketing 6. Name: David Liu. Start Without Debugging’i tıklayın. Name: Janet Gates. Dept: Sales Employee added All employees . Dept: IT Id: 5. Name: Janet Gates. Dept: Sales 4. Name: Janet Gates. Visual Studio 2008’e dönmek için Enter tuşuna basın. Entrance yönteminde. allEmployees’ı generic List<Employee> koleksiyon olarak üretir. select işleci tarafından döndürülen veri bir Employee nesnesidir ve bu aşamada gösterilen kod. Name: Keith Harris. Name: Eric Lang. Dept: Marketing Id: 6. 7. Dept: IT 5. Name: Eric Lang. Name: Orlando Gee. Name: David Liu. ToList ve ToArray yöntemlerinin generic ve generic olmayan sürümlerini sağlar.ToList<Employee>( ) select e. Dept: Sales Employee added All employees Id: 1. Name: David Liu.

Örneğin: var customerFirstNames = from cust in customers select cust. Visual Studio 2008’e dönmek için Enter tuşuna basın. Save iletişim kutusu görünürse. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. 3. Dept: IT David Liu. Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 21’e geçin.Country. 2. . Dept: Marketing Lucy Harrington. Örneğin: var customerFirstNames = customers.Where(addr => String. Numaralandırılabilir koleksiyondan satırları filtrelemek Where yöntemini kullanın ve satırların eşleşmesi gereken ölçütü içeren bir lambda deyimi belirleyin. “United States”) select a. 9. 5. 4. Dept: IT Orlando Gee. “United States”)). Select(usComp => usComp.Equals(addr.FirstName. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. görüntülenen listenin Donald Blanton adını kapsamadığına dikkat edin.Country. Bunun nedeni. sorgunun Donald Blanton adı empTree ikili ağacına eklenmeden önce değerlendirilmesi ve sonuçların ön belleğe alınmasıdır.FirstName). Ya da where sorgu işlecini kullanın.Equals(a. Dept: Marketing Eric Lang. Bölüm 20 Hızlı Başvuru Bunun İçin Numaralandırılabilir koleksiyondan belirlenen alanları planlamak Şunu Yapın Select yöntemini kullanın ve alanları tanımlayan bir lambda deyimi belirleyin. Dept: Sales Bu defa. Örneğin: var usCompanies = addresses. Ya da from ve select sorgu işleçlerini kullanın. uygulamanın allEmployees koleksiyonu üzerinde ikinci yinelemesinde. Örneğin: var usCompanies = from a in addresses where String. 6. Dept: Sales Keith Harris.Select(cust => cust.CompanyName). Name: Name: Name: Name: Name: Name: Janet Gates.CompanyName.392 Kısım III Id: Id: Id: Id: Id: Id: Bileşenler Yaratmak 1.

Sonuçları içeren bir liste ya da dizi oluşturmak için ToList ya da ToArray yöntemini kullanın. Select(comp => comp. Ya da group by sorgu işlecini kullanın. (custs. custs. İki farklı koleksiyonda tutulan veriyi birleştirmek Birleşecek koleksiyonu.Country }).CompanyName. c.Country. birleşme kriterini ve sonuç için alanları belirleyen Join yöntemini kullanın.Country).CompanyName equals c. c.Country }.FirstName.Bölüm 20 Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 393 Veriyi belirli bir sırada numaralandırmak OrderBy yöntemini kullanın ve satırları sıralamak için alanı tanımlayan bir lambda deyimi belirleyin.FirstName. Örneğin: var companyNames = from a in addresses orderby a.FirstName.CompanyName.CompanyName select new { c. Örneğin: var citiesAndCustomers = from a in addresses join c in customers on a. Bir LINQ sorgusu için sonuçların hemen üretilmesini sağlamak. Örneğin: var citiesAndCustomers = customers.GroupBy(addrs => addrs. Select(c => new { c. a. custs => custs. Join(addresses. Örneğin: var allEmployees = from e in empTree. c. Örneğin: var companiesGroupedByCountry = from a in addresses group a by a. addrs) => new {custs.CompanyName). Örneğin: var companiesGroupedByCountry = addresses. Örneğin: var companyNames = addresses. Ya da join sorgu işlecini kullanın.CompanyName).CompanyName }). addrs => addrs.ToList<Employee>() select e.LastName.LastName. Bir alandaki değerlere göre veriyi gruplamak GroupBy yöntemini kullanın ve satırları gruplamak için kullanılacak alanı tanımlayan bir lambda deyimi belirleyin.CompanyName select a.CompanyName. . addrs.LastName.OrderBy(addr => addr. Ya da orderby sorgu işleci kullanın.

.

sağdan sola mı gerçekleşeceğini belirleyen birleşim özelliği vardır. Örneğin. Bazı işleçleri çiftler halinde geliştirme gerekliliğini anlamak. (int ve double gibi) türler üzerinde (toplama ve çıkarma gibi) standart işlemleri gerçekleştirmek için standart işleç simgelerini (+ ve . Her işlecin.gibi) kullanmada önemli bir aşama kaydettiniz. Bunun anlamı. Kendi türleriniz üzerinde açık dönüştürme işleçleri geliştirmek. Kendi türleriniz üzerinde örtülü dönüştürme işleçleri geliştirmek. Kendi yapı ve sınıflarınız için de işleçler tanımlayabilirsiniz. Örneğin. + işleci sayısal türlerle kullanıldığında “ekle” anlamına gelirken dizilerle kullanıldığında “birleştir” anlamına gelir. İşleçleri Anlamak İşleçleri. Örneğin. Bir unary (tekli) işleç tek işleneni olan işleçtir. işlenenleri deyimler içinde toplamak için kullanırsınız. Örneğin. Örneğin. Kendi türleriniz için artırma ve azaltma işleçleri yazmak. Her işlecin ayrıca. işlecin soldan sağa mı. artırım işleci (++) bir tekil işleçtir. a + b * c ’ nin a + (b * c) ile aynı olduğudur. * işleci + işlecinden daha önceliklidir. bu bölümün konusu budur. Her işleç simgesinin önceliği vardır. çarpım işleci (*) ikili bir işleçtir. 395 .Bölüm 21 İşleç Aşırı Yüklemesi Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n n Kendi türleriniz için ikili işleçler geliştirmek. = işleci sağ birleşiktir (sağdan sola gerçekleşir) bu yüzden a = b = c ile a = (b = c) aynı şeydir. Yerleşik sayısal türlerin birçoğu her işleç için önceden tanımlanmış davranışları ile birlikte gelir. birlikte çalıştığı türe bağlı olarak kendi anlamı vardır. Bir binary (ikili) işleç iki işleneni olan işleçtir. Kendi türleriniz için tekil işleçler geliştirmek.

ama yöntemin adı operator anahtar sözcüğü ile birlikte bildiriyor olduğunuz işlecin simgesi olmalıdır. Örneğin. n n n n İpucu [] imini işleç olarak taklit etmek için dizinleyiciler kullanabilirsiniz. Bu yüzden. Öncelik ve birleşim özellikleri işleç simgesinin üzerinde kullanılacağı türü değil (örneğin int) işleç simgesini temel alır (örneğin +). a + b * c. Bir işlecin çoklu işlenenlerle kullanım özelliğini (işlenen sayısı) değiştiremezsiniz. Bunu yapabilseydiniz işler çok karmaşıklaşırdı. sınıf üyesine erişimi gösteren nokta işlecini (. C# ayrıca. Bunu yaptığınızda kullandığınız işleçler. Örneğin. aşağıda. sözdizimi oldukça farklı olmasına rağmen. bir sayıyı başka bir sayının kuvveti yapmak için yeni bir simge (** gibi) yaratamazsınız. Hour’un iki örneğini toplamak için + ikili işleci tanımlayan kullanıcı tanımlı bir Hour yapısı görebilirsiniz: struct Hour { public Hour(int initialValue) { this. Benzer biçimde. Yeni işleç simgeleri üretemezsiniz. Bir dönüş türü ve parametreler içeren yöntem benzeri bir sözdizimi kullanırsınız.) aşırı yükleyemezsiniz. kendi türlerinizi tanımlarken.396 Kısım III Bileşenler Yaratmak İşleç Kısıtlamaları C#’ın. aşağıdaki kurallarla çok iyi tanımlanmış bir ana çatıya otomatik olarak dahil olurlar: n Bir işlecin öncelik ve birleşim özelliklerini değiştiremezsiniz. Yerleşik türler uygulandığında işleçlerin anlamlarını değiştiremezsiniz. b ve c’nin türünden bağımsız olarak a + (b * c) ile aynı şeydir.value = initialValue. atama (=) imini işleç olarak taklit etmek için özellikleri. bir işlevi işleç olarak taklit etmek içinse temsilcileri kullanabilirsiniz. ifadesi her zaman a. Kendi türünüz için bir * işleci bildirirseniz bu bir ikili işleç olmalıdır. Örneğin. Aşırı Yüklenmiş İşleçler Kendi işleç davranışlarınızı tanımlamak için. Bunu yapabilseydiniz de gereksiz birçok karmaşıklık olurdu. Bunun için bir yöntem yaratmanız gerekir. Aşırı yükleme yapamayacağınız bazı işleç simgeleri vardır. var olan işleç simgelerinden birçoğunu aşırı yüklemenize izin verir. çarpım (x) simgesi ikili bir işleçtir. 1 + 2 deyiminin önceden tanımlı bir anlamı vardır ve bu anlamı geçersiz kılamazsınız. Örneğin. belirli bir işleci aşırı yüklemelisiniz. } . yöntemleri aşırı yüklemenize imkan sağladığını görmüştünüz. Örneğin.

Hour b) { return Hour. } . bu sözdiziminin geçerli C# dili olmadığına. // yalancı kod } Ancak. abstract. + işlecini Hour türünde iki deyim üzerinde kullandığınızda C# derleyicisi kodunuzu otomatik olarak kullanıcı tanımlı işlece yapılan bir çağrıya dönüştürür.Bölüm 21 public static Hour operator+ (Hour lhs. Hour rhs) { return new Hour(lhs. Örneğin. İşleçler asla çok biçimli olamaz ve virtual. Bir işleç bildirirken uymazsanız kodunuzun derlenmeyeceği son bir kural daha vardır: Parametrelerden en az birinin içeren tür olması gerekir. override ya da sealed niteleyiciler kullanamazlar. bir yalancı kod olduğuna dikkat edin. Ancak. private int value. Bir ikili işleci yalnızca kendi iç yazım sistemiyle kullanabilirsiniz (işlenenler arasında simge olacak biçimde). işleçlerin hiçbir zaman gizli bir this parametrelerinin olmadığına dikkat etmelidirler). Bütün işleçler statik olmalıdır.b). Bu örnekte. C# derleyicisi aşağıdaki kodu: Hour Example(Hour a. bir tamsayıyı (saat miktarını) bir Hour nesnesine .value + rhs. Bütün işleçler genel olmalıdır. } İşleç Aşırı Yüklemesi 397 Aşağıdaki noktalara dikkat edin: n n İşleç geneldir.operator+(a. her iki parametre de Hour nesnesidir. Hour b) { return a + b. } şuna dönüştürür: Hour Example(Hour a. ikili işleçler için (left-hand side (sol taraf) ve righthand side (sağ taraf) anlamında) lhs ve rhs kullanabilirsiniz.value).. n İpucu İyi biçimlendirilmiş işlevsellik (işleçler gibi) bildirirken parametreler için bir adlandırma standardı belirlemek çok yararlıdır. İşleç statiktir. Diğer bir deyişle. Bir ikili işlecin (yukarıda gösterilen + gibi) iki açık bağımsız değişkeni ve bir tekil işlecin de bir tane açık bağımsız değişkeni vardır (C++ ile program geliştirenler.. Yukarıda gösterilen Hour sınıfının operator+ örneğinde parametrelerden biri (a ya da b) bir Hour nesnesi olmalıdır.

bir int ile bir Hour’u toplayabileceğinizdir. } . ikinci parametre tamsayı olabilir). (a + b) deyimini geçerli yapabilmek için bir Hour (a. Bu kural derleyiciye. Bunun anlamı.398 Kısım III Bileşenler Yaratmak ekleyen operator+ işlecinin bazı ek uygulamalarını tanımlamanız gereken zamanlar olabilir (ilk parametre Hour.....value + rhs.value).value = initialValue. ilk parametresi Hour ve ikinci parametresi int olan bir + ikili işleç bildirmelisiniz. Hour yapısının bir int’ten bir Hour yaratan bir kurucusu vardır. tek yapmanız gereken int’i Hour’a dönüştürmek için ilk önce Hour kurucusunu kullanmaktır. Hour sum = a + b... ama bir int ile bir Hour’u doğrudan toplamak kadar açık ya da kısa değil. bir işleç çağrısını çözümlerken nereye bakacağı konusunda yardımcı olur ve ayrıca yerleşik işlecin anlamını değiştirmenize de engel olur. int b = .. Diğer bir deyişle. int rhs) { return lhs + new Hour(rhs). Hour sum = a + new Hour(b). sağda) toplamanın ne demek olduğunu bildirmelisiniz. solda) ile bir int’i (b. Aşağıdaki kod önerilen yaklaşımı göstermektedir: struct Hour { public Hour(int initialValue) { this.. } public static Hour operator+ (Hour lhs.. } . } .. public static Hour operator+ (Hour lhs... Örneğin: Hour a = . Bu tamamen geçerli bir kod. int b = . Simetrik İşleçler Yaratmak Bir önceki bölümde.. şunun gibi: Hour a = .. Hour nesnesinin iki örneğini toplamak için bir + ikili işlecinin nasıl bildirileceğini gördünüz. private int value.. Hour rhs) { return new Hour(lhs..

Amaç.value = initialValue. Ayrıca.. Yalnızca yaygın ve anlamlı durumları karşılayın ve farklı bir durum uygulamak gerekliyse sınıfın kullanıcısının ek adımlar atmasına izin verin. bir işleci aşırı yüklüyorsanız.. işlecin arkasındaki gerçek mantık tek bir yerde tutulur. hepsi farklı bir ikinci parametre içeren birçok farklı sürümünü sağlamamanız gerektiğine dikkat edin. private int value. int rhs) { return lhs + new Hour(rhs). Derleyici onu sizin için aşırı yükleme yazmayacak ya da eşleşen bir işleç bulmak için işlenenlerin yerlerini değiştirmeyecektir. Hour sum = a + b.. Hour rhs) { return new Hour(lhs) + rhs. } Not C++ ile program geliştirenler aşırı yüklemeyi kendileri sağlamalıdırlar. public static Hour operator+ (Hour lhs. ortak dil çalışma zamanını (CLR) desteklemez ya da işleç aşırı yüklemesini algılamaz.. İşleçler ve Ortak Dil Belirtimleri Kullanılan her dil. a+b yazabiliyorsanız b+a da yazabilmeyi beklersiniz. Bu yüzden. sol işlenen olarak bir Hour’un sağ işlenen olan bir int ile nasıl toplanacağını bildirir.. ek operator+’nın var olan işlevselliği kolay kullanılır hale getirmesidir. int bağımsız değişkeninden bir Hour oluşturmak ve ardından ilk sürümü çağırmaktır. Sol işlenen olarak bir int’in sağ işlenen olarak bir Hour ile nasıl toplanacağını bildirmez: int a = .. } . Microsoft Visual Basic başlıca örnektir. Hour b = . } . Bu operator+. // derleme zamanı hatası Bu biraz mantığa aykırıdır.. Diğer dillerde de kullanabilmek istediğiniz bir sınıf yaratıyorsanız. bu işlecin..Bölüm 21 İşleç Aşırı Yüklemesi 399 İşlecin ikinci sürümünün tüm yaptığı. operator+’ın ikinci bir aşırı yüklemesini sağlamalısınız: struct Hour { public Hour(int initialValue) { this.. Bu şekilde. } public static Hour operator+ (int lhs. aynı ..

Örneğin: Hour a = . çünkü bu b = b + a ile aynıdır. çünkü yerleşik int türüne bir Hour atamanın yolu yoktur. // a = a + b ile aynı İlk bileşik atama işleci (a += a) geçerlidir. Uygun basit işleci bildirdiyseniz.. // a = a + a ile aynı a += b. a @= b deyimi (burada @ imi herhangi geçerli bir işleç yerine kullanılmaktadır) her zaman a = a @ b şeklinde değerlendirilecektir. a += a. otomatik olarak şunun gibi değerlendirilir: a = a + b. . Hour türü. Toplama geçerli olsa da atama geçersizdir. b+= a yazamayacağınıza dikkat edin. } Sınıfınızı bir Visual Basic uygulamasında da kullanabilmeniz gerekiyorsa. şu: a += b. ikinci bileşik atama işleci (a += b) de geçerlidir çünkü a’nın türü Hour’dur ve b’nin türü int’tir.. int b = .400 Kısım III Bileşenler Yaratmak işlevselliği destekleyen alternatif bir teknik sağlamalısınız. int rhs) { . Hour yapısı için operator+’yı uyguladığınızı varsayalım: public static Hour operator+ (Hour lhs... Benzer biçimde. Genel olarak. } Bileşik Atamayı Anlamak Bir bileşik atama işleci (+= gibi) her zaman ilgili işleci (+ gibi) gibi değerlendirilir.. int rhs) { . Diğer bir deyişle. aynı sonucu veren bir Add yöntemi de sağlamanız gerekir: public static Hour Add(Hour lhs. çünkü a’nın türü Hour’dur ve Hour türü her iki parametresi de Hour olan bir ikili operator+ işleci bildirir.. ilk parametresi Hour ikinci parametresi int olan bir ikili operator+ işleci daha bildirir. Örneğin..... Ancak. ilgili bileşik atama işlecini çağırdığınızda otomatik olarak çağrılır.

. Sonekli bir deyimin sonucu. artırma ve azaltma işleçlerinin dönüş türlerinin parametre türleriyle aynı olması gerektiğidir... Bu denkliğin anlamı. işlenenin deyim gerçekleşmeden önceki değeridir.operator++(now). } . now = Hour.Bölüm 21 İşleç Aşırı Yüklemesi 401 Artırma ve Azaltma İşleçleri Bildirmek C# kendi artırma (++) ve azaltma (--) işleçlerinizi bildirmenize izin verir.. C#. return arg. statik (static) ve tekil olmalıdırlar. etkili bir biçimde şuna dönüştürür: Hour now = new Hour(9). Hour postfix = now++.value++. Bu işleçleri bildirirken de standart kurallar geçerlidir. . Diğer bir deyişle. aşağıda Hour yapısı için artırma işlecini görebilirsiniz: struct Hour { . // yalancı kod C#’ta geçerli değil Hour prefix = now. C# derleyici şunu: Hour now = new Hour(9). } Artırma ve azaltma işleçleri. Hour prefix = ++now. private int value. derleyici şunu: Hour now = new Hour(9). önek ya da sonek biçiminde yazılabilmeleri dolayısıyla benzersizdirler. Hour postfix = now. etkili bir biçimde şuna dönüştürür: Hour now = new Hour(9). public static Hour operator++ (Hour arg) { arg. Örneğin. genel (public). // yalancı kod C#’ta geçerli değil Önekli bir deyimin sonucu ise işlecin dönüş değeridir. zekice. now = Hour. her iki önek ve sonek biçimleri için de aynı işleci kullanır.operator++(now).

now = Hour.value = initialValue. Bu çalışsa da artırma işlecinin derleyici çevirisinin her kullanışında yeni bir nesnenin yaratılmasıyla sonuçlanır. // yalancı kod C#’ta geçerli değil Hour bir sınıfsa. Bu öneri sadece artırma işleci için değil.operator++(now).. Hour bir sınıfken artırma işlecinin doğru uygulaması aşağıdaki gibidir: class Hour { public Hour(int initialValue) { this. atama ifadesi postfix’te now’un bir kopyasını oluşturur ve now ’da yapılacak değişiklikler postfix’i değişmeden bırakır ki bizim de istediğimiz budur. private int value. . yeni bir nesne yarattığına dikkat edin. public static Hour operator++(Hour arg) { return new Hour(arg. Hour’u sınıfa dönüştürüp artırma işlecinin uygulamasını değiştirmeden bırakırsanız sonek çevirisinin doğru yanıtı vermediğini görürsünüz. atama ifadesi postfix = now şimdi postfix (sonek) değişkeninin now ile aynı nesneye başvurmasını sağlar.value + 1). Bu bellek kullanımı ve çöp toplama maliyeti açısından pahalı olabilir. tüm işleçler içindir.. Dolayısıyla.. sınıfları tanımlarken işleç aşırı yüklemelerini sınırlandırmanız önerilir. Hour postfix = now. Bir sınıfın bir başvuru türü olduğunu anımsarsanız ve daha önce açıklanan derleyici çevirilerine yeniden bakarsanız bunun neden oluştuğunu görebilirsiniz: Hour now = new Hour(9).. now’u otomatik olarak güncelleştirmek postfix’i de güncelleştirir! Hour bir yapıysa. } . } . Yeni nesnedeki veri artırılır ancak özgündeki veri değiştirilmeden kalır. } operator++’ın şimdi orijinal veriye bağlı olarak.402 Kısım III Bileşenler Yaratmak Yapı ve Sınıflardaki İşleçler Hour yapısındaki artırma işleci uygulamasının çalışmasının tek nedeninin Hour’un bir yapı olmasından kaynaklandığını anlamak önemlidir.

yoksa bu işleçler kafa karıştırıcı olabilir. Hour rhs) { return lhs. } Bu işleçlerden dönüş türü Boolean olmak zorunda değildir. Ancak başka bir tür kullanmak için iyi bir nedeniniz olmalıdır. kendiniz açıkça yazmalısınız. Örneğin. Aşağıda Hour yapısı üzerindeki == ve != işleçlerini görebilirsiniz: struct Hour { public Hour(int initialValue) { this.value == rhs.value != rhs. operator== işlecini ya da operator!= işlecini tanımlarsanız her ikisini de tanımlamanızı isteyerek bu düşüncenizi destekler. Ayrıntılı bilgi için Visual Studio 2008 ile verilen .. } public static bool operator!=(Hour lhs. hash algoritmaların etkisini azaltacağından tüm nesnelerinizin GetHashCode yöntemindeki aynı tamsayıyı döndürmeyin). } .Bölüm 21 İşleç Aşırı Yüklemesi 403 İşleç Çiftleri Tanımlamak Bazı işleçler doğal olarak çiftler halinde gelir. ne kadar açıkça görünseler de. C# derleyicisi bu işleçlerin hiçbirini sizin yerinize yazmaz...NET Framework Reference belgelerine bakın).Object’ten kalıtımla alınan Equals ve GetHashCode yöntemlerini de geçersiz kılmanız gerekir. GetHashCode yöntemi Microsoft .. >= işleçleri için de geçerlidir. iki Hour değerini == işlecini kullanarak da karşılaştırabilmeyi beklersiniz. Hour rhs) { return lhs.value. C# derleyicisi. Equals yöntemi operator== yöntemiyle tam olarak aynı davranışı göstermelidir (birini diğeri ile tanımlamak). public static bool operator==(Hour lhs. > ve <=. private int value. iki Hour değerini != işleci kullanarak karşılaştırabiliyorsanız.value = initialValue. Bu yöntemin tüm yapması gereken ayırt edici bir tamsayı değer döndürmektir (Ancak. .NET Framework’teki diğer sınıflar tarafından kullanılır.value. Not operator== ve operator!= ’i tanımlarsanız System. Bu ya hep ya hiç kuralı ayrıca <. Onları. bir nesneyi bir hash tablosundaki bir anahtar olarak kullandığınızda bir hash değer hesaplamaya yardımcı olmak için GetHashCode yöntemi nesne üzerinde çağrılır. } . (Örneğin.

404 Kısım III Bileşenler Yaratmak Bir İşleç Uygulamak Aşağıdaki alıştırmada başka bir Microsoft Windows dijital saat uygulamasını tamamlayacaksınız. uygulama henüz oluşturulamaz çünkü Minute yapısı henüz tamamlanmamıştır. 2. İlk alıştırmada. private Minute minute. private Hour hour. if (this. minute ve second değerleri için olan üç alanı güncelleştirerek zamanı kendisi tutar. minute ve second alanlarının bildirimlerini bulun.second++. olay başlatıldığında delegate yöntemi (her saniye çağrılan yöntem) o anki hour (saat). Code and Text Editor penceresinde. private Second second..second == 0) { this. Microsoft Visual Studio 2008’i başlatın. if (this.minute++.hour++. tock yöntemi aşağıdaki gibi görünür: private void tock() { this. her biri hour. minute ve second değişkenlerini güncelleştirmek için bu yöntem her saniye çağrılır. eksik toplama işleçlerini uygulayarak Minute yapısını tamamlayacaksınız. Clock. } 4. Kodun bu biçimi. operator+ aşırı yüklemelerini yazın 1.cs dosyasını açın ve sınıfın sonundaki hour. Bu alanlar o anki saati gösterir: class Clock { .minute == 0) { this. Ancak. } } } . Clock sınıfının tock yöntemini bulun. Bunun yerine delegate yöntemi. Minute ve Second’dır ve tümü yapıdır. Bu üç alanın türleri sırasıyla Hour. 3. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 21\ Operators klasöründe yer alan Operators projesini açın. Bölüm 17’deki alıştırmaya benzer. Ancak. minute (dakika) ve second (saniye) değerlerini almaz.. Hour. bu biçiminde.

Minute. Minute. 9.cs dosyasını açın.value == rhs. Bu ifade. } . } 8.pulsed. tock yönteminin aşağıdaki if ifadesini içermesi ama uygun operator==’un Minute yapısında bildirilmemiş olmasıdır: if (minute == 0) { hour++. operator!=’in sol işlenen olarak Minute ve sağ işlenen olarak da int kabul eden bir sürümünü uygulayın. Bu işlecin dönüş türünün bool olması gerektiğini unutmayın. private int value. int)’ requires a matching operator “!=” to also be defined. int rhs) { return lhs. pulsed alanının tick olayı gerçekleştiğinde bu yöntemin çağrılmasını sağlar (pulsed alanı her saniyede bir olay oluşturmak için DispatcherTimer nesnesini kullanan bir Ticker’dır. this. Build menüsünde Build Solution’ı tıklayın. operator==’ın bir biçimini bildirdiğiniz halde gerekli olan operator!= eşini bildirmemiş olmanızdır. Sorun.operator ==(Operators. Code and Text Editor penceresinde. 5.Minute.. public static bool operator==(Minute lhs.. Code and Text Editor penceresinde operator==’ın sol işlenen olarak bir Minute ve sağ işlenen olarak da bir int alan biçimini geliştirin. .. } İlk göreviniz bu işleci Minute yapısı için uygulamaktır. 7.tick += tock. Build menüsünde Build Solution’ı tıklayın. Tamamlanmış işleç aşağıdaki gibi görünmelidir: struct Minute { . Bu konu Bölüm 17’de açıklanmıştır).. Oluşum hata verir ve farklı bir hata iletisini görüntüler: The operator ‘Operators. Oluşum hata verir ve aşağıdaki hata iletisini görüntüler: Operator ‘==’ cannot be applied to operands of type ‘Operators.Bölüm 21 İşleç Aşırı Yüklemesi 405 Clock sınıfının kurucuları aşağıdaki ifadeyi içerir.Minute’ and ‘int’. Şimdiki sorun. 6.

Dönüştürme İşleçlerini Anlamak Bazen bir türdeki deyimi başka bir türe dönüştürmek gerekir. } 10. Derleyici. private int value.. Örneğin. Uygulama çalışır ve her saniye kendiliğinden güncelleştirilen dijital bir saat görüntüler. int rhs) { return lhs. 11. Yerleşik Dönüştürmeler Sağlamak Yerleşik türlerin yerleşik dönüştürmeleri vardır. ama durum böyle değildir. Bu kez uygulama hatasız biçimde oluşturulur. } } Haklı olarak.. } . yöntem çağrılınca bu dönüştürmeyi gerçekleştiren kodu üretecektir. Build menüsünde Build Solution’ı tıklayın. Örneğin. bir int kapalı biçimde bir double’a dönüştürülebilir.value != rhs. ama bunu ancak ve ancak o değer double’a dönüştürülebiliyorsa yapar. Uygulamayı kapatın ve Visual Studio 2008 programlama ortamına dönün. MyDoubleMethod çağrılırken yalnızca double türündeki değerlerin bağımsız değişken olarak kullanılabilmesini bekleyebilirsiniz.MyDoubleMethod(42).406 Kısım III Bileşenler Yaratmak Tamamlanmış işleç aşağıdaki gibi görünmelidir: struct Minute { . MyDoubleMethod’un türü double olmayan bağımsız değişkenlerle çağrılmasına da izin verir.... aşağıdaki yöntem tek bir double parametresi ile bildirilmiştir: class Example { public static void MyDoubleMethod(double parameter) { . C# derleyicisi.. Debug menüsünde Start Without Debugging’i tıklayın. // kapalı int-double dönüştürmesi . public static bool operator!=(Minute lhs. Kapalı dönüştürme özel bir sözdizimi gerektirmez ve asla bir özel durum oluşturmaz: Example. 12.

. public static implicit operator int (Hour from) { return this.. } Hangi türden dönüştürüyorsanız o tür tek bir parametre (burada Hour) olarak bildirilir ve hangi türe dönüştürüyorsanız o tür operator anahtar sözcüğünden sonra tür adı olarak yazılır (burada int). bir Hour’un kapalı biçimde bir int’e dönüştürülebileceğini bildiren bir işleç görebilirsiniz: struct Hour { .5 olduğunu düşünün. operator anahtar sözcüğünden önce belirtilmiş bir dönüş türü yoktur.0). Diğer yandan. çünkü sonuç özgün değerden dardır (daha az bilgi içerebilir) ve bir OverflowException (TaşmaÖzelDurumu) özel durumu yaratabilir. } private int value. Bir dönüştürme işleci public ve static olmalıdır. Açık bir dönüştürme bazen daraltma dönüştürmesi (narrowing conversion) olarak da adlandırılır.. } } ... aşırı yüklenmiş işlecin sözdizimine benzer. bir double kapalı biçimde bir int ’e dönüştürülemez: class Example { public static void MyIntMethod(int parameter) { .0). // derleme zamanı hatası double’dan int ’e dönüştürme yapmak bilgi kaybına neden olabildiğinden otomatik olarak yapılmaz (MyIntMethod ’un bağımsız değişkeninin 42. Aşağıda.value. Kullanıcı Tanımlı Dönüştürme İşleçleri Uygulamak Kullanıcı tanımlı bir dönüştürme işlecinin sözdizimi.MyIntMethod((int)42. . bu nasıl dönüştürülür?) Bir double bir int’e dönüştürülebilir ama dönüştürme açık bir gösterim sistemi (bir dönüştürme) gerektirir: Example. kapalı ya da açık biçimde başka türlere dönüştürülebilir olup olmadıklarını denetleyebilmeniz için kendi kullanıcı tanımlı türlerinize dönüştürme işleçleri yazmanıza izin verir.Bölüm 21 İşleç Aşırı Yüklemesi 407 Bir kapalı dönüştürme widening conversion (genişletme dönüştürmesi) olarak da adlandırılır çünkü sonuç özgün değerden geniştir (en az özgün değer kadar bilgi içerir ve hiçbir şey kaybolmaz)..MyIntMethod(42. C#. Example.

// açık Hour – int dönüştürmesi Dönüştürme işlecini ne zaman açık ne zaman kapalı olarak bildirmeniz gerekir? Bir dönüştürme her zaman güvenliyse.value + rhs. // kapalı Hour – int dönüştürmesi } } Dönüştürme işleci açık olsaydı bir önceki örnek derlenmezdi çünkü bir açık dönüştürme işleci. ancak “Hello. Örneğin. simetrik işleçleri sağlama sorununu çözmek için alternatif bir yol sunar.408 Kısım III Bileşenler Yaratmak Kendi dönüştürme işleçlerinizi yazarken kapalı dönüştürme mi açık dönüştürme mi olduklarını belirtmelisiniz.. Aksi durumda bir explicit (açık) dönüştürme olarak bildirilmelidir.value = initialValue. bunun anlamı C# derleyicisi onu kapalı biçimde kullanabilir demektir (dönüştürme olmadan): class Example { public static void MyOtherMethod(int parameter) { . Hour ’dan int ’e dönüştürme yapmak her zaman güvenlidir (her Hour..value). (“7” dizesinde sorun yok. } public static Hour operator+(Hour lhs. az önce bahsedilen Hour ’dan int ’e dönüştürme işleci kapalıdır. Example.MyOtherMethod((int)lunch).MyOtherMethod(lunch). Hour + int ve int + Hour) sağlamak yerine. Bir string ’i Hour ’a dönüştüren bir işleç açık olmalıdır. Hour rhs) { return new Hour(lhs. } public static void Main() { Hour lunch = new Hour(12). daha önceden olduğu gibi. (iki Hour parametresi olan) operator+’ın tek bir biçimini ve bir kapalı int ’ten Hour ’a bir dönüştürme sağlarsınız: struct Hour { public Hour(int initialValue) { this. World”ü bir Hour ’a (saate) nasıl dönüştürebilirsiniz?) Simetrik İşleçler Yaratmak (Yeniden) Dönüştürme işleçleri. } . bilgi kaybetme olasılığı yoksa ve özel durum oluşturmuyorsa bir implicit (kapalı) dönüştürme olarak tanımlanabilir. Hour yapısı için operator+’nın üç biçimini (Hour + Hour. karşılık gelen bir int değeri içerir). açık bir dönüştürme işlemini gerektirir: Example. Bunu implicit ya da explicit anahtar sözcüklerini kullanarak yaparsınız. bu yüzden bunun kapalı olması anlaşılabilir. Örneğin. çünkü tüm dizeler geçerli Hour göstermez.

Her işleç parametre tür çiftleri (Second.cs dosyasını görüntüleyin. } . int b) { Hour eg1 = a + b.minute == 0) { this. int) ve (int. Second yapısı şu anda operator== ve operator!= işleçlerinin aşırı yüklenmiş üçer uygulamasını içermektedir. Second yapısına kapalı bir dönüştürme işleci ekleyecek ve yerlerini tutacağı işleçleri sileceksiniz. Operators projesini görüntüleyin.second++. Dönüştürme işlecini yazın 1.second == 0) { this. operator+’yı iki Hour bağımsız değişkeni ile çağırır: void Example(Hour a. // b Hour’a dönüştürüldü Hour eg2 = b + a.cs dosyasını görüntüleyin tock yöntemini tekrar sınayın: private void tock() { this. Bu kod parçası == işlecini kullanarak bir Second ile bir int ’i karşılaştırır. if (this. (Second. private int value.second == 0) ifadesine dikkat edin. . Visual Studio 2008’e dönün.minute++. } } } Önceki kod örneğindeki if (this.. C# derleyicisi otomatik olarak int’i Hour’a dönüştürüp. Second).Bölüm 21 public static implicit operator Hour (int from) { return new Hour (from). } İşleç Aşırı Yüklemesi 409 Bir Hour ile bir int’i toplarsanız (herhangi bir sırada). // b Hour’a dönüştürüldü } Bir Kapalı Dönüştürme İşleci Eklemek Aşağıdaki alıştırmada dijital saat uygulamasını değiştireceksiniz.. if (this. 2.hour++. Code and Text Editor penceresinde Second. Code and Text Editor penceresinde Clock. Second) için aşırı yüklenmiştir.

value.value.. public static implicit operator Second (int arg) { return new Second(arg). kapalı bir dönüştürme işleci kullanmak kapalı dönüştürme işleci kullanmamaktan potansiyel olarak daha yavaştır. Debug menüsünde Start Without Debugging’i tıklayın. } 6.. Build menüsünde Build Solution’ ı tıklayın. Uygulamanın hala doğru olarak çalıştığını doğrulayın.. second == 0) ifadesinin derlenmemesine neden olur. Program bu kez başarıyla oluşturulur çünkü dönüştürme işleci ve geri kalan iki işleç birlikte sildiğiniz dört işlecin işlevini yerine getirir.. Tek fark. } 4. public static bool operator==(Second lhs. Oluşturma başarısız olur ve aşağıdaki hata iletisini verir: Operator ‘==’ cannot be applied to the operands of type ‘Operators. 7.value == rhs..410 Kısım III Bileşenler Yaratmak 3. Second rhs) { return lhs.Second’ and ‘int’ Bir Second ve bir int’i karşılaştıran işleçleri kaldırmak 1. Aşağıdaki iki işleç Second yapısındaki operator== ve operator!= işleçlerin tek sürümleri olmalıdır: struct Second { . int’ten Second ’a dönüştürme yapan Second yapısına kapalı bir dönüştürme işleci ekleyin. operator== ve operator!= işleçlerinin bir Second ve bir int parametresi alan dört versiyonunu silin (iki Second parametresi alan işleçleri silmeyin).. Second yapısında. } public static bool operator!=(Second lhs. Build menüsünde Build Solution’ı tıklayın .. . 5. Dönüştürme işleci aşağıdaki gibi görünmelidir: struct Second { . Second rhs) { return lhs. adımda vurgulanan if (this. Code and Text Editor penceresinde.value != rhs. } . } ..

} .. Save iletişim kutusu görünürse. } .. Bölüm 21 Hızlı Başvuru Bunun İçin Bir işleç uygulamak Şunu Yapın public ve static anahtar sözcüklerini yazın. } ... Örneğin: struct Hour { .. Örneğin: struct Hour { .. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.. bildirmekte olan işlecin türünü ve hangi türden dönüştürme yapılıyorsa parantez içinde bir tek parametre olarak o türü yazın. ardından dönüş türünü ve operator anahtar sözcüğünü ekleyin ve daha sonra bildirilen işlecin simgesini ve parantez içinde uygun parametreleri yazın. } Bir dönüştürme işleci bildirmek public ve static anahtar sözcüklerini yazın. ardından implicit ya da explicit anahtar sözcüğünü ve operator anahtar sözcüğünü ekleyin ve daha sonra dönüştürülen türü.Bölüm 21 İşleç Aşırı Yüklemesi 411 8. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.. public static bool operator==(Hour lhs.. Uygulamayı kapatın ve Visual Studio 2008 programlama ortamına dönün.. Hour rhs) { .. public static implicit operator Hour(int arg) { . Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 22’ye geçin..

.

. . Doğrulamayı Gerçekleştirmek . Menüler ve İletişim Kutularıyla Çalışmak . . . . . . . . . 451 Bölüm 24 . . . . . 473 Kısım IV 413 . . . . . . . . . . . . . . . . . . . . 415 Bölüm 23 . . . . . . . . . . . . . . . . . . . . .Adım Adım Microsoft Visual C# 2008 Windows Uygulamaları ile Çalışmak Bu kısımdaki konular: Bölüm 22 . . . . . . . . . . . . . Windows Presentation Foundation’a Giriş . . . . . . . . . .

.

Artık başlıca dil yeteneklerini edindiğinize göre Kısım IV. İlerleyen 415 . formun görünümüne ve tümüyle çalışıyor olmasına odaklanarak uygulamayı çok basit tutacaksınız. bulmak isteyebileceğiniz en iyi çancıların bir topluluğu olan Middleshire Bell Ringers Association üyelerinin bilgilerini girmesini ve ayrıntılarını görüntüleyebilmesini sağlayan bir uygulama yaratacaksınız. WPF formları ve denetimlerinin özelliklerini tasarım anında ya da çalışma anında değiştirmek.Bölüm 22 Windows Presentation Foundation’a Giriş Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n Microsoft Windows Presentation Foundation (WPF) uygulamaları yaratmak. WPF formları ve denetimlerinin başlattığı olayların bazılarını nasıl durduracağınızı ve işleyeceğinizi öğreneceksiniz. WPF uygulamaları yaratmak için System. lambda deyimleri ve değer türleri ile başvuru türleri arasındaki farklar gibi dilin daha ayrıntılı noktalarının birçoğunu anlıyor olmanız gerekir. Son olarak. şirketinizin standartlarına kolayca uygun hale getirilen kullanıcı arabirimi oluşturmak için WPF modellerinin kullanımını öğreneceksiniz. Bu bölümde. metin kutuları ve düğmeler gibi sık kullanılan WPF denetimleri ile çalışmak WPF denetimleri için modeller tanımlamak. Özellikle. Etiketler. bu yetenekler üzerinde bilgilerinizi nasıl geliştireceğinizi ve Microsoft . Design View ve Properties penceresini ve ayrıca Extensible Application Markup Language ya da XAML dilini kullanarak WPF formları ve denetimlerinin özelliklerini nasıl ayarlayacağınızı göreceksiniz. birçok GUI uygulamasının ortak bileşenlerini kullanarak basit bir WPF uygulaması oluşturmayı öğreneceksiniz. Bir WPF Uygulaması Yaratmak Örnek olarak.Windows ad alanındaki nesneleri nasıl kullanacağınızı göreceksiniz. n Bu kitabın ilk üç kısmındaki alıştırmaları tamamlamış ve örnekleri incelemiş olduğunuza göre Microsoft Visual C# dilinden iyi anlıyor olmanız gerekir. C# kullanarak programların nasıl yazılacağını ve bileşenlerin nasıl yaratılacağını öğrendiniz. Ayrıca. Önce. bir kullanıcının. Genişletilmiş yöntemler. WPF formları ve denetimleri tarafından açığa çıkarılan olayları işlemek.NET Framework’ün bir parçası olarak sunulan Graphical User Interface (Grafiksel Kullanıcı Arabirimi -GUI) kitaplıklarından yararlanmak için C#’ı nasıl kullanacağınızı gösterecek.

3. Middleshire Bell Ringers Association projesini yaratın 1. 2. Location alanına. .4. Visual C#’ı tıklayın. yeni bir proje yarattıktan sonra formu planlayıp. yeni bir WPF uygulaması yaratmak için aşağıdaki işlemleri gerçekleştirin: 2.416 Kısım IV Windows Uygulamaları ile Çalışmak bölümlerde. yüksek derecede adapte edilebilir kullanıcı arabirimleri oluşturmak için WPF formlarının sağladığı bazı özellikleri öğrenecek. Visual Studio 2008 Standard Edition ya da Visual Studio 2008 Professional Edition kullanıyorsanız. Daha önceki bölümlerde Microsoft Visual Studio 2008’de var olan WPF uygulamalarını kullandığınız için ilk birkaç alıştırma sizin için bir tekrar olacak. Aşağıdaki ekran görünümü. Belgeler klasörünüz altındaki \Microsoft Press\Visual CSharp Step By Step\Chapter 22 yolunu yazın. 2.1. New Project iletişim kutusu açılır. form denetimlerini ekleyerek Middleshire Bell Ringers Association uygulamasını oluşturmaya başlayacaksınız. Project Types bölmesinde. menüler ekleyecek ve girilen verilerin anlamlı olduklarından emin olmak için doğrulama işlemlerini geliştireceksiniz. Templates bölmesinde. 2. (Belgeler klasöründeki\ Microsoft Press\Visual CSharp Step by Step\Chapter 22 \Completed BellRingers\ klasöründeki BellRingers projesini oluşturup çalıştırarak bitmiş bir sürümü görebilirsiniz. File menüsünde. uygulamayı bitirdiğinizde nasıl görüneceğini gösteriyor. New’ i işaret edin ve daha sonra Project’ i tıklayın.2.) Bir Windows Presentation Foundation Uygulaması Yaratmak Bu alıştırmada. 2. WPF Application simgesini tıklayın. Visual Studio 2008’i başlatın.

Options iletişim kutusunda. uygulamanın adını kullanır. 3.Window1” xmlns=”http://schemas. Belgeler klasörünüz altındaki Microsoft Press\Visual CSharp Step By Step\Chapter 22 yolunu yazın. Height ve Width özellikleri. Design View penceresi altındaki XAML bölmesinde formu inceleyin. Sağ bölmede. Bu örnekte. OK’ i tıklayın. OK’i tıklayın. Visual Studio projects location metin kutusuna. Formu ve Izgara (Grid) yerleşimini inceleyin 1. Tools menüsünde Options’ı tıklayın. WPF tarafından kullanılan taslakları tanımlayan XML ad alanlarını gösterir.microsoft.6. formun başlık çubuğunda görünen metni belirler. formun varsayılan yükseklik ve genişliğini belirler. 3. OK’i tıklayın. 3. Microsoft Visual C# 2008 Express Edition kullanıyorsanız. 2. sol bölmedeki ağaç görünümünde Projects and Solutions’ı tıklayın.6.1.7.4.com/winfx/2006/xaml” Title=”Window1” Height=”300” Width=”300”> <Grid> </Grid> </Window> Class özniteliği formu uygulayan sınıfın tümüyle nitelendirilmiş adını belirtir. 3. Name alanına BellRingers yazın.5. 3.microsoft. Name alanına BellRingers yazın.8.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas. Bu . formlar için varsayılan ad alanı olarak. xmlns öznitelikleri. Formun XAML tanımlamasının şu şekilde göründüğüne dikkat edin: <Window x:Class=”BellRingers.5.Bölüm 22 Windows Presentation Foundation’a Giriş 417 2. 3. WPF Uygulama şablonu.3. yeni bir grafik uygulaması yaratmak için aşağıdaki işlemleri gerçekleştirin. 3. (XML ad alanlarına aşina iseniz. 3. BellRingers ad alanında Window1 olarak adlandırılmıştır. şimdilik bu xmlns özniteliklerini ihmal edebilirsiniz. 3. File menüsünde New Project’i tıklayın. denetimlerin tümü ve bir WPF uygulama içine birleştirebildiğiniz diğer öğeler bu ad alanlarında tanımlamlara sahiptir.2. New Project iletişim kutusunda WPF Application simgesini tıklayın.) Title özniteliği. Window1 adında boş bir form içerir. Yeni proje yaratılır.

Bu bölümde. Bir diğeri. birden fazla satır ve sütunu (dolayısıyla adlarını) tanımlamak için Grid bölmesinin özelliklerini kullanabilir ve bu satır ve sütunların tanımladığı her hücre içine denetimleri sürükleyebilirsiniz. 5. Design View penceresinde Window1 formunu tıklayın.Controls. StackPanel otomatik olarak. Properties penceresinde. Common kısmında. bazı şeyleri basit tuttuk ve sadece tek bir hücre kullandık. Bir yerleştirme bölmesinin başlıca amacı. denetimleri sürükleyebildiğiniz tek bir hücre tanımı olarak düşünebilirsiniz. denetimleri dikey düzenlemede yerleştirir. Not Grid bölmesi esnektir fakat karmaşıktır. metin kutuları ve etiketler gibi denetimleri formdaki bölmeye yerleştirin.Window denetimi için özellikler görüntüler.Windows. 2. Design View penceresinde. sonraki adımda inceleyeceğiniz bir alt denetim içerir.418 Kısım IV Windows Uygulamaları ile Çalışmak değerleri XAML bölmesinde değiştirerek ya da Properties penceresini kullanarak düzenleyebilirsiniz. bir satırdaki denetimleri soldan sağa doğru düzenleyen ve geçerli satır tümüyle dolduktan sonra bir sonraki satıra geçen WrapPanel örneğidir. kullanıcı çalışma zamanında pencereyi yeniden boyutlandırırsa denetimlerin nasıl yerleştirileceğini yönlendirmektir. Button’u tıklayın ve daha sonra formun sağ üst kısmını tıklayın. Window1 formunu tıklayın ve daha sonra da Toolbox sekmesini tıklayın. formun başlık çubuğunda yeni başlığın görüntülendiğine dikkat edin. içerdiği denetimlerin yerleşimini yönetir. Not Window1 formu. Örneğin.Windows. Title özelliğini tıklayın ve daha sonra formun başlık çubuğundaki metni değiştirmek için Middleshire Bell Ringers Association – Members yazın. 3. Window öğesinin Grid adında bir alt öğe içerdiğine dikkat edin. Bir WPF uygulamasında. XAML bölmesinde. düğmeler. Farklı yerleşim stilleri sağlayan başka bölmeler de mevcuttur. Grid bölmesini. XAML bölmesinde. form çalıştığında uygulanan C# kodu yazarak bu değerleri ve birçok başka özelliği değiştirebilirsiniz. her denetim doğrudan bir öncekinin altına geçecek şekilde. tasarım zamanında denetimlerinizin konumunu tam olarak belirleyebilirsiniz.Grid denetimi için özellikler görüntülerse. bölme türüne uygun olarak denetimler otomatik olarak yeniden boyutlandırılır ve yeniden konumlandırılır. Bu işlem kılavuz yerine formu seçer ve ardından Properties penceresi System. Bununla birlikte. Varsayılan ayar olarak. Properties penceresi System. 4. Ayrıca. Window1 formunda Window1 metnini tıklayın. Bölme. WPF uygulama şablonu tarafından eklenen varsayılan bölme Grid ’dir. . formun Title özniteliğindeki değerin değiştiğine ve Design View penceresinde.

XAML bölmesindeki kodu inceleyin. Grid öğesi ve içeriği. düğme kılavuzun üst köşesinden 84 birim. XAML bölmesindeki satırlar. Design View penceresi denetimi en yakın köşeye bağlar. düğmenin uygun köşeye bağlandığını gösterir.0” Name=”button1” Width=”75” Height=”23” VerticalAlignment=”Top”>Button</Button> </Grid> Not Bu bölüm boyunca. Margin özelliğinin.84. 6. Bir kılavuz üzerine bir kılavuz yerleştirdiğinizde. Kenar boşlukları değerinin 0 olması. kılavuzun üst ve sağ köşelerine saplanmış düğmeyi gösterir. sağ köşesinden 34 birim uzaklıktadır (Her birim 1/96 inch’dir). Button denetimi formda kapsanan Grid denetimine eklenir. aşağıdaki gibi forma eklenir: Formu tıklamanızla birlikte.Bölüm 22 Windows Presentation Foundation’a Giriş 419 Formun üst ve sağ köşelerine sabitlenen iki bağlayıcıyı gösteren düğme denetimi. en üstteki başlık çubuğundan ayrıdır. kılavuzun uygun köşesine bağlama noktalarının herhangi birini ya da tümünü bağlayabilirsiniz.34. Düğmenin HorizontalAlignment ve VerticalAlignment özellikleri denetimin bağlandığı köşeleri ve Margin özelliği de bu köşelere olan uzaklığı gösterir. kılavuzun alt ve sol köşesine bağlanacaktır. Varsayılan ayar olarak. şimdi aşağıdaki gibi görünmelidir (Margin özelliği için değerleriniz değişebilir): <Grid> <Button HorizontalAlignment=”Right” Margin=”0. Bölüm 1’den. siz formu yeniden boyutlandırsanız bile bu uzaklıkları aynı tutmaya çalışacaktır. Denetimi kılavuzun sol altına doğru yerleştirirseniz. sağ ve alt köşelere uzaklığını belirleyen dört değer içerdiğini hatırlayın. kılavuzun sırasıyla sol. üst. Uygulamayı çalıştırdığınızda. WPF çalışma zamanı. basılan sayfaya uyacak şekilde yarım ve girintili gösterilmiştir. Görüntülenen XAML parçasında. Tüm forma yerleşen kılavuz. . Bağlayıcılar.

denetimin karşılıklı köşelere bağlandığını gösteren. Margin özelliğinin şimdi sol kenar boşluğu için sıfır dışında bir değer gösterdiğine dikkat edin.420 Kısım IV Windows Uygulamaları ile Çalışmak 7. Not Bağlantıyı kaldırmak için. Form belirdiğinde. düğme denetimini tıklayın ve daha sonra aşağıdaki resimde gösterildiği gibi. Visual Studio 2008’e dönün. pencereyi yeniden boyutlandırın. kılavuzun köşesine bağlanan bağlantı noktasını tıklayabilirsiniz. Debug menüsünde Start Without Debugging’ı tıklayarak. Bunun yerine. köşeler hareket ettikçe form genişler ya da daralır. formun sol köşesine denetimi iliştirmek için sol bağlantı noktasını tıklayın: XAML bölmesinde. uygulamayı yeniden oluşturun ve çalıştırın. 8. Form belirdiğinde. Formun köşelerini sürüklediğinizde düğmenin formun üst ve sağ köşelere uzaklığının değişmeden sabit kaldığına dikkat edin. Toolbox ’dan forma ikinci bir Button denetimi ekleyin ve formun ortasına yerleştirin. HorizontalAlignment ve VerticalAlignment özelliklerinin varsayılan değeri. Formu kapatarak. 13. Design View penceresinde. formu genişletmeyi ve daraltmayı deneyin. 12. . Stretch adı verilen değerdir. Formu kapatın ve Visual Studio 2008’e dönün. 10. Debug menüsünde Start Without Debugging’i tıklayarak uygulamayı oluşturun ve çalıştırın. Design View penceresinde. 9. 14. Formun sol ve sağ köşelerine bağlandığından düğmenin artık hareket etmediğine dikkat edin. HorizontalAlignment özelliğinin artık belirtilmediğine dikkat edin. Ayrıca. 11.

Forma arka plan resmi ekleyin 1. Form belirdiğinde. Bazen. yeni düğme denetimi ilk düğme denetiminin üstüne çıkar.0” Name=”button2” Width=”75” Height=”23”>Button</Button> İpucu Properties penceresini kullanarak ayrıca. Margin özelliği değerlerini 0’a ayarlayın.0. yeni düğmenin. Margin gibi denetim özelliklerinin birçoğunu ayarlayabilirsiniz. Bu özelliklerle. 16. Form daraldıkça ya da genişledikçe. 17. doğru görünen formlar oluşturabilirsiniz. XAML bölmesinde. Properties penceresini kullanarak özelliklerin tümünü ayarlayamazsınız. Toolbox’daki Common kısmında Image’i tıklayın ve daha sonra form üzerinde herhangi bir yeri tıklayın. Formun yüksekliğini daraltırsanız. Yaklaşımınızda tutarlı olduğunuz sürece. formu yeniden boyutlandırın.0. dörtkenara göre formdaki konumunu aynı tutmaya çalışarak yeniden konumlandığına (formun merkezinde kalmaya çalışır) dikkat edin. VerticalAlignment ve HorizontalAlignment özelliklerini kaldırın ve Width ve Height özelliklerini aşağıdaki gibi ayarlayın: <Button Margin=”0. Bununla birlikte. 18. Not Düğme denetiminin Width ve Height özelliklerini ayarlamazsanız. düğme tüm formu doldurur . Formun arka planında bir resim görüntülemek için bu resim denetimini kullanacaksınız. 2.Bölüm 22 Windows Presentation Foundation’a Giriş 421 15. Formu kapatın ve Visual Studio 2008’e dönün. kullanıcının pencereyi yeniden boyutlandırdığını belirlemek için karmaşık kod yazmak zorunda kalmadan kullanıcının ekran çözünürlüğü ne olursa olsun. Grid gibi yerleştirme bölmelerini kullanarak. yine çok sayıda karmaşık kod yazmak zorunda kalmadan. Ek olarak. uygulamanın kullandığı denetimlerin görünümlerini ve özelliğini değiştirebilirsiniz. Aşağıdaki alıştırmalarda bu özelliklerin bazılarını inceleyeceksiniz. . Design View penceresinde Window1 formunu tıklayın. Debug menüsünde Start Without Debugging’i tıklayarak uygulamayı bir kere daha oluşturun ve çalıştırın. kolaylıkla şirketiniz tarafından istenen herhangi bir tarza uyacak uygulamalar oluşturabilirsiniz. WPF ile. değerleri dikkatlice girdiğiniz sürece XAML bölmesine değerleri doğrudan yazmak kolaydır.

Resim aşağıdaki gibi formda görünmelidir: . projeye kaynak dosya olarak eklediğiniz Bell.Source> </Image> Resim denetiminin amacı.Source> <BitmapImage UriSource=”Bell. Solution Explorer’da. File name kutusuna Bell. Name dışındaki diğer özellik değerlerini kaldırın: <Image Margin=”0.gif dosyası çalan bir çan resmini içerir.gif resmini yükler. 5. XAML bölmesinde. bir resmi görüntülemektir. Resim denetiminin kapalı etiket sınırlayıcısını (/>).422 Kısım IV Windows Uygulamaları ile Çalışmak Not Grid’in arka planında bir resim görüntülemek için başka birçok teknik kullanabilirsiniz. BellRingers projesini farenin sağ düğmesiyle tıklayın. 4. resim denetiminin tanımını aşağıda gösterildiği gibi değiştirin. Burada gösterilen örnek.gif resim dosyasını uygulamanızın kaynak dosyası olarak ekler. Add Existing Item – BellRingers iletişim kutusunda. Bell. Resim kaynağını değişik yollarla belirleyebilirsiniz. Add’i işaret edin ve daha sonra Existing Item’ı tıklayın.0. sıradan etiket sınırlayıcısı (>) ile değiştirmeniz ve kapalı </Image> etiketi eklemeniz gerektiğine dikkat edin: <Image Margin=”0.0” Name=”image1”/> İki düğme denetimi görünür kalacak biçimde. Bu hareket.0.0. XAML bölmesinde.0” Name=”image1” > <Image.0. Belgeler klasörünüz altındaki Microsoft Press\Visual CSharp Step By Step\ Chapter 22 klasörüne geçin. 3.gif” /> </Image.gif yazın ve Add’i tıklayın. Bell. kılavuzu tamamen yerleştirmek için resim denetimi genişler. resim denetiminin Margin özelliğini ayarlayın ve aşağıda gösterildiği gibi. Bu alıştırmada gösterilen yöntem basit olsa da diğer stratejiler daha fazla esneklik sağlayabilir.

0.Source> </Image> İki düğme şimdi resmin önünde görünmelidir. Diğer bölme denetimi örneklerini ilerleyen kısımlarda göreceksiniz. metin kutuları ve etiketler gibi denetimlerin form üzerinde bulunma şekillerini değiştirebilirsiniz. XAML bölmesinde.0. .0” Name=”button2” Width=”76”>Button</Button> <Image Panel. y ekseninin dikey.0. Konu şudur.ZIndex=”1” Height=”23” Margin=”0. daha önce eklenen denetimlerin en üstüne eklendiği bir z sırasına sahiptir. öncelik XAML tanımında yer alma sırasına göre belirlenir. açık bir şekilde denetimin ZIndex özelliği için bir değer belirlemektir. Resim denetimini düğmelerin arkasına götürmenin en az iki yolu vardır.Bölüm 22 Windows Presentation Foundation’a Giriş 423 Ancak bir sorun var. Yüksek ZIndex değerli denetimler. düğmeler.Source> <BitmapImage UriSource=”Bell. Not z sırası terimi. siz aksini belirtmedikçe. düşük ZIndex değerli denetimlerin önünde yer alır.gif” /> </Image. diğer denetimler için bir kapsayıcı olarak görev yapar ve denetimlerin birbirine göre nasıl yerleşeceklerini belirler. Bir forma birden fazla bölme yerleştirebilirsiniz. Not panel (bölme) denetimi. x ekseninin de yatay olduğu üç boyutlu uzayda. WPF ile. z sırası değeri yüksek olan öğeler. Resim arka planda değil ve iki düğme denetimini tümüyle gizliyor. düşük olan öğelerin önünde görünecektir. İki denetim aynı ZIndex değerine sahipse. İkincisi. Grid denetimi bir bölme denetimi örneğidir.0.0” Name=”image1” > <Image. yerleşim bölmesinde yer alan tüm denetimler.0” Name=”button1” Height=”23” VerticalAlignment=”Top”>Button</Button> <Button Panel. z ekseni üzerinde öğenin konumunu gösterir. böylece resim denetiminden sonra görünürler. 6. düğmelerin XAML tanımlarını hareket ettirmektir. Birincisi. düğme ve resim denetimlerinin ZIndex özelliklerini aşağıdaki kodda gösterildiği gibi ayarlayın: <Button Panel.84.ZIndex=”1” Margin=”169.34.ZIndex=”0” Margin=”0.

34. Key özelliğini kullanarak her stile benzersiz bir ad verebilirsiniz. düğme üzerindeki metinde kullanılan yazı tipinin yanı sıra. Button. Not Bir WPF penceresini derlediğinizde. bu stilin kopyasını oluşturarak ikinci düğmenin Resources öğesine ekleyebilir ve daha sonra bu kopyaya başvurabilirsiniz: <Grid> <Button Style=”{DynamicResource buttonStyle}” Panel.Foreground” Value=”White”/> <Setter Property=”Button. Key özelliği. kodda bu öğelere nasıl başvurulacağını gösterir.Resources> Button </Button> Bir denetimin özelliklerine varsayılan değerleri atamak için o denetimin <Style> öğesini kullanabilirsiniz. Stiller daha fazla şey yapabilir. C# kodunuzdaki kaynakları yönetmek isterseniz Name özelliğini belirleyebilseniz de.) Bu örnek. adlandırılan stile dayalı yeni bir stil yaratır ve daha sonra düğmeye bu stili uygular.ZIndex=”1” Margin =”169. Stiller kaynaklardır ve onları denetimin Resources öğesine eklersiniz.Background” Value=”Gray”/> <Setter Property=”Button. Forma eklediğiniz denetimler ve diğer öğeler kendi Name özelliği ayarına sahip olmalıdır çünkü kaynaklarda olduğu gibi. Stiller kapsama sahiptir.0” Name=”button1” Height=”23” VerticalAlignment=”Top”> . Daha sonra denetimin Style özelliğinden yeni stile başvurabilirsiniz.FontFamily” Value=”Comic Sans MS”/> </Style> </Button.Resources> <Style x:Key=”buttonStyle”> <Setter Property=”Button. Form üzerindeki ikinci düğmeden buttonStyle stiline başvurmaya çalışırsanız.0” Name=”button1” Height=”23” VerticalAlignment=”Top”> <Button.84. Design View penceresinde görüntülenen düğmenin.Resource gibi birleşik alt özellik içeren bir denetimin XAML tanımını. Bunun yerine. düğmenin arka plan ve ön plan renkleri için değerleri belirler. kodun okunuşunu ve bakımını kolaylaştırmak için iyi bir uygulamadır.424 Kısım IV Windows Uygulamaları ile Çalışmak Denetimlerin form üzerindeki görünümlerini yönetmek için bir stil oluşturun 1. stilin adırı değil bu koleksiyondaki kaynağın bir tanımlayıcısını gösterir. Visual Studio pencerenin içerdiği kaynakları pencere ile ilişkili bir koleksiyona ekler. XAML bölmesinde. <Button Style=”{DynamicResource buttonStyle}” Panel. formun ilk düğmesini aşağıda koyu harfle gösterilen koddaki gibi değiştirin. birden fazla satır üzerine dağıtmak.84. hiçbir şey olmaz. denetimler kaynağın Key değerini belirterek kaynaklara başvurur.34.ZIndex=”1” Margin =”169. {DynamicResource buttonStyle} sözdizimi. Açıkça söylemek gerekirse. (Bu bölümde daha sonra göreceğiniz gibi. stil için belirlenen özellik değerleri ile eşleşmek için görünümünü değiştirdiğine dikkat edin.

microsoft.Foreground” Value=”White”/> <Setter Property=”Button. o penceredeki tüm denetimlerden bu stile başvurabilirsiniz. kılavuz üzerine bir <Window.Resources> Button </Button> .ZIndex=”1” Height=”23” Margin=”0.microsoft. </Grid> Bununla birlikte.0” Name=”button2” Width=”76”> <Button.com/winfx/2006/xaml” Title=”Middleshire Bell Ringers Association . Resources> öğesini silin.Resources> <Style x:Key=”buttonStyle”> <Setter Property=”Button. pencere için kaynak olarak bir stil tanımlamaktır.Members” Height=”300” Width=”300”> <Window.Background” Value=”Gray”/> <Setter Property=”Button.Resources> <Grid> <Button Style=”{StaticResource buttonStyle}” Panel. 2.Background” Value=”Gray”/> <Setter Property=”Button.. Daha iyi bir strateji. Her iki düğmeden yeni stile başvurun ve kodu daha okunulur yapmak için button2 denetiminin tanımını birden fazla satır üzerine dağıtın.Resources> <Style x:Key=”buttonStyle”> <Setter Property=”Button.Resources> <Style x:Key=”buttonStyle”> <Setter Property=”Button. kaynak tanımı ve kaynağa başvuru ile birlikte aşağıdaki gibidir: <Window x:Class=”BellRingers. Daha sonra. XAML bölmesinde.Foreground” Value=”White”/> <Setter Property=”Button.Background” Value=”Gray”/> <Setter Property=”Button.Window1” xmlns=”http://schemas.. bu yaklaşım oldukça fazla tekrarlanabilir ve düğmelerin stilini değiştirmeniz gerekirse bakımı bir kabusa dönüşebilir.FontFamily” Value=”Comic Sans MS”/> </Style> </Button.Resources> öğesi ekleyin.Foreground” Value=”White”/> <Setter Property=”Button.Resources> Button </Button> <Button Style=”{DynamicResource buttonStyle}” Panel.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.FontFamily” Value=”Comic Sans MS”/> </Style> </Window.FontFamily” Value=”Comic Sans MS”/> </Style> </Button.84.0” Name=”button1” Height=”23” VerticalAlignment=”Top”> Button </Button> .0.34. buttonStyle stilinin tanımını bu yeni öğeye geçirin ve daha sonra her iki düğmeden <Button.0. Formun tüm XAML tanımı için güncellenmiş kod.ZIndex=”1” Margin =”169.Bölüm 22 Windows Presentation Foundation’a Giriş 425 <Button.

0. Design View penceresinde.Source> </Image> </Grid> </Window> Her iki düğmenin de aynı stil ile Design View penceresinde belirdiğine dikkat edin. Window1 formunu tıklayın ve daha sonra Toolbox sekmesini tıklayın. Daha fazla bilgi için. özelliklerin her biri (arka plan. Style etiketinde TargetType özniteliğini belirterek bu yinelemeyi ortadan kaldırabilirsiniz. Bu kapsam dışındaki başvuru çalışır. Örneğin.0. kaynağın tanımlandığı XAML kodunun üstünde buttonStyle stiline başvurdunuz. Stil tanımında hâlâ biraz yineleme vardır. . DynamicResource anahtar sözcüğü yerine StaticResource kullanarak düğme stiline başvurur. dinamik kaynaklardan daha verimlidir çünkü uygulama oluşturulduğunda başvuru analizi yapılır.0. adımında. Statik ve dinamik kaynaklar arasında birçok başka farklılıklar ve bir kaynağa dinamik olarak başvurabilmeniz için kısıtlamalar vardır. etiketler ve metin kutuları gibi diğer denetimler nasıl olur? 4.0” Name =”image1”> <Image. başvurabilmeniz için öncelikle bir kaynağı tanımlamanızı gerektirir. Peki. Common bölümünde TextBox’ı tıklayın ve sonra formun alt bölümünde herhangi bir yeri tıklayın. çünkü DynamicResource kullanmak. C#’daki ile benzerdir. Statik kaynakların kapsama kuralları.ZIndex=”1” Height=”23” Margin=”0. statik kaynaklar.gif” /> </Image. Not Yukarda girdiğiniz kod.ZIndex=”0” Margin=”0. StaticResource kullanarak stile başvuran denetimler güncellenmeyecektir. bununla birlikte dinamik kaynaklar daha fazla esneklik sağlar. fakat DynamicResource kullanarak stile başvuran denetimler güncellenecektir. çalışma zamanında kaynağa başvurunun analizinin yapılmasını kaynağın oluşturulduğu noktaya kadar erteler.426 Kısım IV Windows Uygulamaları ile Çalışmak <Button Style=”{StaticResource buttonStyle}” Panel.0” Name=”button2” Width=”76”> Button </Button> <Image Panel.0. Bu alıştırmanın 1.NET Framework belgelerine başvurun. ön plan ve yazı tipi) açık bir şekilde düğme özellikleri olduklarını belirtir. Genel olarak. uygulama çalıştıkça kaynağın kendisi değişirse (çalışma zamanında stili değiştirmek için kod yazabilirsiniz). 3. Visual Studio 2008 tarafından sağlanan .Source> <BitmapImage UriSource=”Bell. TargetType özniteliğini belirtmek için stil tanımını aşağıdaki gibi değiştirin: <Style x:Key=”buttonStyle” TargetType=”Button”> <Setter Property=”Background” Value=”Gray”/> <Setter Property=”Foreground” Value=”White”/> <Setter Property=”FontFamily” Value=”Comic Sans MS”/> </Style> Forma istediğiniz kadar düğme ekleyebilirsiniz ve tümünü yine buttonStyle stilini kullanarak düzenleyebilirsiniz.

. Gösterildiği gibi iletiyi tıklarsanız.. hatanızı şimdi düzelteceksiniz! 6...” (Belge kök öğesi değiştirilmiş ya da tasarımcıyı güncellerken beklenmedik hata oluştu. daha sonra aşağıda gösterildiği gibi düğme ve metin kutusu denetimlerinde stile başvuruları düzenleyin: <Window x:Class=”BellRingers. Style=”{StaticResource bellRingersStyle}” . Design View penceresinde form kaybolur ve yerine aşağıdaki ileti gelir: Telaşlanmayın. yeniden adlandırmak iyi olacaktır.Bölüm 22 Windows Presentation Foundation’a Giriş 427 5..> Button </Button> <Button Style=”{StaticResource bellRingersStyle}” . XAML bölmesinde.> <Window. Key özelliğini düzenleyin ve stil tanımını TargetType yerine Control olacak şekilde değiştirin.. bir metin kutusunun stili olarak ayarlamaya çalışmak başarısızlıkla sonuçlanır.Resources> <Grid> <Button Style=”{StaticResource bellRingersStyle}” . Stilin TargetType özniteliğini Control olarak ayarlamak..> Button </Button> . Control sınıfından kalıtımla alır. sadece açık bir şekilde Control sınıfına ait özellikler için Setter öğelerini ..Resources> <Style x:Key=”bellRingersStyle” TargetType=”Control”> <Setter Property=”Background” Value=”Gray”/> <Setter Property=”Foreground” Value=”White”/> <Setter Property=”FontFamily” Value=”Comic Sans MS”/> </Style> </Window.. XAML bölmesinde.0... Design View penceresinde “The document root element has been altered or an unexpected error has been encountered in updating the designer. Bununla birlikte. <TextBox . metin kutuları ve düğmeleri de içeren denetimlerin birçok farklı türü.. metin kutusu denetiminin tanımını değiştirin ve buttonStyle stili uygulamaya çalışan. WPF modelinde. /> </Grid> </Window> Stil artık sadece düğmelere uygulanmayacağından. Control sınıfından kalıtımla alınan denetime stilin uygulanabileceğini belirtir. aşağıdaki örnekte gösterilen Style özniteliğini belirtin: <TextBox Style=”{StaticResource buttonStyle}” Height=”21” Margin=”114. Yeniden yüklemek için burayı tıklayın) hata iletisi görünür.Window1” .58” Name=”textBox1” VerticalAlignment=”Bottom” /> Düğme için tasarlanmış bir stili. Click here to reload.44.

Start Without Debugging’ i tıklayın.Triggers> öğesini ekleyin. bu düğmeye ait özelliklerden birini belirlerseniz. Formu kapatın ve Visual Studio 2008’e dönün. Ne yazık ki. 10. bir denetim için IsMouseOver özelliği artık true olmadığında.428 Kısım IV Windows Uygulamaları ile Çalışmak sağlayabilirsiniz.Triggers> </Style> Tetikleyici. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Reload the designer bağlantısını tıklayın. metin kutusunu tıkladığınızda. Tetikleyiciler.) <Style x:Key=”bellRingersStyle” TargetType=”Control”> <Setter Property=”Background” Value=”Gray”/> <Setter Property=”Foreground” Value=”White”/> <Setter Property=”FontFamily” Value=”Comic Sans MS”/> <Style. bir uygulamada önemli bir özel durum (kullanıcının düğmeyi tıklaması gibi) meydana geldiğinde gerçekleştirilecek bir hareketi belirtir. bellRingersStyle stili. Uygulamayı tekrar oluşturmak ve çalıştırmak için Debug menüsünde. çözümü yeniden oluşturun. metin kutusunu tıklayarak bir metin yazdığınızda metin imlecini görmenizi zorlaştırır. olay tarafından gerçekleştirilen hareketler.Triggers> <Trigger Property=”IsMouseOver” Value=”True”> <Setter Property=”Background” Value=”Blue” /> </Trigger> </Style. 8. Tetikleme özelliğindeki değer tersine dönerse. Metin kutusuna bir şeyler yazın ve yazdıklarınızın beyaz renkte Comic Sans MS yazı tipinde belirdiğini doğrulayın. Background özelliği orijinal değerine geri döner. Fare işaretçisini uzaklaştırdığınızda. Bu varsayılan davranış. Bu defa. bir özellik değeri değiştiğinde gerçekleştirilecek olan hareketi belirler. renklerin seçimi. Bu problemi sonraki adımda çözeceksiniz. Daha önce gösterilen örnekte. Formun şimdi görünmesi gerekir. Olaylar. fare işaretçisi üzerine gittiğinde denetimin arka plan rengini geçici olarak değiştirmek için IsMouseOver özelliğindeki değişikliği belirler. tetiklenen hareket tamamlanmamış olur. Control sınıfının parçası olmayan bazı ek özelliklere sahiptir. 9. (TriggerCollection’ın mühürlendiğine (sealed olduğuna) dair bir hata iletisi alırsanız. Düğmelerin aynı şekilde olmadığına dikkat edin. TargetType özniteliğini Control olarak ayarlayamazsınız. Design View penceresinde. özel durum sona erdiğinde tamamlanmamış olur. Düğme denetimleri bu işlevselliği gerçekleştirir ve fare işaretçisi üzerine geldiğinde rengi mavinin farklı bir tonuna dönüşür. 11. Not Tetikleyicileri olaylarla karıştırmayın. . bellRingersStyle stilini düzenleyin ve aşağıdaki kodda koyu renkle gösterilen <Style. metin kutusunun rengi orijinal giri rengine dönüşür. Metin kutusunun gri arka planda olduğuna dikkat edin. stilde belirtilen tetikleyiciyi geçersiz kılar. (Düğmeler. özellik değerlerindeki geçici değişikliklere karşılık verir. XAML bölmesinde. mavi renk olur ve metin imlecini rahatlıkla görebilirsiniz.) 7.

bu App. bu dosyada tanımlanan pencere sınıfının adı değişmez. aşağıdaki gibi olduğunu görürsünüz: <Application x:Class=”BellRingers.xaml dosyasını açarsanız.xaml olarak kalır). Anahtar özellik. XAML dosyasının adına başvurduğunu kavramak önemlidir. Application nesnesinin yaratılması gereken pencere için XAML dosyasını belirten StartupUri özelliğidir. . Bir uygulama başladığında hangi formu görüntüleyeceğini nereden bilir? Bölüm 1’den hatırlarsanız. Not Form üzerindeki tüm denetimlere genel olarak bir yazı tipi uygulayabilmeniz için alternatif bir yaklaşım.microsoft. bu özellik. Bir pencere için metin özellikleri belirtirseniz ve bu penceredeki denetimlere stil uygularsanız. Application nesnesi. Uygulamayı oluşturduğunuzda. derleyici bu XAML tanımını bir Application nesnesine dönüştürür. Farklı bir form görüntülemek isterseniz. Bunlar. Formu kapatın ve Visual Studio 2008’e dönün.App” xmlns=”http://schemas. Sınıfın varsayılan adı Window1’dir.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas. tutarlı olun. sadece StartupUri özelliğinin değerini değiştirmeniz gerekir. FontFamily. Sınıfı yeniden adlandırırsanız. belirtilen WPF formunu yaratan ve açan koda çevrilir. dosya ve pencere sınıf adlarının her ikisini de değiştirin.com/winfx/2006/xaml” StartupUri=”Window1. Bir WPF Uygulaması Nasıl Çalışır? Bir Windows Forms uygulaması herhangi bir sayıda form içerebilir: Visual Studio 2008’te Project menüsündeki Add Window komutunu kullanarak bir uygulamaya ek formlar ekleyebilirsiniz. StartupUri özelliğinin. bu nedenle yeniden adlandırmak istediğinizde. Benzer şekilde. bu XAML dosyasında pencereyi gerçekleştiren sınıfa değil. FontSize ve FontWeight özelliklerini kapsar. tetikleyiciler gibi ek kolaylıklar sağlar ve yazı tipi ile ilişkili özellikler ayarlamak zorunda olmazsınız.xaml”> <Application. denetimlerin stili pencere stiline göre önceliğe sahip olur.microsoft. dosya adı değişmeyecektir (Window1. uygulama için Main yöntem sağlayan nesne olarak düşünebilirsiniz. BellRingers projesi için App.xaml dosyasının amacıdır. Bununla birlikte. denetimleri tutan pencerenin metin özelliklerini ayarlamaktır. dosya adını değiştirirseniz.Bölüm 22 Windows Presentation Foundation’a Giriş 429 12. Pencere sınıfı ve XAML dosyası farklı adlara sahipse bu karmaşıklığa neden olabilir. Application nesnesini. stiller.Resources> </Application> Bir WPF uygulaması oluşturduğunuzda. uygulamanın süresini denetler ve uygulamanın başlangıçta görüntüleyeceği formu oluşturmaktan sorumludur.Resources> </Application.

diğer daha güçlü denetimlere çok fazla aşina olmayabilirsiniz. aynı anda sadece bir çan çalsa da. Son olarak. false ve null’dur. bunun için en iyi denetim türüdür. kule kaptanının yönlendirmesi altında çan çalanlar grubu kendi çanlarını farklı . birkaç denetim eklediniz ve stil tanımladınız. IsThreeState özelliği True olarak atanmadıysa tam olarak üç duruma sahip olabilir. bazı özellikleri ayarladınız.430 Kısım IV Windows Uygulamaları ile Çalışmak Forma Denetimler Eklemek Şimdiye kadar. bu tonlar çan çalma birliği tarafından “yöntemler” olarak adlandırılır). İpucu CheckBox denetimleri. Eski Microsoft Windows Forms kitaplığı. Üç durum. Middleshire bölgesi birkaç kuleye sahiptir fakat liste statiktir. küçük bir engel vardır: WPF kütüphanesi bir eşdeğer denetim sağlamaz. çanların asıldığı bir “kuleye” sahiptir. true. Bir veritabanındaki tablodaki bazı sütunlar null değerlere olanak sağlar. TextBox. uygulama üyenin çalabildiği tonların kaydını tutar (daha karmaşığı. Üyenin ilk adını ve soyadını girmek için TextBox denetimlerini kullanacaksınız. üyelerin topluluğa ne zaman katıldıkları ve çan çalma deneyimleri (1 yıla kadar. üyenin “kaptan” (diğer çan çalanlarla bağlantıyı sağlayan kişi) kulesi olup olmadığını da kaydeder. Üyenin deneyimini göstermek için seçenek düğmelerini kullanabilirsiniz (seçenek düğmeleri birbirini dışlayan değerler kümesi sağlar). WPF kütüphanesi çeşitli denetimlerin koleksiyonuna sahiptir. WPF Denetimlerini Kullanmak Bir sonraki alıştırmada. Her biri belirli türde veri girişine uygun olan çeşitli denetimler kullanacaksınız. üyenin topluluğa katıldığı tarihi göstermek için kusursuzdur. Bir ilişkisel veritabanından elde edilen bilgiyi görüntülüyorsanız bu durumlar kullanışlıdır. CheckBox ve ComboBox gibi bazı denetimlerin amacı oldukça açık iken. Bu işlevselliği sağlamak için kendi denetiminizi uygulayabilirsiniz ya da bir WPF formuna DateTimePicker denetimi eklemek için Windows Forms birlikte işlerliğini ve WindowsFormsHost denetimini kullanabilirsiniz. Bununla birlikte. Form ayrıca. Bu tür veriyi işlemek için en iyi denetim ComboBox’tır. Bu uygulamada sonraki yaklaşımı benimseyeceksiniz. Çok sık yeni kule eklenmeyeceğini ve eski kulelerin de çok fazla kaldırılmadığını umuyoruz. tutulan değerin tanımlı olmadığını ya da bilinmeyen değer olduğunu gösterir. 1 ile 4 yıl arasında. Formu kullanışlı yapmak için. ListBox. Her üye. 5 ile 9 yıl arasında ve 10 yıl ya da daha fazla) olduğuna dair istatistiksel bilgi toplar. bir form yarattınız. tarihleri seçmek ve görüntülemek için DateTimePicker denetimi sağlar ve bu denetim. forma kullanıcının çan çalma topluluğu üyeleri ile ilgili ayrıntıları girdiği denetimler ekleyeceksiniz. Bir çan çalıcı. CheckBox. biraz daha fazla denetim eklemeniz ve bazı kodlar yazmanız gerekir. Uygulama ayrıca. seçilmiş (True) ya da seçilmemiş (False) olabilir.

XAML bölmesinde.Window1” .. Gerçek dünyada. Design View penceresinde. Formdan iki düğme denetimini ve metin kutusu denetimini kaldırın. Title=”.. formdaki denetimleri sıfırlamak ve girilen veriyi iptal etmek için Clear’ı tıklayabilir.. Design View penceresinde Window1. Etiketi tam olarak konumlandıramadığınız ve boyutlandıramadığınız için endişelenmeyin.. bu listeyi bir veritabanında saklayacaksınız. XAML bölmesinde.xaml’in görüntülendiğinden emin olun.>First Name</Label> İpucu Ayrıca etiket tarafından görüntülenen metni ve Properties penceresindeki Content özelliğini ayarlayarak birçok diğer denetimi de değiştirebilirsiniz.) . bu nedenle yöntemlerin listesi zamanla değişebilir. Kullanıcı üyenin ayrıntılarını girdiğinde. Toolbox’dan bir TextBox denetimini forma.” Height=”470” Width=”600”> . forma uygulayacağınız yöntemlerin küçük bir seçimini kullanacaksınız..) Bu bilgiyi görüntülemek ve üyenin yöntemi çalıp çalamadığını göstermek için iyi bir denetim. Grandsire.Bölüm 22 Windows Presentation Foundation’a Giriş 431 sıralarda çalarak basit bir müzik yapabilirler.. etiket adını First Name olarak değiştirin: <Label .. CheckBox denetimlerinin listesini içeren ListBox denetimidir. Çeşitli çan çalma yöntemleri vardır ve Plain Bob. Bu uygulamada. İpucu Hizalama denetimlerine yardımcı olmak için Design View penceresi tarafından görüntülenen kılavuz çizgilerini kullanabilirsiniz. 5. Design View penceresinde Window1 formunu tıklayın. Add düğmesi veriyi onaylayacak ve saklayacaktır. Forma denetimler ekleyin 1. Stedman. Her geçen gün yeni yöntemler yazılır. formun Height özelliğini 470 olarak ve Width özelliğini 600 olarak değiştirin: <Window x:Class=”BellRingers. (“Veriyi Yönetmek” başlıklı Kısım V’te bir veritabanındaki veriye nasıl erişeceğinizi ve veriyi nasıl alacağınızı göreceksiniz. </Window> 3. Window1 formunu tıklayın. Reverse Canterbury. daha sonra bu işlemi birkaç denetim için de yapacaksınız. etiketin sağ tarafına sürükleyin. 4. Kent Treble Bob ve Old Oxford Delight gibi eski seslere sahiptir.. Toolbox ’ dan forma bir Label denetimi sürükleyin ve sol üst köşeye yakın bir yere yerleştirin. 2. Kullanıcı. (Kılavuz çizgileri siz form üzerinde denetimi sürükledikten sonra görüntülenir.

Windows..432 Kısım IV Windows Uygulamaları ile Çalışmak 6.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas. bu metin kutusunun Name özelliğini lastName olarak değiştirin. DateTimePicker denetimini tutmak için forma bir WindowsFormsHost denetimi ekleyeceksiniz.Window1” xmlns=”http://schemas. firstName olarak değiştirin: <TextBox .Forms ve WindowsFormsIntegration derlemelerine başvurmasını gerektirir. 12. XAML bölmesinde. 9. CTRL tuşunu basılı tutarak System. firstName metin kutusunun altına ve Tower etiketinin sağına yerleştirin.microsoft. Windows. Forma ikinci bir Label denetimi ekleyin. Forma üçüncü bir Label denetimi ekleyin ve doğrudan First Name etiketi altına yerleştirin. XAML bölmesinde. aşağıda gösterildiği gibi. </Window> . etiket metnini Last Name olarak değiştirin.Windows. Forma dördüncü Label denetimini ekleyin ve Tower etiketinin altına yerleştirin./> 7. Forma başka bir TextBox denetimi ekleyin ve Last Name etiketinin sağına yerleştirin.. Forma bir CheckBox denetimi ekleyin. 14.. firstName metin kutusunun sağına yerleştirin. XAML bölmesinde.. Aşağıdaki basamaklarda. XAML bölmesinde. 13. 11.assembly=System.Forms” Title=. Add Reference iletişim kutusunda . Name=”firstName” ..Windows.. XAML bölmesinde. XAML bölmesinde. BellRingers projesi altındaki References klasörünü farenin sağ düğmesiyle tıklayın ve daha sonra Add Reference’ı tıklayın. Windows Forms kütüphanesindeki türleri kapsam içine getirir ve wf’i bu ad alanı için takma ad olarak saptar: <Window x:Class=”BellRingers.NET sekmesini tıklayın. Solution Explorer ’da. metin kutusunun Name özelliğini. Bu bildirim.Forms ve WindowsFormsIntegration derlemelerini seçin ve daha sonra OK’i tıklayın. etiket metnini Tower olarak değiştirin. XAML bölmesinde.com/winfx/2006/xaml” xmlns:wf=”clr-namespace:System.> . 8. açılan kutunun Name özelliğini isCaptain olarak değiştirin ve bu onay kutusunda görüntülenen metni Captain olarak değiştirin. 10. XAML bölmesinde..microsoft. aşağıda koyu harflerle gösterilen XML ad alanı bildirimini Window1 formuna ekleyin. bu açılan kutunun Name özelliğini towerNames olarak değiştirin.Forms. Bu denetimler uygulamanın System. bu etiketin metnini Member Since olarak değiştirin. Forma bir ComboBox denetimi ekleyin.. lastName metin kutusunun altına ve towerNames açılan kutusunun sağına yerleştirin.

/> </GroupBox> .) WindowsFormsHost denetimi için tamamlanmış XAML kodu şu şekilde görünmelidir: <WindowsFormsHost . 18. 16. Toolbox’da. Name=”hostMemberSince” . Windows. WindowsFormsHost denetiminin kapatma etiket sınırlayıcısını (/>).. Ek olarak. sıradan sınırlayıcı karakteri olarak değiştirmeniz ve bir </WindowsFormsHost> etiketi eklemeniz gerekir.> <StackPanel . yeni denetimi görmek için sayfayı aşağıya doğru çekmeniz gerekebilir. Name=”stackPanel1” .. grup kutusunun Name özelliğini yearsExperience olarak ve Header özelliğini de Experience olarak değiştirin.. Visual Studio pencerelerinizin nasıl düzenlendiğine bağlı olarak.Bölüm 22 Windows Presentation Foundation’a Giriş 433 15.. forma WindowsFormsHost denetimi ekleyin ve towerNames açılan kutusunun altına yerleştirin. denetim kullanılabilir hale gelir. XAML bölmesinde..> <wf:DateTimePicker Name=”memberSince”/> </WindowsFormsHost> DateTimePicker denetimi form üzerinde görünmeli ve geçerli tarihi göstermelidir. Forma Toolbox’ın Containers bölümünden bir GroupBox denetimi ekleyin ve Member Since etiketinin altına yerleştirin. Header özelliği form üzerinde grup kutusu için etiketi değiştirir.. 19. Bu denetimin yerleştirilmesi konusunda endişelenmeyin çünkü bir sonraki alıştırmada XAML tanımında denetimlerin özelliklerini düzenleyeceksiniz.... XAML bölmesinde. WindowsFormsHost denetiminin Name özelliğini hostMemberSince olarak değiştirin. Controls bölümünde.Forms ve WindowsFormsIntegration derlemelerine başvurular eklediğiniz sürece bu uyarıyı ihmal edebilirsiniz..Forms ad alanına başvuruları doğru bir şekilde analiz edebilmesi için bu basamak gereklidir. System. WindowsFormsHost denetimine alt özellik olarak bir Windows Forms DateTimePicker denetimi ekleyin ve memberSince olarak adlandırın. Name=”yearsExperience” . Uygulamaya Windows Forms denetimleri eklemeden önce. Not WindowsFormsHost denetimini yerleştirmenizden sonra. Yine XAML bölmesinde. GroupBox denetimi için XAML kodu içinde StackPanel denetiminin meydana geldiğini doğrulayın: <GroupBox Header=”Experience” . WindowsFormsHost’un bulunamadığını söyleyen bir uyarı görüntülenebilir..Windows. XAML bölmesinde. Build menüsünde Build Solution’ı tıklayın.. Visual Studio 2008’in System. XAML bölmesinde. 17. (Diğer alt özelliklerde olduğu gibi. Forma StackPanel denetimi ekleyin ve yearsExperience grup kutusu içine yerleştirin.

XAML bölmesinde.>10 or more years</RadioButton> 22. StackPanel denetimine üç RadioButton denetimi daha ekleyin. 0. Aşağıdaki tabloda. 25.. Forma bir ListBox denetimi ekleyin ve GroupBox denetiminin sağına yerleştirin.. XAML bölmesinde. Otomatik olarak yukardan aşağıya doğru sıralanmalıdır. her bir denetime atamanız gereken değerler ve yerleşim özellikleri listelenmiştir. 25. Forma bir Button denetimi ekleyerek GroupBox denetiminin altına.>5 to 9 years</RadioButton> Name=”accomplished” . XAML bölmesinde. bu düğmenin Name özelliğini clear olarak ve bu düğme tarafından görüntülenen metni de Clear olarak değiştirin. Forma bir RadioButton denetimi ekleyin ve yeni eklediğiniz StackPanel denetimine yerleştirin.. denetimler yerinde kalacak şekilde tasarlanmıştır. seçenek düğmeleri StackPanel denetiminin üst kısmından 10 birim uzaktadır ve seçenek düğmeleri arasında da yatay olarak 20 birim mesafe vardır.434 Kısım IV Windows Uygulamaları ile Çalışmak 20.... 21. StackPanel denetiminde önceki öğeye bağlı olduğuna dikkat edin. 0. Forma başka bir Button denetimi ekleyerek...... . Name=”novice” . Denetimlerin kenar boşlukları ve hizalaması. liste kutusunun Name özelliğini methods olarak değiştirin. Denetim label1 Özellik Height Margin VerticalAlignment HorizontalAlignment Width Değer 23 29. . Add düğmesinin sağındaki düğme yanına yerleştirin. 23... 24. her seçenek düğmesinin Name özelliğini ve görüntülediği metni aşağıdaki gibi değiştirin: <GroupBox.. Seçenek düğmeleri için belirlenmiş kenar boşluğu değerlerinin. 0 firstName Height Margin .. Forma tüm gerekli denetimleri eklediniz. 0 Top Left 75 21 121.. Bir sonraki basamak yerleşimi düzenlemektir..> <StackPanel . formun sol alt köşesindeki düğme yakınına yerleştirin...>Up to 1 year</RadioButton> Name=”intermediate” .>1 to 4 years</RadioButton> Name=”experienced” . bu düğmenin Name özelliğini add olarak ve bu düğme üzerindeki metni de Add olarak değiştirin. XAML bölmesini ya da Properties penceresini kullanarak bu değişiklikleri yapın.. XAML bölmesinde. kullanıcı formu yeniden boyutlandırırsa.> <RadioButton <RadioButton <RadioButton <RadioButton </StackPanel> </GroupBox> . .

0 Top Left 175 23 29. 25. 25.Bölüm 22 Windows Presentation Foundation’a Giriş 435 Denetim Özellik VerticalAlignment HorizontalAlignment Width Değer Top Left 175 23 305. 0. 0 Top Left 75 21 380. 134. 0. 0 Top label2 Height Margin VerticalAlignment HorizontalAlignment Width lastName Height Margin VerticalAlignment HorizontalAlignment Width label3 Height Margin VerticalAlignment HorizontalAlignment Width towerNames Height Margin VerticalAlignment HorizontalAlignment Width isCaptain Height Margin VerticalAlignment HorizontalAlignment Width Label4 Height Margin VerticalAlignment . 72. 0 Top Left 75 23 29. 0. 0 Top Left 75 21 121. 0. 0. 0. 72. 72. 0 Top Left 275 21 420.

20. 0. 0 Top Left 275 200 29. 0 120 16 0. 0 120 200 310. 174. 0. 0 120 16 0. 0. 20. 134. 0 Top Left 258 151 224 16 0.436 Kısım IV Windows Uygulamaları ile Çalışmak Denetim Özellik HorizontalAlignment Width Değer Left 90 23 121. 0. 0. 0. 0 Top Left 245 hostMemberSince Height Margin VerticalAlignment HorizontalAlignment Width yearsExperience Height Margin VerticalAlignment HorizontalAlignment Width stackPanel1 Height Width Novice Height Margin Width Intermediate Height Margin Width Experienced Height Margin Width Accomplished Height Margin Width Methods Height Margin VerticalAlignment HorizontalAlignment Width . 10. 0 120 16 0. 174. 0. 20.

Resources> 2.>First Name</Label> Aynı stili aşağıdaki denetimlere de uygulayın: n n n label2 label3 isCaptain ... XAML bölmesinde. 388. 0.. 0 Top Left 75 23 313. <Window. label1 denetimine. 0. </Style> </Window. aşağıda gösterildiği gibi. Mevcut bellRingersStyle stilini olduğu yerde bırakın. denetimlere stil uygulayacaksınız. 0 Top Left 75 Clear Height Margin VerticalAlignment HorizontalAlignment Width Son olarak. Denetimlere stiller uygulayın ve formu test edin 1. bellRingersFontStyle stilini uygulayın: <Label Style=”{StaticResource bellRingersFontStyle}” . Bu stilin. fakat etiketler. sadece bu stile başvuran denetimlerin yazı tipini değiştirdiğine dikkat edin. <Windows.. XAML bölmesinde.Resources> öğesine aşağıdaki kodda koyu renkle gösterilen bellRingersFontStyle stilini uygulayın. 388.Resources> <Style x:Key=”bellRingersFontStyle” TargetType=”Control”> <Setter Property=”FontFamily” Value=”Comic Sans MS”/> </Style> <Style x:Key=”bellRingersStyle” TargetType=”Control”> . açılan kutu ve seçenek düğmeleri muhtemelen gri arkaplanda görüntülenmemelidir. Düğmeler ve metin kutuları gibi denetimler için bellRingersStyle stilini kullanabilirsiniz.Bölüm 22 Windows Presentation Foundation’a Giriş 437 Denetim Add Özellik Height Margin VerticalAlignment HorizontalAlignment Width Değer 23 188.

Aşağıdaki denetimlere bellRingersStyle stilini uygulayın: n n n n firstName lastName add clear 4. Form çalıştığında aşağıdaki resimdeki gibi görünmelidir: Methods liste kutusunun şu anda boş olduğuna dikkat edin. . 6. otomatik olarak stilin bu denetimlerde görüntülenen öğeler tarafından kullanılmasına neden olur. sonraki alıştırmada bu açılan kutuyu doldurmak için kod yazacaksınız. 5. Kulelerin listesi şu anda boştur. Tower açılan kutusundaki aşağı oku tıklayın.438 Kısım IV Windows Uygulamaları ile Çalışmak n n n n towerNames label4 yearsExperience methods Not yearsExperience grup kutusuna ve methods liste kutusuna stil uygulamak. Formu kapatın ve Visual Studio 2008’e dönün. Debug menüsünde Start Without Debugging’i tıklayın. 3. Aynı şekilde. Sonraki alıştırmada liste kutusunu doldurmak için kod ekleyeceksiniz.

Code and Text Editor penceresi açılır ve Window1.Bölüm 22 Windows Presentation Foundation’a Giriş 439 Özellikleri Dinamik Olarak Değiştirmek Şimdiye kadar. özellikleri statik olarak değiştirmek için Design View penceresini. Window1 sınıfına.Empty. görüntülenen verinin listesini içeren Items adında bir özelliğe sahiptir. public void Reset() { firstName. Properties penceresini ve XAML bölmesini kullandınız. Design View penceresinde. Reset yöntemini form ilk çalıştığında ve kullanıcı Clear düğmesini tıkladığında çağıracaksınız. Bu örnek için. 2. } } Bu yöntemdeki iki ifade. Reset yöntemini yaratın 1. biraz kod yazmanız gerekir. Bunu yapmak için.. 3. uygulama kodlanmış bir koleksiyon kullanacaktır. böylece forma C# kodunu ekleyebilirsiniz. Window1 sınıfına.cs dosyası görüntülenir. towers adlı dize dizisini ekleyin: public partial class Window1 : Window { private string[] towers = { “Great Shevington”. “Upper Gumtree”. Bu bilgi genelde bir veritabanında tutulacaktır ve kulelerin listesini elde etmek için kod yazacaksınız ve ComboBox’ı dolduracaksınız.Empty. Reset adlı private bir yöntem yaratacaksınız.xaml. Form çalıştığında her denetimin değerini varsayılan başlangıç değerine sıfırlamak yararlı olur. “Little Mudford”.Text = String. metin kutularının boş olduğunu garantiler. firstName ve lastName metin kutularının Text özelliğine boş bir dize atayarak..Text = String. aşağıda koyu harfle gösterilen Reset yöntemini ekleyin: public partial class Window1 : Window { . form üzerindeki diğer denetimler için özellikleri başlatmanız ve towerNames açılan kutusunu ve methods liste kutusunu doldurmanız gerekir. kule adlarını listesini içeren. “Downley Hatch” }... Aşağıdaki alıştırmalarda. aşağıda koyu harfle gösterilen. Hatırlarsanız. Ayrıca. formu farenin sağ düğmesiyle tıklayın ve daha sonra View Code’u tıklayın. } . . Middleshire bölgesindeki tüm çan kulelerinin bir listesini içerecektir. Daha sonra. lastName. towerName açılan kutusu. Bir ComboBox.

çünkü aksi takdirde listede çok sayıda kopya değerler olabilir) ve towers dizisinde bulunan kuleleri ekleyin. Açılır kutu gibi. bir veritabanından doldurulabilirdi.Text = towerNames.Items.Items[0] as string..aşağıdaki gibi. foreach döngüsünden sonraki ifade.Clear(). foreach (string towerName in towers) { towerNames.440 Kısım IV Windows Uygulamaları ile Çalışmak 4. Ayrıca..Items. towerNames açılır kutuyu temizlemek için aşağıdaki ifadeleri yazın (bu ifadeleri yazmanız önemlidir. towerNames. Items adında bir özelliğe sahiptir.Items> </ComboBox> 5. tasarım sırasında kodlanacak değerleri belirleyebilirsiniz: <ComboBox Text=”towerNames”> <ComboBox. Reset yönteminde yazdığınız koddan sonra.Items> <ComboBoxItem> Great Shevington </ComboBoxItem> <ComboBoxItem> Little Mudford </ComboBoxItem> <ComboBoxItem> Upper Gumtree </ComboBoxItem> <ComboBoxItem> Downley Hatch </ComboBoxItem> </ComboBox. bir açılır kutunun XML tanımında. ilk kulenin varsayılan değer olarak gösterilmesine neden olur: public void Reset() { . liste kutusu da. methods liste kutusunu çan çalma yöntemlerinin bir listesiyle doldurmanız gerekir.Add(towerName). } towerNames. Ancak . ComboBox gibi. görüntülenen değerlerin koleksiyonunu içeren. } Not Ayrıca.

ringingMethods dizisindeki yöntemlerle doldurmak için Reset yöntemine aşağıda koyu harfle gösterilen kodu ekleyin. 0. yani görüntülemek için mantıklı bir tür olduğu sürece.. “Reverse Canterbury”. methods. isCaptain onay kutusu. CheckBox method. Aşağıda koyu harfle gösterilen.Clear().Add(method). WPF modelinin esnekliği ile... “Crayford Little Court” }. methods liste kutusu. method. } .IsChecked = false. } } Not Birçok WPF denetimi. “Kent Treble Bob”. “Grandsire”.Content = methodName. .. onay kutusu tarafından görüntülenen metni ve Margin özelliğini ayarlayarak da listedeki öğeler arasındaki boşluğu (bu kod her öğeden sonra 10 birim boşluk ekler) belirleyebilirsiniz: public void Reset() { .. sıradan metin dizelerinden çok onay kutularının listesini görüntülemelidir. Bu defa. } 6. Onay kutusunun Content özelliğini ayarlayarak.Items..Items. Bunun için. methods. yöntemlerin listesini içeren dize dizisini Window1 sınıfına ekleyin: public partial class Window1 : Window { . liste kutuları ve açılır kutular gibi denetimler için çeşitli farklı türlerde içerik belirleyebilirsiniz.Margin = new Thickness(0. 7. private string[] ringingMethods = { “Plain Bob”.Bölüm 22 Windows Presentation Foundation’a Giriş 441 daha önceki gibi. “Old Oxford Delight”. “Norwich Surprise”. methods liste kutusunu. IsChecked özelliğini ayarlamanız gerekir. isCaptain.. 0. Bu özellik tam olarak bir nesnedir. Reset yöntemine aşağıda koyu renkle gösterilen ifadeyi ekleyin: public void Reset() { . her öğenin bir onay kutusu olduğuna dikkat edin. false varsayılan değerinde olmalıdır.. o denetim tarafından görüntülenen değeri okumak ve ayarlamak için kullanabileceğiniz bir Content özelliğine sahiptir. method. “Stedman”. “Winchendon Place”. hemen hemen herhangi bir tür atayabilirsiniz. foreach (string methodName in ringingMethods) { method = new CheckBox(). 10). bu örnek için bazı kodlanmış değerler uygulayacaksınız.

DateTimePicker denetimine başlangıç değeri atamak için Reset yöntemine.. memberDate. kapsayıcının Child özelliğine başvurarak daha sonra uygun bir türe dönüştürdüğünüze dikkat edin. Seçenek düğmesi. fakat bir WPF uygulaması ile Windows Forms denetimlerini birleştirdiğinizde bunu yapmamalısınız. en çok. novice. bir sınıf tanımlayan dosyaya. bu nedenle using ifadesi eklemenin bu denetimlere olan başvuruların tümünü belirsiz yapacak olmasıdır! 10. Bunu yapmanın en iyi yeri. this. grupta sadece bir seçenek düğmesi seçilebilir (true olarak atanır) ve diğerlerinin tümü otomatik olarak temizlenir (false olarak atanır). Varsayılan ayar olarak. novice seçenek düğmesinin IsChecked özelliğini ayarlayarak bunu düzeltmelisiniz. WPF kütüphanesindeki denetimlerle aynı adı kullanan birçok denetim içermesi.DateTimePicker memberDate = hostMemberSince. Bunu. Bununla birlikte. true ya da false değer içermesi bakımından CheckBox’a benzer. form ilk görüntülendiğinde çağrılacak olan Reset yöntemini düzenlemeniz gerekir. } 9.. } Bir WindowsFormsHost kapsayıcısında bir nesneye erişmek için. Member Since DateTimePicker denetiminin varsayılan ayar olarak geçerli tarihe ayarlandığından emin olmalısınız.Value = DateTime. DateTime sınıfının statik Today yönteminden elde edebilirsiniz.Windows.Today. Tipik olarak.IsChecked = true..Windows. seçenek düğmelerini bir arada bir GroupBox içine yerleştirdiğinizde. Geçerli tarihi. düğmelerin hiçbiri seçilmeyecektir.. Aşağıda koyu renkle gösterilen ifadeyi Reset yöntemine ekleyin: public void Reset() { . seçenek düğmeleri birbirini dışlayan bir koleksiyon biçimlendirir. Window1 kurucusudur. Son olarak.Windows. } . System. Bunun nedeni.Forms. aşağıda koyu harfle gösterilen kodu ekleyin.Forms ad alanının. Ayrıca.Child as System.Forms.Windows. DateTimePicker sınıfının System. InitializeComponent yöntemini çağıran ifadeden sonra Reset yöntemine bir çağrı ekleyin: public Window1() { InitializeComponent().Reset(). denetimin Value özelliğini ayarlayarak yapabilirsiniz. güçleri artar. Form. üyelerin çan çalma deneyimlerini yıl sayısı olarak gösteren dört seçenek düğmesi içerir.442 Kısım IV Windows Uygulamaları ile Çalışmak 8.Forms ad alanında tanımlandığına dikkat edin. System. sınıfın ad alanını kapsam içine almak için bir using ifadesi ekleyin. public void Reset() { . Bu durumda.DateTimePicker.

Yılı tıklayarak. Düğmenin birşeyler yapmasını istiyorsanız. ayları açılır liste olarak görüntülemek için ay adını tıklayabilirsiniz. 15. Windows Forms’da Olayları İşlemek Bir program geliştirici olarak göreviniz. Ayrıca. Tower açılır kutusunu tıklayın. 16. Debug menüsünde Start Without Debugging’i tıklayarak projeyi oluşturun ve çalıştırın. kendi olaylarınızı nasıl yayınlayacağınızı ve onlara nasıl abone olacağınızı gördünüz. daha sonra bunlardan birini seçebilirsiniz. 13. Microsoft Foundation Classes (MFC) ya da Windows için GUI uygulamaları oluşturmakta kullanılan diğer herhangi bir araçla ilgilendiyseniz Windows’un kodu ne zaman çalıştıracağını belirlemek için olay yönlendirmeli (event-driven) model kullandığının farkındasınızdır. Member Since tarih/zaman seçicisinin sağ tarafındaki aşağı okunu tıklayın. Experience grup kutusundaki her seçenek düğmesini tıklayın. Aynı anda birden fazla seçenek düğmesi seçebileceğinize dikkat edin. Çan kulelerinin listesini göreceksiniz. uygun onay kutusunu seçmek için yöntemlerden bazılarını tıklayın. Form açıldığında. Bu bölümdeki alıştırmaların sonuncusunda bu işlevselliği ekleyeceksiniz. Bölüm 17’de. bu bölümün son alıştırmasında yapacağınız şeydir. 12. sayısal yukarı aşağı denetimi kullanarak yılı seçebilirsiniz. Bir WPF Formda Olayları İşlemek Microsoft Visual Basic. 17. Bu düğmeler şu an hiçbir şey yapmaz. . ayı seçmek için okları kullanabilirsiniz. Formu kapatın ve Visual Studio 2008’e dönün. uygun onay kutusu temizlenecektir. uygulamanızla ilgili olduğunu hissettiğiniz olayları yakalamak ve bu olaylara tepki gösteren kodlar yazmaktır. Bir tarihi tıklayarak. Bir yöntemi ikinci defa tıklarsanız. WPF formları ve denetimleri abone olabileceğiniz kendi önceden tanımlı olaylarını içerirler ve bu olaylar birçok kullanıcı arabiriminin gereksinimlerini işlemek için yeterli olmalıdır. bu olaya tepki veren kodu yazmalısınız. Sık rastlanan bir örnek. Add ve Clear düğmelerini tıklayın. Methods liste kutusunda.Bölüm 22 Windows Presentation Foundation’a Giriş 443 11. Varsayılan değer geçerli tarih olacaktır. Bu. 14. Bir takvim göreceksiniz. bir kullanıcı fare ile tıkladığında ya da düğme etkinken Enter tuşuna bastığında “Somebody clicked me” (Birileri düğmeye bastı) olayını başlatan Button denetimidir.

. bir kule kaptanının bir yıldan az deneyimi olabilir mi?) emin olmak için geçerliliğini denetlemelidir ve veri geçerli ise. 3. İki düğme ortak bir eylem gerçekleştirirse. WPF denetimleri çeşitli olaylara yol açabilir. bir veritabanına ya da diğer kalıcı saklama ortamına göndermek için veriyi düzenlemelidir. Click=”>Add</Button> Click= teriminden sonra. Tümüyle yeni bir olay işleme yöntemi üretmek isterseniz. Add düğmesinin Click olayı için kod.) 2. denetimin varsayılan olayı için olay yönteminin kökünü üretir.444 Kısım IV Windows Uygulamaları ile Çalışmak Clear düğmesinin Click olayını işleyin 1. TextChanged olayını işlemek için olay yönteminin kökünü üretir. üyenin tüm verilerini doldurduktan sonra bilgiyi kaydetmek için Add düğmesini tıklayacak. veri girişini yansıtan bir ileti kutusu görüntüler. Design View penceresinde Window1. <New Event Handler> komutunu seçebilirsiniz. WPF çalışma zamanı. RoutedEventArgs e) { this. XAML bölmesinde. } Kullanıcılar.. Aşağıda koyu harflerle gösterildiği gibi. bu parametreleri olayın kaynağı hakkında bilgi ve olayı işlerken yararlı olabilecek ek bilgilerle birlikte dolduracaktır. Add düğmesi için Click olayı. <New Event Handler> ve clear_ Click öğelerini gösteren bir kısayol menüsünün belirdiğine dikkat edin. Form üzerindeki Clear düğmesini çift tıklayın.xaml dosyasını görüntüleyin. Olay yönteminin iki parametre aldığına dikkat edin: sender parametresi (bir object) ve ayrıca bir bağımsız değişken parametresi (bir RoutedEventArgs nesnesi). Window1.xaml formunu görüntüleyen Design View penceresine dönün. Şimdilik. Kullanıcı Clear düğmesini tıkladığında. kullanıcı Clear düğmesini tıkladığında çağrılacak olan bir olay yöntemidir. Add düğmesini tanımlayan öğeyi bulun ve aşağıda koyu harflerle gösterilen kodu yazmaya başlayın: <Button . bir düğme için varsayılan olay. tırnak işaretini yazdığınızda. clear_Click yönteminin gövdesinde Reset yöntemini çağırın: private void clear_Click(object sender. Design View penceresinde bir formu ya da bir denetimi çift tıkladığınızda. Bu. Code and Text Editor penceresi belirir ve clear_Click adında bir yöntem yaratır. (Bir metin kutusu denetimini çift tıklarsanız. Click olayıdır.Reset(). . Bu alıştırmada bu parametreleri kullanmayacaksınız. Verinin geçerliliğinin denetlenmesi ve saklanması ile ilgili daha fazlasını sonraki bölümlerde öğreneceksiniz. Visual Studio. iki düğme arasında aynı olay işleyicisini (örneğin clear_Click) paylaşabilirsiniz. Visual Studio. formun varsayılan değerlerine sıfırlanmasını istersiniz. girilen verinin anlamlı olduğundan (örneğin.

Click olayından başka bir olay işlemek için. Window1 sınıfına add_Click yönteminin eklendiğine dikkat edin. XAML kodunda düğme için add_Click metni belirir. towerNames. daha sonra yöntemi pencere sınıfına eklemeniz gerekir. aksi takdirde.AppendLine(cb.Text).Content.Value) { details.cs dosyasından add_Click gibi bir olay yöntemini kaldırmaya karar verirseniz.xaml. Visual Studio 2008 belgelerine bakın.Text. IntelliSense listesi denetim için özellikler ve olayları görüntüler. details.xaml. 6.AppendLine(nameAndTower). Kısayol menüsünden <New Event Handler> komutunu tıklamak yerine. lastName. Bu yöntem doğru imzaya sahip olmak zorundadır. 5. Bir denetim için XAML kodu düzenlediğinizde. firstName. RoutedEventArgs e) { string nameAndTower = String. Not Bir düğme için Click olayını işlemekle sınırlı değilsiniz.Text. uygulamanız derlenmez.cs dosyasını görüntüleyen Code and Text Editor penceresine geçin. StringBuilder details = new StringBuilder().ToString().ToString()).Items) { if (cb. add_Click yöntemine aşağıdaki kodu ekleyin: private void add_Click(object sender. “Member Information”). İpucu Olay işleyici yöntemleri için Visual Studio 2008 tarafından üretilen varsayılan adları kullanmak zorunda değilsiniz.IsChecked.Bölüm 22 Windows Presentation Foundation’a Giriş 445 4. } . Window1.Show(details. Kısayol menüsünde <New Event Handler> komutunu çift tıklayın. Ancak. Her denetim tarafından desteklenen olayların tam listesi için. Window1. yöntemin adını yazabilirsiniz. uygun denetimin XAML tanımını düzenlemeniz ve olayın Click=”add_Click” başvurusunu kaldırmanız gerekir.Format( “Member name: {0} {1} from the tower at {2} rings the following methods:”. } } MessageBox. foreach (CheckBox cb in methods. bir void döndürmeli ve bir object parametresi ve RoutedEventArgs parametresi olmak üzere iki bağımsız değişken almalıdır Önemli Daha sonra. olayın adını yazın ve daha sonra bu olayı işlemek için istediğiniz yöntemin adını yazarak yöntemi seçin.

Ayrıca. çalışma zamanı gerçekte değiştirilmiş değeri içeren yeni bir dize yaratır ve daha sonra eski dizeyi terk eder. . Bir dizeyi tekrar tekrar değiştirmek. Son olarak.Format yöntemi. Kod daha sonra details adında bir StringBuilder nesnesi yaratır. . Not StringBuilder nesnesi yerine sıradan dize birleştirme kullanabilirdiniz. nameAndTower adında bir string değişkeni yaratır. 8. Clear düğmesini tıklayın ve formdaki denetimlerin varsayılan değerlere sıfırlandığını doğrulayın. Başlık araç çubuğunda “Member Information” yazacaktır. üyenin adını ve bağlı olduğu kulenin adını saklayan. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Yöntem. System. Burada kullanılan Show yöntemi. ekranda iletişim kutularını görüntülemek için statik yöntemler sağlar. nameAndTower dizesindeki metin. bir kule ve birkaç yöntem seçin. fakat StringBuilder sınıfı çok daha etkilidir ve bu kodda gerekli türde görevleri gerçekleştirmek için önerilen bir yaklaşımdır.Format yöntemini kullanır. dize her değişiklikte bellekte oluşturulmak zorunda olduğundan kodunuzun verimsiz olmasına neden olabilir (eski dizelerde sonuçta çöp toplama gerçekleşecektir). ileti kutusunun gövdesindeki details dizesinin içeriğini görüntüler. Kodun. bu liste kutusu. Append. başlangıç olarak details nesnesini yerleştirmek için kullanılır. 10. String. 7. biçimlendirilmiş dizeyi ekranda görüntülemek yerine sonuç olarak döndürmesi dışında. Her seferinde yeni bir nesne yaratmak zorunda kalmadan. Add düğmesini tıklayın ve yeni üyenin bilgilerini ve yeni üyenin çalabildiği yöntemleri gösteren Member Information ileti kutusunun belirdiğini doğrulayın.WriteLine yöntemi ile aynı şekilde çalışır. 9. Console. MessageBox sınıfı. görüntüleyeceği bilginin dize gösterimini oluşturmak için bu StringBuilder nesnesini kullanır.446 Kısım IV Windows Uygulamaları ile Çalışmak Bu kod bloğu. Kod daha sonra. Show. Formu kapatın ve Visual Studio 2008’e dönün. Hatırlarsanız. değeri bir dize içinde değiştirdiğinizde. kod sonuçları sıfırlamak için statik String. Üyenin ilk adı ve soyadını yazın. Her onay kutusu incelenir ve kullanıcı tarafından seçilmişse. methods liste kutusundaki Items koleksiyonu üzerinden yinelenir. Insert ve Remove yöntemlerini kullanarak StringBuilder nesnesine karakterler ekleyebilir ve çıkarabilirsiniz. onay kutusunun Content özelliğindeki metin details StringBuilder nesnesine eklenir.Text ad alanındaki StringBuilder sınıfı bu verimsizliği önlemek için tasarlanmıştır. onay kutusu denetimlerini içerir.NET Framework’de ve C#’da string veri türü sabittir. metin kutusunun Text özelliğine ve açılır kutu denetimine erişerek bu denetimlerin geçerli değerlerini nasıl okuduğuna dikkat edin. bir aşırı yüklenmiş yöntemdir ve ileti kutusunda göstermek için belirleyebileceğiniz çeşitli simgeler ve düğmeler içerir.

Window1 penceresinin XAML tanımına aşağıdaki kodu yazmaya başlayın: <Window x:Class=”BellRingers.. olay işleyici bittiğinde form kapanır. Cancel adında bir Boolean özelliğine sahiptir. memberFormClosing yöntemine aşağıda koyu harflerle gösterilen ifadeleri ekleyin: private void Window_Closing(object sender. Kullanıcıyı kaydedilmemiş veriyi kaydetmesi için uyarmak ya da formu gerçekten kapatmak isteyip istemediğini sormak için bu olayı kullanabilirsiniz. Closing=”> 2.. Closing olayı..xaml.Cancel = (key == MessageBoxResult.. System.Question. e. <New Event Handler> komutunu çift tıklayın. MessageBoxImage. “Confirm”. Visual Studio. CancelEventArgs sınıfı.YesNo. Tırnak işaretini yazdıktan sonra kısayol menüsü göründüğünde. MessageBoxButton. Window1 sınıfına.No).Bölüm 22 Windows Presentation Foundation’a Giriş 447 Bu bölümdeki son alıştırmada.Window1” . XAML bölmesinde. Olay işleyicideki Cancel’i true olarak ayarlarsanız. Design View penceresinde... Title=”..ComponentModel. 4. Window_Closing olay yönteminin kökü eklenir: private void Window_Closing(object sender.” . MessageBoxResult.. pencereyi kapatan Closing olayını işlemek için bir olay işleyici ekleyeceksiniz. Form için Closing olayını işleyin 1.. System.. Window1. böylece kullanıcılar uygulamayı gerçekten sonlandırmak istediklerini onaylayabilir.ComponentModel. Title=”.” . Closing=”Window_Closing”> 3. } . Window_Closing adında bir olay yöntemi üretir ve aşağıdaki gibi formun Closing olayı ile ilişkilendirir: <Window x:Class=”BellRingers. fakat form gerçekte kapanmadan önce ortaya çıkar.Window1” .No).. kullanıcı formu kapatma girişiminde bulunduğunda..CancelEventArgs e) { MessageBoxResult key = MessageBox.cs dosyasını görüntüleyen Code and Text Editor penceresine geçin.Show( “Are you sure you want to quit”.CancelEventArgs e) { } Bu yöntemin ikinci parametresinin CancelEventArgs türüne sahip olduğuna dikkat edin.

Beliren ileti kutusunda No’yu tıklayın. Yes ve No düğmeleri ve bir soru işareti simgesi içerir. İleti kutusu. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin.No. Kullanıcı No’yu tıklarsa. Uygulamayı çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. 5. ikinci ifade. kullanıcı Enter tuşuna basarsa varsayılan düğmeyi gösterir (kullanıcı yeni yazdığı verileri kazara kaybetmektense formu kapatmamayı ister). n . formun kapanmasını engelleyen.448 Kısım IV Windows Uygulamaları ile Çalışmak Bu ifadeler. Formu kapatmayı tekrar deneyin. WPF. ileti kutusu kapanacak ve tıklanan düğme yöntemin değeri olarak dönecektir (MessageBoxResult olarak-hangi düğmenin tıklandığını tanımlayan numaralandırma). İşlevsel kullanıcı arabirimi oluşturmak için gerekli WPF özelliklerinin kullanımını gördünüz. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 23’e geçin. Save iletişim kutusu görünürse. Form çalışmaya devam etmelidir. ileti kutusunda Yes’i tıklayın. Bu defa. burada gördüğümüz özelliklerden daha fazlasını. özellikle iki boyutlu ve üç boyutlu grafikler ve animasyon ile ilgili çok daha fazla özellik içerir. 7. Son parametre olan MessageBoxResult. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Kullanıcı her iki düğmeyi de tıkladığında. CancelEventArgs parametresinin (e) Cancel özelliğini true olarak atayacaktır. kullanıcıya uygulamayı kapatmak isteyip istemediğini soran bir ileti kutusu gösterir. Form kapanır ve uygulama sonlanır. 6. Formu kapatmaya çalışın.

Örneğin: novice. <Window> öğesinde ya da denetimi tanımlayan öğede özelliği ve değeri belirleyin Aşağıdakilerden birini yapın: n View menüsünde.Add(“Upper Gumtree”). Bölmeye seçenek düğmeleri ekleyin. Items özelliğinin Add yöntemini kullanın. Code’u tıklayın. . Aynı bölmedeki tüm seçenek düğmeleri birbirini dışlayandır.xaml.Items. ilk önce Items özelliğini temizlemeniz gerekebilir. Formun arkasındaki koda göz gezdirmek Birbirini dışlayan seçenek düğmeleri tanımlamak C# kodu kullanarak bir açılır kutu ya da liste kutusu doldurmak Forma StackPanel gibi bir bölme ekleyin.Clear(). Solution Explorer’da. Listenin mevcut içeriğini saklı tutmak isteyip istemediğinize bağlı olarak. formun .cs dosyasını çift tıklayın.xaml dosyasının klasörünü genişletin ve görünen . n n Design View penceresini farenin sağ düğmesiyle tıklayın ve sonra da View Code’u tıklayın. olayı belirleyen kodu ekleyin ve daha sonra ya mevcut yöntemden uygun imzaya sahip olanı seçin ya da ortaya çıkan kısayol menüsünde <Add New Event> komutunu tıklayarak yaratılan olay yönteminde olayı işleyen kodu yazın.Items. n XAML bölmesinde. Design View penceresinde formu ya da denetimi tıklayın. Bir onay kutusu ya da seçenek düğmesi denetimini başlatmak Bir denetim ya da form için bir olayı işlemek IsChecked özelliğini true ya da false olarak atayın. Örneğin: towerNames.Bölüm 22 Windows Presentation Foundation’a Giriş 449 Bölüm 22 Hızlı Başvuru Bunun İçin Bir WPF uygulaması yaratmak Forma denetimler eklemek Bir formun ya da denetimin özelliklerini değiştirmek Şunu Yapın WPF Uygulama şablonu kullanın. Daha sonra aşağıdakilerden birini yapın: n Properties penceresinde. Örneğin: towerNames. değiştirmek istediğiniz özelliği seçin ve yeni değeri girin. XAML bölmesinde.IsChecked = true. Denetimi Toolbox’dan forma sürükleyin.

.

Kullanıcı bir menü komutunu tıkladığında işlemleri gerçekleştirmek için menü olaylarına tepki vermek. var olan bir belgeyi açmak. Menu ve MenuItem sınıflarını kullanarak menüler yaratmak ve düzenlemek. Bu bölümde. belgeyi kaydetmek.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n Microsoft Windows Presentation Foundation (WPF) uygulamaları için. Kullanıcıların dosya adı girmesi için uygulamanızda Windows ortak iletişim kutularını kullanmak. Bölüm 22’de yarattığınız Bell Ringers uygulamasında ise yeni bir üye olabilir. Etkin konuma göre içerikleri değişen açılan menüler yaratmayı öğreneceksiniz. dosya ve yazıcılar gibi sık kullanılan öğeler için kullanıcının hızlı. Son olarak. File menüsü tipik olarak menü çubuğunun ilk öğesidir ve bu menüde genellikle bir belge yaratmak. belgeyi yazdırmak ve uygulamadan çıkmak için komutlar bulunur. Windows Forms kitaplığının bir parçası olarak sağlanan ortak iletişim sınıflarını öğreneceksiniz. ContextMenu sınıfını kullanarak içerik duyarlı açılan pencere menüler yaratmak. Kullanıcı menüdeki bir komutu tıkladığında nasıl tepki verileceğini göreceksiniz. Menüleri kod üzerinden değiştirmek ve dinamik menüler yaratmak. kolay ve tanıdık bir yolla bilgi girmesini sağlamanıza olanak verir. Örneğin. 451 . Not document (Belge) terimi uygulamanın kullandığı veri anlamındadır. Menü Temel İlkeleri ve Stil Birçok Windows uygulamasına bakarsanız. menü çubuğunda bazı bileşenlerin aynı yerde birçok kez yinelendiğini ve bu öğelerin içeriklerinin önceden kestirilebilir olduğunu fark edersiniz. menülerin nasıl yaratıldıklarını ve menüleri Menu denetimini kullanarak formlara nasıl ekleyeceğinizi öğreneceksiniz. Bu iletişim sınıfları. Birçok profesyonel Microsoft Windows uygulaması ayrıca komutlar ve seçenekler içeren ve kullanıcıya uygulamayla ilgili birçok değişik görevi yerine getirme olanağı veren menüler sunar. n n n n Bölüm 22’de denetimleri ve olayları seçilebilir yapan bir WPF uygulamasının nasıl yaratılacağını gördünüz. Microsoft Office Excel’de belge bir elektronik tablodur.

hem de uygulamanın telif hakları ile lisanslama ayrıntılarını içeren “hakkında” bilgisine erişimi sağlayan Help menüsü olmasıdır. öğeler içerir. Belgeler klasörünüzde bulunan \Microsoft Press\Visual CSharp Step by Step\Chapter 23\BellRingers klasöründe yer alan BellRingers çözümünü açın. açılır kutular vb. Design View penceresindeki XAML bölmesini kullanarak tanımlayabilirsiniz ve ayrıca Microsoft Visual C# kodu kullanarak çalışma zamanında da menüleri düzenleyebilirsiniz. Exit komutu neredeyse şaşmaz biçimde File menüsünün son komutudur. 2.com/en-us/library/Aa286531. File menüsünde uygulamaya özel komutlar da olabilir. İyi tasarlanmış bir uygulamada çoğu menüler tahmin edilebilir olup uygulamanın öğrenilmesini ve kullanılmasını kolaylaştırmaya yardımcı olur. Bir komutu gerçekleştirmek için tıklayabileceğiniz metin öğeleri içeren menülere aşina olabilirsiniz. komutlar içeren bir Edit menüsüne de sahiptir. Menüleri. düğmeler. Menülerin kod ile nasıl değiştirileceğini ve yaratılacağını bu bölümün ilerleyen kısımlarında ele alacağız. Menu denetimi de oldukça esnektir. bir menü tanımlamak için basit bir kabuk sağlar. Bu. . Paste. Clear. bir şeyler meydana gelmesini bekler! Uygulamanız menü olaylarını yakalayarak ve denetim olaylarını işlemeye oldukça benzer şekilde kodu çalıştırarak komutlar üzerinde rol oynar. Birçok WPF yaklaşımında olduğu gibi.452 Kısım IV Windows Uygulamaları ile Çalışmak Bu komutların oluşum sırası uygulamalar arasında benzerlik gösterir. WPF menüleri ayrıca. menü öğeleri için bir taşıyıcı olarak Menu denetimini sağlar. Bir menü düzenlemek hikayenin sadece yarısıdır.microsoft. böylece hemen hemen her tür WPF denetimi içeren bir menü yapısı tanımlayabilirsiniz. metin kutuları.aspx adresinde sunmaktadır. İpucu Microsoft. Bir uygulama genelde Cut. Bölüm 22’de oluşturduğunuz uygulamanın kopyasıdır. Bir Menü Yaratmak Aşağıdaki alıştırmada Middleshire Bell Ringers Association uygulaması için menüler yaratmak için XAML bölmesini kullanacaksınız. örneğin. Kullanıcı bir menüdeki komutu tıkladığında. Menüler ve Menü Olayları WPF. Menu denetimi. Uygulama menüsü yaratın 1. Sıklıkla menü çubuğunda uygulamaya özgü menüler de olur ama burada da genellikle son menünün hem yardıma. Microsoft Visual Studio 2008’i başlatın. Find vb. sezgisel kullanıcı arabirimleri için menü tasarımı dahil menü temel ilkelerinin tümünü Microsoft Web sitesi olan http://msdn2.

0.) DockPanel denetimi. Not Bu bölüm boyunca. Not Margin özelliğine 0 atamakla. 5. Properties penceresinde. . Tower ve Captain kullanıcı arabirim öğelerini kapsayacaktır. HorizontalAlignment özelliğini Stretch olarak ve VerticalAlignment özelliğini de Top olarak atayın. şu şekilde görünmelidir: <DockPanel Height=”100” HorizontalAlignment=”Stretch” Margin=”0” Name=”dockPanel1” VerticalAlignment=”Top” Width=”Auto”> <Menu Height=”22” Name=”menu1” Width=”Auto” DockPanel. Design View penceresinde Window1. Last Name. 0. fakat menüyü DockPanel üzerine yerleştirmek çok daha iyi bir uygulamadır çünkü daha sonra menüyü ve menünün form üzerindeki yerleşimini kolayca düzenleyebilirsiniz. DockPanel ve Menu denetimlerinin kodunu inceleyin.xaml’i görüntüleyin. (First Name. DockPanel.) 4.Dock özelliğini Top olarak. yerleştirdiğiniz diğer denetimlerin düzenlemesini denetlemek için kullanabileceğiniz bir bölme denetimidir. 0. tasarım anında ya da çalışma zamanında kodu çalıştırarak bölmeyi hareket ettirmek suretiyle tüm menüyü form üzerinde başka bir yere yerleştirebilirsiniz. Toolbox’dan.xaml’i çift tıklayın. Properties penceresinde. Menu denetimi. Forma doğrudan bir menü ekleyebilirsiniz. Örneğin. Controls bölümünden bir Menu denetimini DockPanel denetimine sürükleyin. DockPanel’in üst kısmında boydan boya gri bir çubuk olarak görünür. DockPanel denetimi. 0 atamak aynı şeydir. VerticalAlignment özelliğini Top olarak ve Margin özelliğini de 0 olarak ayarlayın. formun üst kısmında ve tam form genişliğinde yer almalıdır. Width özelliğini Auto olarak. XAML kodunda ortaya çıkmaz çünkü “Stretch” değeri bu özellik için varsayılan değerdir.Dock=”Top” VerticalAlignment=”Top”> </DockPanel> HorizontalAlignment özelliği. Toolbox’daki. HorizontalAlignment özelliğini Stretch olarak.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 453 3. (Solution Explorer’da Window1. menüyü alt tarafta ya da bir kenarda yerleştirirseniz. Bölüm 22’de gördüğünüz Grid ve StackPanel denetimleri gibi. XAML bölmesinde. DockPanel’in Width özelliğini Auto olarak. XAML bölmesinden satırlar ayrı olarak gösterilmiştir ve basılan sayfaya yerleşecek şekilde tasarlanmıştır. Controls kısmından bir DockPanel denetimini formda herhangi bir yere sürükleyin.

Not Menu denetiminin Properties penceresi. menüye odaklanılmalıdır ve “File” menüsünde “F” harfi ve “Help” menüsünde “H” harfinin altı çizili olmalıdır: Menü öğelerinden birini tıklarsanız. Aynı erişim tuşunu karışıklığa neden olacağından birden fazla menü için kullanmayın. Bu özelliği ve sonra bu özellikte görünen üç nokta düğmesini tıklarsanız. Alt tuşuna basın. Help menüsü için Alt+H) bastığında. . MenuItem öğelerinin Menu denetiminin alt özelliği olarak göründüğüne dikkat edin. bu nedenle Menu öğesinin (/>) etiket sınırlayıcısını. Collection Editor görünür. menüdeki öğelerin sırasını değiştirmek ve bu öğelerin özelliklerini ayarlamak için bu pencereyi kullanmanıza imkan sağlar fakat menüye yeni öğeler eklemenize izin vermez. Form görününce. 8. bu bölümde menülerinizin yapısını tanımlamak için XAML bölmesini kullanacaksınız. kullanıcı Alt tuşuna ve F tuşuna bastığında. File menüsü görünür. Yazma zamanında. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. 7. menü öğesi için gösterilen metni belirler. başlık çubuğunun altındaki pencerenin üst kısmında menüyü görmelisiniz. File menüsü için Alt+F. Formu kapatın ve Visual Studio 2008’e dönün. Kullanıcı Alt tuşuna ve menünün alt çizgi (_) ile gösterilen harfine (Burada.Dock=”Top” VerticalAlignment=”Top” HorizontalAlignment=”Stretch” > <MenuItem Header=”_File” /> <MenuItem Header=”_Help” /> </Menu> MenuItem öğesinin Header özniteliği. Bu bir diğer yaygın kuraldır. Items adında bir özellik görüntüler. O nedenle. bu öğelerin içereceği alt menüleri tanımlamadığınızdan şu an hiçbirşey meydana gelmez. Çalışma zamanında. o menü öğesine hızlı erişim sağlar. Visual Studio 2008’in geçerli sürümü (Beta 2) menüden öğeleri kaldırmak. XAML bölmesinde.454 Kısım IV Windows Uygulamaları ile Çalışmak 6. <Menu Height=”22” Name=”menu1” Width=”Auto” DockPanel. Menu denetiminin tanımına aşağıdaki kodda koyu harfle gösterilen MenuItem öğelerini ekleyin. alışılmış etiket sınırlayıcı (>) ile değiştirin ve sonuna ayrı bir </Menu> öğesi yerleştirin.

Add Existing Item – BellRingers iletişim kutusunda. Menü göründüğünde ve ilişkili menü öğelerini gruplandırmak için kullanıldığında. Visual Studio 2008’de dahil. Save Member Details ve Exit komutlarını ekler. ekstra sanal ipucu sağlamak için menülerde simgeleri kullanılır yapar. 12. </MenuItem> öğesi ile birlikte alt menü ekleyin: <MenuItem Header=”_File” > <MenuItem Header=”_New Member” Name=”newMember” /> <MenuItem Header=”_Save Member Details” Name=”saveMember” /> <Separator/> <MenuItem Header=”E_xit” Name=”exit” /> </MenuItem> Bu XAML kodu. BellRingers projesini farenin sağ düğmesiyle tıklayın. File menüsüne New Member.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 455 9.bmp” “Note. üç resim dosyasını kaynak dosya olarak uygulamanıza ekler. _File menü öğesinin tanımına. Birçok uygulama. XAML bölmesinde. <Separator/> öğesi çubuk olarak belirir. _Help menü öğesine aşağıda gösterilen alt menü öğesini ekleyin: <MenuItem Header=”_Help” > <MenuItem Header=”_About Middleshire Bell Ringers” Name=”about” /> </MenuItem> 11. . Form ortaya çıktığında File menüsünü tıklayın. Belgeler klasörünüz altında yer alan Microsoft Press\Visual CSharp Step By Step\Chapter 23 klasörüne geçin. Ayrıca. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. File name kutusuna “Ring. aşağıda koyu harfle gösterildiği gibi. bmp” (tırnak işaretleri ile birlikte) yazın ve daha sonra Add’i tıklayın. 10. Formu kapatın ve Visual Studio 2008’e dönün.bmp” “Face. Bu eylem. Add’i işaret edin ve daha sonra Existing Item’ı tıklayın. Aşağıdaki gibi alt menü öğelerini görmelisiniz: About Middleshire Bell Ringers alt menü öğesini görüntülemek için Help menüsünü de tıklayabilirsiniz. Solution Explorer’da. 13. menü öğelerine simgeler ekleyebilirsiniz.

üst seviye menü öğesinin stilini otomatik olarak miras aldığına dikkat edin.bmp”/> </MenuItem. üst seviye menu1 öğesinin tanımını düzenleyin ve Style özelliğini aşağıda gösterildiği gibi BellRingersFontStyle stil olarak ayarlayın: <Menu Style=”{StaticResource bellRingersFontStyle}” ..Icon> </MenuItem> <Separator/> <MenuItem Header=”E_xit” Name=”exit”/> </MenuItem> <MenuItem Header=”_Help”> <MenuItem Header=”_About Middleshire Bell Ringers” Name=”about” > <MenuItem.Icon> <Image Source=”note.Icon> </MenuItem> <MenuItem Header=”_Save Member Details” Name=”saveMember” > <MenuItem.Icon> </MenuItem> </MenuItem> </Menu> 15. Debug menüsünde Start Without Debugging’i tıklayarak uygulamayı oluşturun ve çalıştırın.. 16. > <MenuItem Header=”_File” > <MenuItem Header=”_New Member” Name=”newMember” > <MenuItem.bmp”/> </MenuItem. .bmp”/> </MenuItem. saveMember ve about menü öğelerini düzenleyin ve önceki adımda projeye eklediğiniz simge dosyalarının her birine başvuran MenuItem. Son düzenleme. > Alt menü öğelerinin. newMember. XAML bölmesinde. Şimdi menü öğelerinin metnini. Formu kapatın ve Visual Studio 2008’e dönün... Name=”menu1” .. Form göründüğünde.456 Kısım IV Windows Uygulamaları ile Çalışmak 14. Icon alt öğelerini ekleyin: <Menu Height=”22” Name=”menu1” .Icon> <Image Source=”ring. alt menü öğelerindeki simgelerdeki yazı tipinde görmelisiniz: 17. menü öğelerinin metninin formun geri kalanı ile tutarlı olacak şekilde biçimlendirildiğinden emin olmaktır. File menüsünü tıklayın.Icon> <Image Source=”face.. XAML bölmesinde.

. MenuItem öğesini kullanmakla sınırlı değilsiniz.Items> </ComboBox> </MenuItem> </Menu> Çalışma zamanında menü yapısı şu şekilde görünür: Menülerinizi tasarlarken oldukça özgür olsanız da. Teorik olarak. tasarımınızı basit tutmalı ve çok fazla gösterişli yapmamalısınız. Basamaklanmış menüler yaratmak istiyorsanız. aşağıdaki menü yapısı düğme ve açılır kutu içerir: <Menu . Ayrıca. Böyle bir menü çok sezgisel değildir! .Items> <ComboBoxItem> Great Shevington </ComboBoxItem> <ComboBoxItem> Little Mudford </ComboBoxItem> <ComboBoxItem> Upper Gumtree </ComboBoxItem> <ComboBoxItem> Downley Hatch </ComboBoxItem> </ComboBox.> <MenuItem Header=”Miscellaneous”> <Button>Add new member</Button> <ComboBox Text=”Towers”> <ComboBox. yuvalanmış MenuItem öğeleri kendi içinde daha fazla yuvalanmış MenuItem öğelerine sahip olabilir.. Bununla birlikte.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 457 Menü Öğelerinin Türleri Menu denetimine alt menü öğeleri eklemek için MenuItem öğesini kullandınız. Örneğin. metin kutuları ve diğer denetim türlerinin birçoğunu ekleyebilirsiniz. WPF menülerine açılır kutular. bu işlemi oldukça dip seviyelere kadar sürdürebilirsiniz fakat pratikte iki seviyeden fazlasına gitmemelisiniz. Üst seviye menüdeki öğeleri MenuItem öğeleri olarak belirleyebileceğinizi ve daha sonra menü yapınızı tanımlamak için yuvalanmış MenuItem öğeleri ekleyebileceğinizi gördünüz.

MenuItem_Click_2 ve bu şekilde devam eder. Daha sonra diğer menü öğeleri için Click olay yöntemleri yaratırsanız. o yöntemler de MenuItem_Click_1. hangi olay yönteminin hangi menü öğesine ait olduğunu bulmak zor olabilir. değişik menü olaylarını işleyen kod yazmanız gerekir. XAML tanımında IsEnabled özelliğini False olarak ayarlar. Aşağıdaki alıştırmada. isCaptain. . kullanıcı menü öğesini tıkladığında meyda gelen Click olayıdır. Bazıları diğerlerine göre daha kullanışlıdır. firstName metin kutusunun tanımını tıklayın. kullanıcı New Member’ı tıklayana kadar. Visual Studio Click olayı için MenuItem_Click adında olay yöntemi üretir. Kullanıcı New Member komutunu tıkladığında. Bu olay yöntemlerinden birkaç tane varsa. add ve clear denetimleri ve saveMember menü öğesi için de tekrarlayın. XAML bölmesinde. Tırnak işaretini yazdıktan sonra ortaya çıkan kısayol menüsünde <New Event Handler> komutunu çift tıklayın. Menü öğesi ile ilişkili görevleri gerçekleştirmek için genellikle bu olayı yakalarsınız. Design View penceresindeki XAML bölmesinde. tüm alanları etkinleştirmek. Kullanıcı bir menü öğesini seçtiğinde birkaç farklı olay meydana gelebilir. hostMemberSince. 2. New Member komutunun amacı. yearsExperience. newMember ve exit menü olayları için Click olayları yaratacaksınız. Member menü öğesinin XAML tanımına aşağıdaki kodu yazmaya başlayın: <MenuItem Header=”_New Member” Click=”> 3. kullanıcının yeni bir üyenin ayrıntılarını girebilmesidir. kullanıcının yeni üye ile ilgili bilgi ekleyebilmesi için formun içeriğini sıfırlamak ve Save Member Details komutunu etkinleştirmek istersiniz. İpucu Bir menü öğesi için olay yöntemi tanımladığınızda her zaman anlamlı bir ad verin. Öğeleri işlevsel yapmak için. Properties penceresinde IsEnabled özelliğini temizleyin. methods. (Bu eylem. Siz bir ad vermezseniz. New Member ve Exit menü öğesi olaylarını işleyin 1. Bu nedenle. menü olayları ve bunları nasıl işleyeceğinize dair daha fazla bilgi elde edeceksiniz. towerNames.458 Kısım IV Windows Uygulamaları ile Çalışmak Menü Olaylarını İşlemek Şimdiye kadar oluşturduğunuz menü oldukça sevimli görünüyor fakat hiçbir öğe üzerini tıkladığınızda birşey yapmıyor. Save Member Details komutu ve form üzerindeki tüm alanlar devre dışı olmalıdır. En sık kullanılan olay.) Bu işlemi lastName. Visual Studio newMember_Click adında bir olay yöntemi üretir ve menü öğesinin Click olayı ile ilişkilendirir.

Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 459 4. 6. (View menüsünde Code’u tıklayın. isCaptain. towerNames.) Window1 sınıf tanımının alt kısmına newMember_Click olay yöntemi eklenir: private void newMember_Click(object sender. Kullanıcı hayır derse.IsEnabled = true.IsEnabled = true. exit menü öğesine exit_Click adında bir Click olayı yaratmak için 2. clear.IsEnabled = true. lastName. yearsExperience.IsEnabled = true. memberFormClosing yöntemine aşağıdaki ifadeleri ekleyin: private void newMember_Click(object sender. Bu yöntem formu kapatmalıdır. formun kapanmayacağını hatırlayın. RoutedEventArgs e) { } 5. saveMember. adımdaki tekniği izleyin. } Bu kod Reset yöntemini çağırır ve daha sonra tüm denetimleri etkin hale getirir. methods. Window1.IsEnabled = true.) Daha sonra. form kapanmaz ve uygulama çalışmaya devam eder. Window1.IsEnabled = true.IsEnabled = true. Reset yöntemi form üzerindeki tüm denetimleri varsayılan değerlerine sıfırlar.IsEnabled = true. add. (Reset yönteminin nasıl çalıştığını hatırlamıyorsanız.Close().cs dosyasını görüntüleyen Code and Text Editor penceresine geçin. exit_Click yönteminin gövdesine. firstName. yöntemi görüntülemek için Code and Text Editor penceresini aşağı doğru kaydırın.xaml dosyasını görüntüleyen Design View penceresine dönün. RoutedEventArgs e) { this. Form Closing olayını engellerse. hostMemberSince. aşağıda koyu harfle yazılmış olan ifadeyi yazın: private void exit_Click(object sender.IsEnabled = true. Middleshire Bell Ringers Association uygulaması tam olarak bunu yapar ve kullanıcıya uygulamayı kapatmak isteyip istemediğini sorar. Bölüm 22’den hatırlarsanız.IsEnabled = true. . Code and Text Editor penceresine geçin. RoutedEventArgs e) { this.Reset(). 7. } Formun Close yöntemi formu kapatmaya teşebbüs eder . Exit komutu için bir Click olay yöntemi yaratmanız gerekir.xaml.

Başlangıç olarak.Windows.Forms. Window1.Child as System. kullanıcı alternatif dosya adı ve konumu seçebilecek şekilde kodu düzenleyeceksiniz. towerNames.DateTimePicker memberDate = hostMemberSince. lastName.Forms. firstName.IO.Text).Value.WriteLine(“Tower: {0}”.Value) { writer.WriteLine(“Captain: {0}”.xaml dosyasını görüntüleyen Design View penceresine dönün.Items) { if (cb.WriteLine(“Member Since: {0}”.Content.WriteLine(cb. saveMember menü öğesi tanımını bulun ve saveMember_Click adında (<New Event Handler> komutu tarafından oluşturulan varsayılan addır. Save Member Information menü öğesi olayını işleyin 1. writer. writer. Console nesnesini kullanarak konsol uygulamasında metni görüntülemeye oldukça benzer.Text).DateTimePicker. bilgiyi geçerli klasörde Members. 2. foreach (CheckBox cb in methods. Daha sonra.xaml. Dosyanın sonundaki saveMember_Click olay yöntemini bulun. System. } } Bu kod bloğu.ToString()). dosyanın en üstüne gidin ve listeye aşağıdaki using ifadesini ekleyin: using System.ToString()). StreamWriter sınıfını kullanmak.WriteLine(“Methods: “).Show(“Member details saved”. XAML bölmesinde. WriteLine yöntemini kullanabilirsiniz.txt adında sıradan bir metin dosyasına kaydedeceksiniz. memberDate.WriteLine(“First Name: {0}”.Text). form üzerindeki veri dosyaya kaydedilmelidir.txt”)) { writer. RoutedEventArgs e) { using (StreamWriter writer = new StreamWriter(“Members.460 Kısım IV Windows Uygulamaları ile Çalışmak Bir sonraki adım. writer. writer. 3. saveMember menü öğesini işlemektir. yöntemin Member.txt dosyasına metni yazmak için kullandığı bir StreamWriter nesnesi yaratır. Window1. “Saved”).cs dosyasını görüntüleyen Code and Text Editor penceresinde. Yöntem gövdesine aşağıdaki ifadeleri ekleyin: private void saveMember_Click(object sender.IsChecked.IsChecked.Windows.) bir Click olay yöntemi belirlemek için <New Event Handler> komutunu kullanın. writer. . Kullanıcı bu menü öğesini tıkladığında.ToString()).WriteLine(“Last Name: {0}”. } } MessageBox. isCaptain.

add_Click yöntemini açıklama satırına çevirin. Bu menü öğesi. About Middleshire Bell Ringers menü öğesi olayını işleyin 1.0” Name=”version” Height=”30” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”75”>Version 1.microsoft.xaml formunu tıklayın. Geriye about menü öğesi kalıyor. XAML bölmesinde. Properties penceresinde.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas. Width özelliğine 300 ve Height özelliğine de 156 atayın. Window (WPF)’u tıklayın. Name metin kutusuna About. bu şablon WPF penceresinden çok bir Windows Forms penceresi oluşturur. 2. Design View penceresinde.About” xmlns=”http://schemas. Forma iki etiket denetimi ve bir düğme denetimi ekleyin. yayıncı ve diğer yararlı bilgileri sağlayan bir iletişim kutusu göstermelidir. Uygun denetimleri eklediğinizde.0. uygulamanın sürümü hakkında. 3.IsEnabled = true. Add düğmesi ve ilişkili olay yöntemi şimdi kullanılmaz durumdadır. bu üç denetimin özelliklerini aşağıda gösterildiği gibi değiştirin (isterseniz buildDate etiketi tarafından görüntülenen metni değiştirebilirsiniz): <Window x:Class=”BellRingers. Title özelliğini About Middleshire Bell Ringers olarak değiştirin.com/winfx/2006/xaml” Title=”About Middleshire Bell Ringers” Height=”156” Width=”300” Name=”AboutBellRingers” ResizeMode=”NoResize”> <Grid> <Label Margin=”80.xaml yazın ve daha sonra Add’i tıklayın. About Box pencereleri şablonunu sağlar. 5.microsoft. 5. aşağıdaki ifadeyi açıklama satırına dönüştürün: // add. Add New Item – BellRingers iletişim kutusundaki Templates bölmesinde. Bir sonraki alıştırmada bu olayı işlemek için bir olay yöntemi ekleyeceksiniz.20.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 461 Ayrıntıların tümü yazıldığında. 4. Properties penceresinin üst kısmındaki Name kutusuna AboutBellRingers yazın. Project menüsünde Add Window’u tıklayın. Bununla birlikte.0</Label> . About. bu nedenle Design View penceresinde Add düğmesini silin. kullanıcıya bazı geri dönüşler veren bir ileti kutusu görüntülenir (her zaman iyi bir fikirdir). kullanıcı Help menüsündeki About Middleshire Bell Ringers komutunu tıkladığında bu pencereyi görüntüleyeceksiniz. Kullanıcının pencere boyutunu değiştirmesini engellemek için ResizeMode özelliğini NoResize olarak ayarlayın. Code and Text Editor penceresinde. newMember_Click yönteminde. Not Visual Studio. 4.

0” Name=”ok” HorizontalAlignment=”Left” Width=”78” Height=”23” VerticalAlignment=”Top”>OK</Button> </Grid> </Window> Tamamlanmış form şöyle görünmelidir: 6. 7. aboutWindow.cs dosyasını görüntüleyen Code and Text Editor penceresinde. Window1. . RoutedEventArgs e) { About aboutWindow = new About(). Visual Studio. About.85.0.xaml.462 Kısım IV Windows Uygulamaları ile Çalışmak <Label Margin=”80. RoutedEventArgs e) { this. about_ Click yöntemine aşağıdaki ifadeleri ekleyin: private void about_Click(object sender.cs dosyasına ok_Click yöntemini ekler. about menü öğesinin tanımını bulun ve about_Click adında (<New Event Handler> komutu tarafından üretilen varsayılan addır) bir Click olay yöntemi belirlemek için <New Event Handler> komutunu kullanın.0” Name=”buildDate” Height=”30” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”160”>Build date: September 2007</Label> <Button Margin=”100.xaml. Design View penceresinde OK düğmesini çift tıklayın.ShowDialog().0. XAML bölmesinde. ok_Click yöntemine aşağıdaki ifadeyi ekleyin: private void ok_Click(object sender. ShowDialog yöntemi. } Kullanıcı OK düğmesini tıkladığında pencere kapanacaktır. About penceresi kapanana kadar (kullanıcı OK düğmesini tıkladığında) birşey döndürmez. About penceresinin yeni bir örneğini yaratır ve sonra bu örneği görüntülemek için ShowDialog yöntemini çağırır.xaml.50. } Bu kod.xaml dosyasını görüntüleyen Design View penceresine dönün.cs dosyasını görüntüleyen Code and Text Editor penceresinde.Close(). 8. Window1. düğmenin Click olayı için bir olay yöntemi üretir ve About. 9.

txt dosyasının içeriğini Not Defteri’nde görüntülemek için üzerini çift tıklayın. İleti kutusunda OK’ i tıklayın. Help menüsünde About Middleshire Bell Ringers’ı tıklayın. 8. Tekrar File menüsünü tıklayın. 5. Windows Gezgininde Belgeler klasörünüzün altındaki \Microsoft Press\Visual CSharp Step by Step\Chapter 23\BellRingers\BellRingers\bin\Debug klasörüne gidin. Members. 3. Bu klasörde Members. About penceresi ortaya çıkar. Yeni üye için bilgileri girin. Formdaki alanlar şimdi etkin durumdadır .txt adında bir dosya görmelisiniz. 10. Bu dosya yeni üyenin bilgilerini içermelidir. 7. Members formuna dönmek için OK’i tıklayın. 2. form kapanmaz. Şimdi Save Member Details komutu etkindir. Save Member Details komutu etkisizleştirilir. Debug menüsünde Start Without Debugging’i tıklayarak uygulamayı oluşturun ve çalıştırın. Not Defteri’ni kapatın ve Middleshire Bell Ringers uygulamasına dönün. . No’yu tıklarsanız. 12. File menüsünde Save Member Details’i tıklayın. 11. 13. Formu kapatmak için Yes’i tıklayın. Kısa bir süre sonra “Member details saved” (Üye bilgileri kaydedildi) iletisi görünür. Formdaki tüm alanların etkisiz hale geldiğine dikkat edin. 6. Form kapanmayı dener. Yes’i tıklarsanız form kapanır ve uygulama sonlanır. 9. File menüsünde Exit’i tıklayın. File menüsünde New Member’ı tıklayın.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 463 Menü olaylarını test edin 1. File menüsünü tıklayın. Bu pencereyi yeniden boyutlandıramadığınıza ve About penceresi etkinken Members formu üzerinde hiçbir öğeyi tıklayamadığınıza dikkat edin. Formu kapatmak istediğinizden emin olup olmadığınız sorulur. 4.

Kısayol menüsünü pencere kaynaklarına eklemek.. XAML bölmesinde pencere kaynaklarının sonuna.. 2. metin düzenlemeleri yapabilmek için Cut. textBoxMenu kısayol menüsüne aşağıdaki MenuItem öğesini ekleyin: <Window. Bu menüler. Genellikle context (içerik) ya da shortcut (kısayol) menüler olarak adlandırılırlar. Copy ve Paste komutlarını sağlayan varsayılan bir kısayol menüsü ile ilişkilendirilir. genellikle içerik duyarlıdır ve yalnızca etkin denetime ya da forma özgü komutları listeler. İlk kısayol menüsü firstName ve lastName metin kutusu denetimlerine bağlıdır ve kullanıcının denetimleri temizlemesini sağlar. Window1. <ContextMenu x:Key=”textBoxMenu” Style=”{StaticResource bellRingersFontStyle}”> <MenuItem Header=”Clear Name” Name=”clearName” /> </ContextMenu> </Window. stil tanımından sonrasına aşağıdaki ContextMenu öğesini ekleyin: <Window. Not Metin kutusu denetimleri. <ContextMenu x:Key=”textBoxMenu” Style=”{StaticResource bellRingersFontStyle}”> </ContextMenu> </Window.Resources> Bu kısayol menüsü. WPF uygulamasına kolayca kısayol menüleri ekleyebilirsiniz. firstName ve lastName kısayol menüsü yaratın 1. İkinci kısayol menüsü ise forma bağlıdır ve gösterilmekte olan üye bilgilerini kaydetmek ve formu temizlemek için kullanılabilecek komutları içerir. bu varsayılan menüyü etkisiz kılacaktır.Resources> .464 Kısım IV Windows Uygulamaları ile Çalışmak Kısayol Menüleri Birçok Windows tabanlı uygulama.Resources> . ContextMenu sınıfını kullanarak. Kısayol Menüleri Yaratmak Aşağıdaki alıştırmalarda iki kısayol menüsü yaratacaksınız.xaml’i görüntüleyen Design View penceresinde.Resources> .. Aşağıdaki alıştırmada tanımlayacağınız kısayol menüsü. bir form ya da denetimi farenin sağ düğmesiyle tıkladığınızda beliren açılan (pop-up) menüleri kullanır. firstName ve lastName metin kutuları tarafından paylaşılacaktır. menüyü penceredeki her denetim için kullanılabilir yapar..

herhangi bir açılır (pop-up) menü belirmemelidir. 7.Text = String. 9. Formda First Name ve Last Name metin kutuları dışında herhangi bir yeri tıklayın. Bu kod..xaml. Biraz değişiklik sağlamak ve kısayol menülerini dinamik olarak yaratmanın ne kadar kolay olduğunu .. lastName. Kısayol menüsünde. textBoxMenu stilinin tanımına dönerek clearName menü öğesine clearName_Click adında (<New Event Handler> komutu tarafından üretilen varsayılan addır. hangi menünün görüntüleneceğini belirler. kısayol menüsüne “Clear Name” (Adı Temizle) açıklamasıyla. /> . Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.Empty. Kısayol menüsünde. 3. /> ContextMenu özelliği.. First Name ve Last Name metin kutularına bir ad yazın. kullanıcı denetimi farenin sağ düğmesiyle tıkladığında. Clear Name komutunu tıklayın ve her iki metin kutusunun da temizlendiğini doğrulayın..Text = String. 4.Empty. Sadece First Name ve Last Name metin kutuları kısayol menülerine sahiptir. 10.. Bu defa. 8. firstName ve lastName metin kutusu denetimlerinin tanımlamalarını düzenleyin ve ContextMenu özelliğini ekleyin: <TextBox .. <MenuItem Header=”Clear Name” Name=”clearName” Click=”clearName_Click” /> 5. Formu kapatın ve Visual Studio 2008’e dönün. <TextBox . Şimdi.. kullanıcı kısayol menüsündeki Clear Name komutunu tıkladığında metin kutularının her ikisini de temizler. 6.cs’i görüntüleyen Code and Text Editor penceresinde.. <New Event Handler> komutunun oluşturduğu clearName_Click olay yöntemine aşağıdaki ifadeleri ekleyin: firstName. XAML bölmesinde.) bir Click olay yöntemi ekleyin.. Form belirdiğinde File’ı tıklayın ve sonra da New Member’ı tıklayın. Name=”lastName” ContextMenu=”{StaticResource textBoxMenu}” . Window1. First Name ve Last Name metin kutularına bir ad yazın.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 465 Bu kod. Name=”firstName” ContextMenu=”{StaticResource textBoxMenu}” . kullanıcının üye bilgisini kaydetmek ve formdaki alanları temizlemek için kullanabileceği komutlar içeren ikinci kısayol menüsünü ekleyebilirsiniz. First Name metin kutusunu farenin sağ düğmesiyle tıklayın.. Last Name metin kutusunu farenin sağ düğmesiyle tıklayın. clearName adında bir menü öğesi ekler. Clear Name komutunu tıklayın ve her iki metin kutusunun da temizlendiğini doğrulayın.

Window1 sınıfı için kurucuyu bulun.. form üzerindeki alanları temizleyen ve varsayılan değerlerine sıfırlayan menü öğeleri yaratmak için aşağıdaki ifadeleri ekleyin: public Window1() { . .xaml. ..Header = “Clear Form”. clearFormMenuItem. } Bu menü öğesi. MenuItem saveMemberMenuItem = new MenuItem(). Bu gerçekten sınıftaki ilk yöntemdir ve Window1 olarak adlandırılır. } 3. this. Üye bilgilerini kaydetmek üzere menü öğeleri yaratmak için Reset yöntemini çağıran koddan sonra aşağıdaki ifadeleri ekleyin: public Window1() { InitializeComponent(). 2. private ContextMenu windowContextMenu = null.Reset(). Daha sonra.. menü öğesi için Header özelliğini ayarlar ve sonra Click olayının saveMember_ Click olay yöntemini çağırması gerektiğini belirtir.cs dosyasını görüntüleyen Code and Text Editor penceresine geçin. (Temsilciler ve olaylarla ilgili daha fazla bilgi için.. aşağıdaki alıştırmada kod kullanarak kısayol menüsü yaratacaksınız.466 Kısım IV Windows Uygulamaları ile Çalışmak göstermek için. Bu kodu yerleştirmek için en iyi yer. bu daha önceki alıştırmada yazdığınız yöntemin aynısıdır. kullanıcı tarafından tıklandığında clear_Click olayını çağırır. RoutedEventHandler türü. kullanıcı yeni bir üye yarattığında pencere için kısayol menüsünü etkinleştirmek için kod ekleyeceksiniz. saveMemberMenuItem..) 4.Click += new RoutedEventHandler(saveMember_Click). MenuItem clearFormMenuItem = new MenuItem(). birçok WPF denetimi tarafından ortaya çıkarılan olayları işlemek için yöntemleri gösteren bir temsilcidir.Click += new RoutedEventHandler(clear_Click). } Bu kod. Bölüm 17’ye bakın. Window1. formun kurucusudur. clearFormMenuItem. Window1 sınıfına aşağıdaki özel (private) değişkeni ekleyin: public partial class Window1 : Window { .. Pencere kısayol menüsünü yaratın 1. Window1 kurucusuna.Header = “Save Member Details”. saveMemberMenuItem.

Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 467 5. formu farenin sağ düğmesiyle tıklayın ve kısayol menüsünün ortaya çıkmadığını doğrulayın. 8. Formun ContextMenu özelliğini kurucuda ayarlamak isteseydiniz. Kısayol menüsünü form ile ilişkilendirmek için. Kısayol menüsünde Clear Form’u tıklayın ve formdaki alanların varsayılan değerlerine sıfırlandığını doğrulayın. uygulamada olmasını istediğiniz bir davranış değildir. windowContextMenu. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. . Formu farenin sağ düğmesiyle tıklayın.. menü öğelerini tutan bir koleksiyon içerir. File menüsünde New Member’ı tıklayın ve sonra yeni üyenin bilgilerini girin. Window1 kurucusuna aşağıdaki ifadeleri ekleyin: public Window1() { . RoutedEventArgs e) { .. Formu kapatın ve Visual Studio 2008’e geri dönün. Kısayol menüsünde Save Member Details’ı tıklayın.Add(saveMemberMenuItem). 11. 10. this. windowContextMenu.Add(clearFormMenuItem). Form belirdiğinde.Items. 9. Formu farenin sağ düğmesiyle tıklayın. “Member details saved” (Üye bilgileri kaydedildi) ileti kutusunun belirdiğini görün ve daha sonra OK’i tıklayın.Items. formdaki denetimler etkisiz hale getirilse bile Save Member Details ve Clear Details kısayol menü öğeleri etkin olacaktı. 7... 6. } ContextMenu türü. newMember_Click olay yönteminin sonuna aşağıdaki ifadeyi ekleyin: private void newMember_Click(object sender. Daha fazla üyenin bilgisini girin. İpucu Formun ContextMenu özelliğini null olarak ayarlayarak kısayol menüsü ile form ilişkisini kesebilirsiniz. 12.ContextMenu = windowContextMenu. Items adında. Bu. } Uygulamanın sadece yeni üye işlevselliği kullanılabilir olduğunda kısayol menüsünü form ile ilişkilendirdiğine dikkat edin. Kısayol menüsü kurmak ve yeni yarattığınız menü öğelerini yerleştirmek için. windowContextMenu = new ContextMenu().

SaveFileDialog sınıfı Microsoft. üye bilgilerini kaydetmenize olanak verse de verileri hep aynı dosyaya kaydeder ve burada olan her şeyin üzerine yazar. kullanıcı bilgileri bir dosyaya kaydederken. Şimdi bu konulara eğilme zamanıdır. saveDialog. BellRingers uygulamasında. Window1. YourName yerine kendi hesap adınızı yazın: private void saveMember_Click(object sender. } . Örneğin. saveDialog.FileName = “Members”.cs’i görüntüleyen Code and Text Editor penceresinde. kullanıcı bir dosyayı açmak ya da kaydetmek isterse. Kullanıcının bir tür bilgiyi belirtmesini gerektiren birçok günlük görev bulunur. genellikle kendisine hangi dosyayı açmak istediği ya da dosyayı nereye kaydetmek istediği sorulur.AddExtension = true. Aynı iletişim kutularının birçok farklı uygulama tarafından kullanıldığını fark etmişsinizdir. dosyanın üst kısmına aşağıdaki using ifadesini ekleyin: using Microsoft. RoutedEventArgs e) { SaveFileDialog saveDialog = new SaveFileDialog().Title = “Bell Ringers”. SaveFileDialog sınıfını kullanacaksınız.OverwritePrompt = true. saveDialog.468 Kısım IV Windows Uygulamaları ile Çalışmak Windows Ortak İletişim Kutuları Bell Ringers uygulaması.NET Framework sınıf kütüphanesi. saveDialog. saveDialog.. .DefaultExt = “txt”.Win32. bu işlevsellik o kadar yaygındır ki Microsoft bunu standartlaştırmış ve “ortak iletişim” olarak kullanılabilir kılmıştır (Microsoft Windows işletim sistemiyle birlikte gelen ve kendi uygulamalarınızda kullanabileceğiniz bir bileşendir). SaveFileDialog sınıfını kullanın 1.ValidateNames = true.Win32 ad alanındadır. Bu uygulama geliştiricilerin düş güçlerinin eksikliğinden kaynaklanmamaktadır.. SaveFileDialog Sınıfını Kullanmak Aşağıdaki alıştırmada.xaml. 2. Microsoft . saveDialog. saveMember_Click yöntemini bulun ve bu yöntemin başlangıcına aşağıdaki kodu ekleyin. bu ortak iletişim kutuları için kapsayıcı görevi yapan OpenFileDialog ve SaveFileDialog sınıflarını sağlar. Save File ortak iletişim kutusu ile kullanıcıdan dosya adı ve dosyanın konumunu girmesini isteyeceksiniz. saveDialog.InitialDirectory = @”C:\Users\YourName\Documents\”.

OverwritePrompt gibi bazı diğer özellikler tarafından kullanılır.ShowDialog(). İletişim kutusu tarafından kullanılan varsayılan dizin. Aşağıdaki tabloda bu özelliklerin amacı listelenmiştir.. yani kullanıcı düğmelerinden birini tıklayarak bu iletişim kutusunu kapatana kadar uygulamadaki diğer formları kullanmaya devam edemez. iletişim kutusu kullanıcının yazdığı dosya adında sadece geçerli karakterler olduğunu doğrular. saveDialog nesnesinin InitialDirectory özelliğini ayarlayan ifade yerine aşağıdaki kodu yazın: saveDialog.InitialDirectory = @”C:\Documents and Settings\YourName\My Documents\”. ValidateNames özelliği true olarak ayarlanmışsa. Dosya adının geçerli olup olmadığını gösterir.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 469 Not Windows XP kullanıyorsanız. Kullanıcı var olan bir dosyanın üzerine yazmaya kalkarsa. ValidateNames özelliğinin de true olması gerekir. kullanıcı tarafından belirlenen dosya adına DefaultExt özelliği tarafından gösterilen dosya adı uzantısını eklemek için iletişim kutusunu etkinleştirir. saveMember_Click yöntemine aşağıdaki ifadeleri ekleyin ve StreamWriter nesnesini yaratan ve üye bilgilerini bir if ifadesi içinde yazan önceki kodu kapsayın: if (saveDialog. Varsayılan dosya adı belirlemek için bu özelliği kullanabilirsiniz ya da varsayılan dosya adı istemiyorsanız bu özelliği temizleyebilirsiniz. Seçili dosya adıdır. } } ShowDialog yöntemi. Özellik DefaultExt AddExtension Tanımı Kullanıcı dosya adını verirken uzantısını belirtmemişse. İletişim kutusunun başlık çubuğunda görüntülenen dize.. Save File iletişim . kullanılacak olan varsayılan dosya uzantısıdır. FileName InitialDirectory OverwritePrompt Title ValidateNames 3.Value) { using (StreamWriter writer = new StreamWriter(“Members. Save File iletişim kutusu tipiktir. SaveFileDialog sınıfının yeni bir örneğini yaratır ve özelliklerini ayarlar. iletişim kutusunun kullanıcıyı uyarmasını sağlar.txt”)) { // varolan kod . Kullanıcı dosya uzantısını ihmal ettiyse. Save File iletişim kutusunu görüntüler. Bunun çalışması için. Bu kod.

7. 5. 4. Belgeler ve varsayılan dosya adı da Members olmalıdır: Dosya adı uzantısını ihmal ederseniz. saveMember_Click yönteminde. File name metin kutusundaki değeri TestMember olarak değiştirin ve daha sonra Save’i tıklayın. File menüsünde New Member’ı tıklayın ve daha sonra yeni üyenin bilglerini ekleyin. Tüm yaptığı. Aşağıda gösterildiği gibi. varsayılan klasör.470 Kısım IV Windows Uygulamaları ile Çalışmak kutusu bir Save düğmesine ve bir Cancel düğmesine sahiptir. iletişim kutusu sizi uyaracaktır. kullanıcının FileName özelliğinde seçtiği dosya adını sağlamaktır. .txt yerine kullanıcının belirlediği dosyaya yazacaktır. aksi durumda false olur . “Member details saved” (Üye bilgileri kaydedildi) iletisinin göründüğünü doğrulayın ve OK’i tıklayın. 8. Kullanıcı Save’i tıklarsa. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. StreamWriter nesnesini yaratan ifadeyi aşağıdaki gibi değiştirin: using (StreamWriter writer = new StreamWriter(saveDialog. “Bell Ringers” başlığı ile Save File iletişim kutusu açılmalıdır. 9. Bell Ringers uygulamasında. Daha sonra uygulamayı kapatın. dosya kaydedildiğinde dosya uzantısı olarak . şimdi Members. File menüsünde Save Member Details’ı tıklayın.txt’i ekler.FileName)) { . } saveMember_Click yöntemi. ShowDialog yöntemi kullanıcıdan dosyayı kaydetmek için bir dosya adı girmesini ister fakat gerçekte dosyayı kaydetmez. Var olan bir dosyayı seçerseniz.. kodu yine kendiniz sağlamak zorundasınız. 6. ShowDialog yöntemi tarafından döndürülen değer true olur..

Tasarım sırasında Properties penceresinde. Dosyayı çift tıklayın ve dosyanın eklediğiniz üyenin bilgilerini içerdiğini doğrulayın. Header özelliği ile menü öğesi için metni belirleyin ve Name özelliğini belirleyerek de her menü öğesine bir ad verin. Bir dosyayı açmak için de aynı tekniği kullanabilirsiniz: bir OpenFileDialog nesnesi yaratın. OpenFileDialog sınıfını kullanmak ile ilgili daha fazla ayrıntı için. Sıradan menüye öğeleri eklediğiniz biçimde kısayol menüsüne öğeleri ekleyin. Visual Studio 2008 için MSDN Kütüphanesine başvurun. Yes’i tıklayarak (Visual Studio 2008 kullanıyorsanız) ya da Save’i tıklayarak (Visual C# 2008 Express Edition kullanıyorsanız) projeyi kaydedin. IsEnabled özelliğini True ya da False olarak ayarlayın ya da çalışma zamanında IsEnabled özelliğini true ya da false olarak ayarlamak için kod yazın. n Bölüm 23 Hızlı Başvuru Bunun İçin Form için bir menü yaratmak Menüye menü öğeleri eklemek Şunu Yapın DockPanel denetimi ekleyin ve formun en üstüne yerleştirin. Pencere kaynaklarına bir ContextMenu ekleyin. Kısayol menüsüne başvurmak için form ya da denetimin ContextMenu özelliğini ayarlayın. Bir menüde ayırıcı çubuğu yaratmak Bir menü öğesini etkinleştirmek ya da devre dışı bırakmak Kullanıcı bir menü öğesini tıkladığında bir eylem gerçekleştirmek Bir kısayol menüsü yaratmak Kısayol menüsünü bir form ya da denetim ile ilişkilendirmek . Uygun harfi alt çizgi ile belirterek menü öğesine bir erişim anahtarı ekleyebilirsiniz. ShowDialog yöntemini kullanarak etkinleştirin ve kullanıcı Open düğmesini tıkladığı sonucunu döndürdüğünde FileName özelliğini alın. Menüye Seperator öğesi ekleyin. Olay yöntemine kodunuzu ekleyin. DockPanel denetimine Menu denetimi ekleyin. Windows Gezginini kullanarak Belgeler klasörünüze gidin. Simgeler ve alt menüler gibi özellikleri görüntüleyebilmek için isteğe bağlı özellikleri de belirleyebilirsiniz.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 471 10. 11. Daha sonra Not Defteri uygulamasını kapatın. Menu denetimine MenuItem öğeleri ekleyin. Save iletişim kutusu görünürse.txt dosyasının yaratıldığını doğrulayın. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i açık bırakın ve Bölüm 24’e geçin. içeriğini okuyabilir ve ekranda alanları yerleştirebilirsiniz. Daha sonra dosyayı açabilir. Menü öğesini seçin ve Click olayı için bir olay yöntemi belirleyin. TestMember.

İletişim kutusu kapandığında. Bu nesnenin Items koleksiyonunu.472 Kısım IV Windows Uygulamaları ile Çalışmak Dinamik olarak kısayol menüsü yaratmak Kullanıcıyı kaydedilecek dosyaya ad vermesi için uyarmak. Kısayol menüsüne başvurmak için form ya da denetimin ContextMenu özelliğini ayarlayın. Bir ContextMenu nesnesi yaratın. menü öğelerini tanımlayan MenuItem nesneleri ile yerleştirin. ShowDialog yöntemini kullanarak iletişim kutusunu görüntüleyin. kullanıcının seçtiği dosyanın adını içerir. SaveFileDialog örneğinin FileName özelliği. SaveFileDialog sınıfını kullanın. .

kullanıcı tarafından girilen bilgilerin anlamlı olmasına yardımcı olsa da genelde gerçekleştirmeniz gereken ek denetimler vardır. Bu strateji ile ilgili problem. etkili ama sıkıntı vermeyen biçimde gerçekleştirmek . formlar ve denetimler tarafından başlatılan olayların nasıl yakalanacağını böylece uygulamanızın güzel görünmek dışında nasıl gerçekten bir şeyler yapabileceğini öğrendiniz. Kullanıcı Girişini Doğrulamak İçin Stratejiler Uygulamanızın kullanıcıları tarafından girilen bilgiyi doğrulamak için birçok strateji uygulayabilirsiniz. Bu bölümde. hiçbir uygulamayı ya da iş kuralını ihlal etmediğinden emin olmak için incelemek. formun kullanımını zorlaştırır ve sinirleri gerer. LostFocus olayı. kullanıcı bir denetimden uzaklaştığında ortaya çıkar. uygulamayı çalıştıran bir kullanıcı tarafından girilen verilerin. denetimlerin LostFocus olayını işlemektir. Arka plandaki iş kuralı görece çok açık olabilir ama çoğu zaman yanlış zamanda gerçekleştirilen doğrulama.Bölüm 24 Doğrulamayı Gerçekleştirmek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n Kullanıcı tarafından girilen bilgileri. Kullanıcının terkettiği denetimdeki veriyi incelemek ve işlecin uzaklaşmasına izin vermeden önce uygulamanın gereksinimleri ile eşleştiğinden emin olmak için bu olaya kod ekleyebilirsiniz. Doğrulamayı. Verileri Doğrulamak Girdi doğrulama kavramı olabildiğince basittir ama uygulama içinde kullanımı her zaman kolay olmaz. Kullanıcı tarafından girilen bilgiyi doğrulamak için veri bağlama doğrulama kurallarını kullanmak. veri girişi için birçok denetim kullanan Microsoft Windows Presentation Foundation (WPF) uygulamasının nasıl yaratılacağını gördünüz. n n Önceki iki bölümde. Microsoft . Birçok Microsoft Windows yazılım geliştiricisinin. özellikle de doğrulama kullanıcının iki ya da daha çok denetime girdiği verilerin karşılıklı doğrulanmalarını gerektiriyorsa.NET Framework’un önceki sürümlerinden aşina olduğu yaygın teknik. çoğu kez bir denetime girilen değer ile 473 . Menüler. Bir formun dikkatli tasarlanması ve denetimlerin uygun kullanımları. Uygulamanın kullanımını kolaylaştırmak amacıyla menüler yarattınız. uygulamanın gereklilikleri tarafından belirlenen iş kurallarına uyduğundan emin olmak için nasıl doğrulanacağını öğreneceksiniz.

belirlenen ve doğrulanan uygun iş modeli sınıfı örneğine kopyalanabilir. Kullanıcı girdisinin tutarlı olduğundan emin olmanız gerekir. kullanıcının bir denetimden diğerine geçiş sırası üzerinde bir güce sahip değilsiniz. İş gereksinimleri değişirse. çoğu kez birkaç denetim için LostFocus olay işleyicisinde benzer mantığı tekrarlamayı bırakırsınız. . iş modeli tarafından istenen sınıfı tanımlar ve daha sonra kullanıcı arabirimi denetimlerinin özelliklerini bu sınıflar tarafından sunulan özelliklere bağlarsınız. Daha sonra. bu nedenle form üzerindeki belirli bir denetimin diğerlerine göre karşılıklı kontrolünü yapıyorsanız her denetimin geçerli veri içerdiğini her zaman varsayamazsınız. “Veriyi Yönetmek” başlıklı Kısım V’te veri bağlama hakkında daha fazla şey öğreneceksiniz. Kullanıcı bir formdaki denetimler üzerinde hareket edebilir. Miss ya da Ms) seçili cinsiyetle (Male (Erkek) ya da Female (Kadın)) eşleşmelidir veya tam tersi. WPF bu sınıfların örneklerini yaratabilir. Uygulamanın bir bölümü. hitap. Bir Müşteri Yönetimi uygulaması geliştirmeniz istendi diyelim. Bu bölümde.474 Kısım IV Windows Uygulamaları ile Çalışmak diğerlerindeki değerleri karşılıklı kontrol etmeniz gerekmesi ve doğrulama mantığının oldukça karmaşık hale gelebilmesidir. bir uygulamanın sunum öğelerinin doğrulama mantığının iş mantığına oldukça yakından bağlı olmasıdır. Aşağıdaki resimdekine benzer bir form yaratmaya karar verdiniz. Çalışma zamanında. ad ve cinsiyeti de içeren temel müşteri bilgilerinin girilmesini gerektirir. kullanıcı arabiriminin Extensible Application Markup Language (XAML) tanımından bu kurallara başvurabilirsiniz. doğrulama mantığını da değiştirmeniz gerekebilir ve kodun bakımı karmaşık bir iş haline gelebilir. WPF ile uygulamanız tarafından kullanılan iş modelinin parçası olarak doğrulama kuralları tanımlayabilirsiniz. Mrs. Bir denetimdeki veriyi değiştirdiğinizde. hitap (Mr. Bu strateji ile ilgili bir diğer önemli konu. veri otomatik olarak. Ayrıca. Bir Örnek: Müşteri Yönetimi Örnek olarak basit bir senaryo düşünün. Bunun için. veri bağlama ile ilişkilendirebileceğiniz doğrulama kuralları üzerinde yoğunlaşacağız.

Uygulama gerçekte herhangi bir veri kaydetmez. doğrulamayı yanlış zamanda yapmanın ve uygulamayı neredeyse kullanılamaz yapmanın ne kadar kolay olduğunu göreceksiniz! Müşteri Ayrıntıları formunu inceleyin 1. Kaydederse. Bir ad girişini sağlamak için doğrulama mantığıyla Customer sınıfını yaratın 1. 5. 3. Microsoft Visual Studio 2008’i başlatın. 7. OK’i tıklayın ve formu kapatarak Visual Studio 2008’e geri dönün. Gender grup kutusunda. Form belirdiğinde. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Uyarıcı bir aşama olarak. Kullanıcının her zaman müşterinin ilk adını ve soyadını girdiğinden emin olmak için bu sınıfı nasıl kullanacağınızı öğrenmekle başlayacaksınız. 3. } . File menüsünde. Solution Explorer’da. 6.Bölüm 24 Doğrulamayı Gerçekleştirmek 475 Veri Bağlamayı Kullanarak Doğrulamayı Gerçekleştirmek Aşağıdaki alıştırmalarda. tüm müşteriler bir ada sahip olmalıdır ve Title ve Gender denetimleri için belirlenen veriler tutarlı olmalıdır. CustomerDetails projesini farenin sağ düğmesiyle tıklayın. 2. Add’i işaret edin ve daha sonra Class’ı tıklayın. Female seçenek düğmesini tıklayın. 2.cs dosyasını görüntüleyen Code and Text Editor penceresinde Customer sınıfına özel foreName ve lastName alanlarını ekleyin: class Customer { private string foreName.cs yazın ve sonra Add’i tıklayın. private string lastName. Save’i tıklayın ve “Customer saved” (Müşteri kaydedildi) ileti kutusunun belirdiğini doğrulayın. Title açılan kutusundaki aşağı okunu ve ardından Mr’ı tıklayın. Customer. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step By Step\Chapter 24\ CustomerDetails klasöründe yer alan CustomerDetails projesini açın. Müşteri Yönetimi uygulamasını inceleyecek ve veri bağlamayı kullanarak doğrulama kuralları ekleyeceksiniz. bir müşteri modelleyen bir sınıf yaratmaktır. 4. uygulama herhangi bir denetim gerçekleştirmediğinden kaydedilen bilgi tutarsız olacaktır. Gerekli doğrulama mantığını eklemenin ilk adımı. İdeal olarak. Add New Item – CustomerDetails iletişim kutusunda Name metin kutusuna Customer.

. Customer sınıfına aşağıdaki kodda koyu harfle gösterilen LastName özelliğini ekleyin..foreName. bir önceki basamakta eklediğiniz foreName alanına dayalı. } else { this.476 Kısım IV Windows Uygulamaları ile Çalışmak 4. } set { if (String.IsNullOrEmpty(value)) { throw new ApplicationException (“Specify a forename for the customer”). uygun bir iletiyle bir özel durum oluşturur.lastName. bir sonraki adım form üzerindeki foreName ve lastName metin kutularını sınıfın uygun özelliklerine bağlamaktır. . } else { this..lastName = value.foreName = value. public string ForeName { get { return this.IsNullOrEmpty(value)) { throw new ApplicationException (“Specify a last name for the customer”). public string LastName { get { return this. } } } } Şimdi Customer sınıfını oluşturdunuz. 5. Customer sınıfına.. Bu özellik ForeName özelliği ile benzer modeli izler: class Customer { . } } } } set erişimci özelliği ilk ad için sağlanan değeri inceler ve değer boş ise. } set { if (String. aşağıdaki genel ForeName özelliğini ekleyin: class Customer { .

Bu kaynak Customer sınıfının yeni bir örneğini yaratır. CustomerForm. Window tanımına aşağıdaki XML ad alanı bildirimini ekleyin: <Window x:Class=”CustomerDetails.74.. Pencerenin XAML tanımında başka bir yerde customerData anahtar değerini kullanarak bu örneğe başvurabilirsiniz. pencere için XAML kodundaki CustomerDetails ad alanındaki türlere başvurabilirsiniz. 2.. 3.Resources> <cust:Customer x:Key=”customerData” /> </Window..com/winfx/2006/xaml” xmlns:cust=”clr-namespace:CustomerDetails” Title=”Customer Details” Height=”273” Width=”370” ResizeMode=”NoResize”> . Kullanıcı form üzerindeki foreName metin kutusundaki değeri güncellerse. . XAML bölmesinde.. yeni veri otomatik olarak customerData nesnesine kopyalanır.Resources> <Grid> .ResizeMode=”NoResize”> <Window.Bölüm 24 Doğrulamayı Gerçekleştirmek 477 Formdaki metin kutusu denetimlerini Customer sınıfındaki özelliklere bağlayın 1.microsoft.Text> </TextBox> Bu kod..CustomerForm” .0” Name=”foreName” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”120” > <TextBox..Resources öğesini pencereye ekleyin: <Window x:Class=”CustomerDetails. customerData nesnesinin ForeName özelliğindeki veriye bağlar. Bu bildirim ile. bu metin kutusunun Text özelliğinde görüntülenen veriyi. Solution Explorer’da.. .xaml dosyasını çift tıklayarak formu Design View penceresinde görüntüleyin.CustomerForm” xmlns=”http://schemas. 4.Text> <Binding Source=”{StaticResource customerData}” Path=”ForeName” /> </TextBox. Customer sınıfındaki ForeName özelliğinin kullanıcının bir değeri sadece silmediğini. gerçekte bir değer belirlediğini denetlediğini hatırlayın.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas. XAML bölmesinde foreName metin kutusunun tanımını bulun ve aşağıda gösterildiği gibi değiştirin (TextBox denetimi için kapanan sınırlayıcı etiketini [/>]. Aşağıdaki Window.microsoft..0. sıradan sınırlayıcı [>] ile değiştirdiğinizden ve kapanan </TextBox> etiketi eklediğinizden emin olun): <TextBox Height=”21” Margin=”70.

Bu defa. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. foreName metin kutusunu tıklayın.0. foreName metin kutusuna tekrar bir değer girin ve lastName metin kutusundaki değeri silin.0. denetimi belirginleştirir. foreName ve lastName metin kutularına adınızı yazın ve daha sonra title açılan kutusunu tıklayın. ExceptionValidationRule öğesi. bu denetimdeki veri değiştiğinde uygulama tarafından oluşturulan bir özel durumu denetleyen yerleşik bir kuraldır.478 Kısım IV Windows Uygulamaları ile Çalışmak 5.0” Name=”foreName” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”120” > <TextBox. Form göründüğünde. girdiğiniz ilk adı silin ve daha sonra title açılan kutusunu tekrar tıklayın.Text> </TextBox> 7.ValidationRules> </Binding> </TextBox. Herhangi bir özel durum saptarsa. 8. böylece kullanıcı giriş ile ilgili bir problem olduğunu görebilir. foreName metin kutusundaki kırmızı çerçevenin yok olduğuna fakat lastName metin kutusu etrafında kırmızı çerçeve olmadığına dikkat edin.ValidationRules> <ExceptionValidationRule/> </Binding.Text> <Binding Source=”{StaticResource customerData}” Path=”ForeName” > <Binding.74. lastName metin kutusuna.ValidationRules alt öğesini ekleyin: <TextBox Height=”21” Margin=”70.Text> <Binding Source=”{StaticResource customerData}” Path=”LastName” > <Binding.ValidationRules> </Binding> </TextBox.0” Name=”lastName” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”120” > <TextBox. Önceki adımda eklediğiniz bağlama tanımını değiştirin ve aşağıda gösterildiği gibi Binding. customerData nesnesinin LastName özelliği ile ilişkilendiren eşdeğer bağlama ve bağlama kuralını ekleyin: <TextBox Height=”21” Margin=”210. 9. Kayda değer birşey olmamalı. 10. . 6. foreName metin kutusu kırmızı bir çerçeve ile belirgin hale gelir.Text> </TextBox> Bir bağlamanın ValidationRules öğesi ile kullanıcı bu denetimde veri girdiğinde uygulamanın gerçekleştirmesi gereken doğrulamayı belirleyebilirsiniz. File menüsünde Save’i tıklayın.ValidationRules> <ExceptionValidationRule/> </Binding.74.

OK’i tıklayın ve sonra title açılan kutusunu tıklayın. özel durumun metnini görüntülemek için geçerli denetimin ToolTip özelliğini ayarlar. Aşağıdaki alıştırmada bunu nasıl yapacağınızı göreceksiniz. İleti kutusunda. foreName metin kutusundan lastName metin kutusuna geçerseniz ve daha sonra da hiçbir şey yazmadan title açılan kutusuna geçerseniz doğrulama gerçekleşmez. Formu kapatın ve Visual Studio 2008’e geri dönün. Menüler gerçekte formun parçası olarak ele alınmaz (farklı olarak işlenirler). Errors)[0].Resources> <cust:Customer x:Key=”customerData” /> <Style x:Key=”errorStyle” TargetType=”Control”> <Style. Sadece bir şeyler yazdığınızda ve sonra sildiğinizde doğrulama çalışır. XAML bölmesinde Window.HasError özelliğinin ne zaman true olarak ayarlandığını saptayan bir tetikleyici içerir.ErrorContent}” /> </Trigger> </Style. Sadece title açılan kutusunu (ya da başka bir denetimi) tıkladığınızda odak dışına çıkılır ve doğrulama meydana gelir. bu nedenle bir menü öğesi seçtiğinizde form üzerinde başka bir denetime geçmiş olmazsınız ve bu yüzden metin kutusu henüz odak dışına çıkmamıştır. Bu problemi daha sonra ele alacaksınız.Triggers> </Style> </Window. foreName ve lastName metin kutuları başlangıçta boştur. Sadece bir denetimdeki girilen değerle ilgili bir problem olduğunu vurgulamak yerine anlamlı bir hata iletisini nasıl görüntüleyebiliriz? Özel durum tarafından üretilen iletiyi yakalayabilir ve formda başka bir yerde görüntüleyebilirsiniz.Path=(Validation. Denetimin bağlama doğrulama kuralı bir özel durum oluşturursa bu meydana gelir. n Özel durum iletilerine bir stil ekleyin 1. Tetikleyici. denetimin Validation. doğrulamanın sadece metin kutusu odak noktasından çıktığında meydana gelmesidir.Bölüm 24 Doğrulamayı Gerçekleştirmek 479 11. CustomerForm. Burada gösterilen bağlama .Self}.Resources öğesine aşağıdaki stili ekleyin: <Window.xaml dosyasını görüntüleyen Design View penceresinde.HasError” Value=”True”> <Setter Property=”ToolTip” Value=”{Binding RelativeSource={x:Static RelativeSource. Bu da sadece kullanıcı form üzerindeki başka bir denetime odaklandığında olur. Şimdi lastName metin kutusu etrafında kırmızı çerçeve belirir. Ayrıca. Bu noktada şu iki soruyu sorabilirsiniz: n Neden form her zaman kullanıcı metin kutusuna bir değer girmeyi unuttuğu zaman bunu saptamıyor? Yanıt.Triggers> <Trigger Property=”Validation.Resources> Bu stil. 12.

> . tümü kendi iletilerini üretir.Self} bağlama kaynağı geçerli denetime başvurur ve (Validation.. Name=”foreName” .. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.” (Müşterinin adını girin) iletisini görüntüleyen bir Ekran İpucu belirmelidir: Bu ileti.. 5.Errors)[0]. “Specify a forename for the customer... 6..480 Kısım IV Windows Uygulamaları ile Çalışmak sözdiziminin ayrıntılı açıklaması bu kitabın kapsamı dışındadır. Aşağıdaki gibi. Form belirdiğinde. girdiğiniz adı silin ve daha sonra tekrar title açılan kutusunu tıklayın. . </TextBox> <TextBox Style=”{StaticResource errorStyle}” . fakat {Binding RelativeSource={x:Static RelativeSource. Başlıklar listesini gizlemek için Title açılan kutusunu tekrar tıklayın ve daha sonra fare işlecini foreName metin kutusu üzerinde bırakın.. 2. foreName metin kutusunu tıklayın. İlk ileti genellikle en önemlisidir). > . Customer sınıfının ForeName özelliğine eklediğiniz özel durum tarafından oluşturulur. Name=”lastName” . </TextBox> 3.. (Bir özel durum başka özel durumlar oluşturabilir. Not foreName metin kutusunun içeriğini gerçekten sildiğinizden emin olun.. foreName metin kutusu kırmızı renk çerçeve ile belirgin hale gelecektir.. 4. foreName ve lastName metin kutularına adınızı yazın ve sonra title açılan kutusunu tıklayın. foreName ve lastName metin kutusuna aşağıda gösterildiği gibi errorStyle stilini uygulayın: <TextBox Style=”{StaticResource errorStyle}” ..ErrorContent bağlama yolu bu bağlama kaynağında bulunan ilk özel durum iletisini ToolTip özelliği ile ilişkilendirir..

Aşağıda gösterildiği gibi.Bölüm 24 Doğrulamayı Gerçekleştirmek 481 7.Male)) { retVal = (proposedTitle.Mr)) ? true : false. Hala çözülmesi gereken bazı problemler var. private Gender gender. Customer. Aşağıda gösterildiği gibi Customer sınıfına özel (private) yöntemi ekleyin: class Customer { . private Title title.. Listeyi gizlemek için Title açılan kutusunu tekrar tıklayın ve sonra fare işlecini lastName metin kutusu üzerinde bırakın ve “Specify a last name for the customer” (Müşterinin soyadını girin) araç ipucunun belirdiğini doğrulayın. private bool checkTitleAndGender(Title proposedTitle. 8. enum Title { Mr. Gender proposedGender) { bool retVal = false. Ms } enum Gender { Male. Customer sınıfına title ve gender özel (private) alanlarını ekleyin: class Customer { private string foreName. 2.. } Customer sınıfının Title ve Gender özelliklerini belirlemek için bu numaralandırmaları kullanacaksınız.Equals(Title. if (proposedGender.cs dosyasını görüntüleyen Code and Text Editor penceresine geçin. aşağıda gösterildiği gibi. Customer sınıfının üstündeki dosyaya. } . } 4. 3. Miss.. Title ve Gender numaralandırmalarını ekleyin.. private string lastName.Equals(Gender. lastName metin kutusunu temizleyin ve sonra Title açılan kutusunu tıklayın.. Formu kapatın ve Visual Studio 2008’e dönün. Female } class Customer { . Fakat müşteriye hitap şekli ve cinsiyetini nasıl doğrulayacağınızı gördükten sonra bu problemi çözeceksiniz. Mrs. . Müşteri hitap şekli ve cinsiyetini doğrulamak için özellikler ekleyin 1..

if (!checkTitleAndGender(this.gender = value. aksi takdirde iki nokta üst üste (:) işaretinden sonrası değerlendirilir ve sonuç olarak kullanılır.Female)) { retVal = (proposedTitle.title. aksi durumda false döndürür. } set { this. Aşağıdaki biçime sahiptir: boolean deyimi ? true sonucu : false sonucu Boolean deyimi değerlendirilir. bu yöntem true döndürür. soru işareti (?) ve iki nokta üst üste (:) arası değerlendirilir ve tüm deyimin sonucu olarak kullanılır. } } Bu yöntem. 5. this.Mr)) ? false : true. proposedTitle ve proposedGender parametrelerindeki değerleri inceler ve tutarlı olması için bu parametreleri test eder.Equals(Gender. Eğer true sonucu verirse.. Title özelliğinin türü Title numaralandırma ve Gender özelliğinin türü de Gender numaralandırmadır: class Customer { . Customer sınıfına aşağıda gösterilen Title ve Gender özelliklerini ekleyin.Equals(Title.482 Kısım IV Windows Uygulamaları ile Çalışmak if (proposedGender. } set { this. value)) .gender)) { throw new ApplicationException( “The title must match the gender of the customer”). } } } public Gender Gender { get { return this.. if (!checkTitleAndGender(value.title = value.title.gender. } return retVal. public Title Title { get { return this. Not Bu yöntemde kullanılan üçlü işlemciye (? ve : ile gösterilen) aşina olmayabilirsiniz. Yoğunlaştırılmış if … else ifadesi gibi çalışır. proposedTitle ve proposedGender parametrelerindeki değerler tutarlı ise.

Gender özelliğini Gender. form üzerindeki male ve female seçenek düğmeleri ve title açılan kutusunu bu yeni özelliklere bağlamaktır. Neyse ki. title açılan kutusunun Text özelliğini.. İlk olarak.ForeName + “ “ + this.Bölüm 24 { Doğrulamayı Gerçekleştirmek 483 throw new ApplicationException( “The gender must match the title of the customer”). public override string ToString() { return this. . Customer sınıfına ToString yöntemini ekleyin: class Customer { .Female olarak ayarlamalısınız. bunun gibi işlemleri gerçekleştirmek için bir çevirici sınıfı belirleyebilirsiniz. Aşağıda gösterildiği gibi. form tarafından yaratılan Customer nesnesinin Title özelliğine bağlamanız gerekir. Text özelliği string türündedir. WPF tarafından gerçekleştirilen bağlama mekanizması ile. } } Verinin doğru olduğunu doğrulamak için müşteri bilgilerini kaydederken görüntülemek için bu yöntemi kullanacaksınız. Her bir seçenek düğmesinin IsChecked özelliğini (bir boolean değerdir).Title..Gender. Gender özelliğini Gender. çok sayıda küçük sorunlar olduğunu anlarsınız. bir boolean değer ve Gender değer arasında dönüştürme yapmak için bir çevirici sınıfı yaratabilirsiniz fakat ayrıca hangi iki seçenek düğmesinin tıklandığını da göstermeniz gerekir. Neyse ki. Bu seçenek düğmelerinden birini tıkladığınızda Gender özelliğini ayarlamış olursunuz fakat her durumda farklı bir değere ayarlarsınız.ToString(). Bir sonraki aşama. Customer nesnesinin Gender özelliğine (Gender türüne sahiptir) bağlamanız gerekir. 6. Title özelliği de Title (bir numaralandırma) türündedir.Male olarak ayarlamalısınız.“ + this. title ve gender alanlarının eşleştiğini doğrulamak için checkTitleAndGender yöntemini çağırır ve alanlar eşleşmiyorsa bir özel durum oluşturur. male seçenek düğmesinin IsChecked özelliği true olarak ayarlanmışsa. Bağlamanın çalışması için string ve Title değerlerini birbirine çevirmeniz gerekir.LastName + “ . İkinci problem de benzer bir problemdir. female seçenek düğmesinin IsChecked özelliği true olarak ayarlanmışsa. Yine. } } } } Bu özelliklerin set erişimcileri.ToString() + “ “ + this. Bununla birlikte. Microsoft’un WPF ekibi bunu iyi düşünmüştür ve hangi seçenek düğmesinin tıklandığını size gösterecek olan bir çevirici yöntemine parametre geçirebilirsiniz. biraz düşünürseniz.

IValueConverter arabirimini uygulamak zorunda olan kendi sınıflarına aittir. return title. aşağıda gösterilen Convert yöntemini ekleyin: public class TitleConverter : IValueConverter { public object Convert(object value.) Bu yöntemden dönüş değeri form üzerindeki özelliğe bağlı veridir. Çevirici sınıflar ve yöntemler yaratın 1. ValueConversion özniteliği parametreleri form (string) tarafından görüntülenen değerin türünü ve sınıftaki (Title) uygun özellikteki değer türünü belirler. Bu ad alanında IValueConverter arabirimi tanımlanır. } } Convert yönteminin imzası IValueConverter arabirimi tarafından tanımlanır. bu nedenle parametreyi kullanmaya kalkmadan önce uygun türe dönüştürmeniz gerektiğine dikkat edin.CultureInfo culture) { Title title = (Title)value. Convert yöntemi bir Title değeri bir string’e dönüştürür. value parametresi. Bu durumda. value parametresinin bir object olarak geçirildiğine. bir öznitelik örneğidir. object parameter. sınıftaki dönüştüreceğiniz değerdir. using System.Globalization. dosyanın üst kısmına aşağıdaki using ifadesini ekleyin. 2. Bir öznitelik bir sınıf için tanımlayıcı metaveri bilgisi sağlar.Windows. Customer.Data. typeof(Title))] public class TitleConverter : IValueConverter { } Sınıfın üst kısmında köşeli parantezler içindeki metin. Type targetType. İlerleyen bölümlerde özniteliklerle ilgili daha fazla örnek göreceksiniz. [ValueConversion(typeof(string).484 Kısım IV Windows Uygulamaları ile Çalışmak Çevirici yöntemler. Design View penceresindeki WPF tasarımcı gibi araçlar tarafından. bir sınıfa başvurduğunuzda sınıfı doğru olarak uyguladığınızı doğrulamak için ValueConversion özniteliği kullanılır.cs dosyasında. Bu arabirim iki yöntem tanımlar: bağlama için veri sağlayan sınıftaki özellik tarafından kullanılan türü form üzerinde görüntülenen türe dönüştüren Convert yöntemi ve form üzerinde görüntülenen türü sınıf tarafından istenen türe dönüştüren ConvertBack yöntemi. TitleConverter sınıfına. 3.ToString(). (Şimdilik diğer parametreleri ihmal edebilirsiniz. Aşağıda gösterilen TitleConverter sınıfını dosyaya ekleyin. . System.

Type targetType.CultureInfo culture) { string radioButtonId = (string)parameter.Miss.CultureInfo culture) { Title retVal = Title. Customer.Bölüm 24 Doğrulamayı Gerçekleştirmek 485 4. sınıf form üzerindeki seçenek düğmelerine uygun olarak Gender değerler ve Boolean değerler arasında dönüşümü yapacaktır. . 5. Type targetType. System.Globalization. TitleConverter sınıfından sonra.Globalization. Gender gender = (Gender)value.Mrs. break. object parameter. bool retVal = false. public object ConvertBack(object value. switch ((string)value) { case “Mr” : retVal = Title. Aşağıda gösterilen ConvertBack yöntemini TitleConverter sınıfına ekleyin: public class TitleConverter : IValueConverter { . break. } return retVal. aşağıda gösterilen GenderConverter sınıfını ekleyin: [ValueConversion(typeof(bool).. GenderConverter sınıfına aşağıda gösterilen Convert yöntemini ekleyin: public class GenderConverter : IValueConverter { public object Convert(object value. 6. } } ConvertBack yönteminde. object parameter.. sınıf için uygun türe dönüştüreceğiniz değerdir.Miss. case “Mrs” : retVal = Title. typeof(Gender))] public class GenderConverter : IValueConverter { } Bu defa. Bu durumda. break.Mr. System.cs dosyasına. case “Miss”: retVal = Title.Ms. ConvertBack yöntemi veriyi string’den (açılan kutudaki Text özelliğinde görüntülenir) uygun Title değere dönüştürür. value parametresi şimdi formdaki. break. case “Ms” : retVal = Title.

return retVal.Female)) retVal = true. Yani. value parametresi Gender.Male. if (String. Anlaşılması gereken önemli nokta. “Female”)) return Gender. parameter parametresi “Male” ise. male seçenek düğmesi için “Male” parametresi ve female seçenek düğmesi için “Female” parametresini belirteceksiniz. onu temizleyemez..486 Kısım IV Windows Uygulamaları ile Çalışmak if (String. value parametresini kontrol etmeniz gerekmez çünkü her zaman true olacaktır. “Female”) && gender.CultureInfo culture) { if (String.Male)) retVal = true. value parametresi Gender. Bir formdaki çeviriciye başvurduğunuzda. public object ConvertBack(object value. parameter parametresine dayanarak yalnızca Gender değerini döndürmeniz gerekir.Equals(Gender. } } Bu yöntem son derecede basittir. System. Type targetType. Bir seçenek düğmesi yalnızca aynı grupta başka bir seçenek düğmesi seçildiğinde temizlenir.Equals(radioButtonId. 7. yöntem parameter parametresini kullanacaktır. yöntem aynı mantığı kullanır.Female. “Male”) && gender. Sonraki alıştırmada.Equals(Gender. kullanıcı düğmeyi sadece seçebilir. çevirici yönteminin sadece kullanıcı form üzerindeki değeri değiştirdiğinde çağrılmasıdır.. Bir sınıfta aynı özelliğe birden fazla denetimin bağlanması gerekiyorsa. müşteri nesnesi de bayan (female) olur ve yöntem true döndürür.Equals(radioButtonId. müşteri nesnesi erkektir (male) ve yöntem false döndürür. . Seçenek düğmesi için. Çevirici yöntemi hangi denetimin çağırdığını belirlemek için bu parametreyi kullanabilirsiniz. } } Bu durumda. GenderConverter sınıfına aşağıda gösterilen ConvertBack yöntemini ekleyin: public class GenderConverter : IValueConverter { . ek bir veri belirtebilirsiniz. bu yararlıdır. object parameter. parameter parametresi “Female” iken. seçenek düğmelerinin forma bağlanması için kod eklediğinizde.Equals((string)parameter.Globalization.Male ise. else return Gender.Female değerini içeriyorsa.

ValidationRules> <ExceptionValidationRule /> </Binding. genderConverter nesnesini çevirici yöntemleri sağlayan kaynak olarak belirleyin ve ConverterParameter özelliğini “Male” olarak ayarlayın. title açılan kutusu tanımını bulun ve errorStyle stili kullanarak denetimi biçimlendirin. 2. XAML bölmesinde.> <ComboBox.Resources> 3. </ComboBox.0.xaml dosyasını görüntüleyen Design View penceresine dönün... errorStyle stilini uygulayın. Başka bir kaynak olarak.IsChecked> <Binding Source=”{StaticResource customerData}” Path=”Gender” Converter=”{StaticResource genderConverter}” ConverterParameter=”Male”> <Binding.Text> <Binding Source=”{StaticResource customerData}” Path=”Title” Converter=”{StaticResource titleConverter}” > <Binding. çevirici yöntemlerini sağlayan nesne olarak titleConverter kaynağını belirleyen XAML kodu ekleyin: <ComboBox Style=”{StaticResource errorStyle}” .Text> </ComboBox> 4. açılan kutunun Text özelliğini customerData nesnesindeki Title özelliğine bağlamak için aşağıda gösterilen. Name=”title” . <RadioButton Style=”{StaticResource errorStyle}” Height=”16” Name=”male” Width=”120” Margin=”0.ValidationRules> </Binding> </ComboBox.. </Window.Items> <ComboBox. genderConverter anahtar değeri ile birlikte GenderConverter nesnesi ekleyin: <Window. Açılan kutu öğeleri listesinden sonra. CustomerForm..0” > Male <RadioButton.ValidationRules> <ExceptionValidationRule /> </Binding.ValidationRules> ..20... pencereye kaynak olarak bir TitleConverter nesnesi ekleyin ve titleConverter’ın anahtar değerini belirtin. male seçenek düğmesinin tanımını değiştirin.. Aşağıdaki kodda gösterildiği gibi.Bölüm 24 Doğrulamayı Gerçekleştirmek 487 Formdaki açılan kutu ve seçenek düğmeleri denetimlerini Customer sınıfındaki özelliklere bağlayın 1.Items> .Resources> <cust:Customer x:Key=”customerData” /> <cust:TitleConverter x:Key=”titleConverter” /> <cust:GenderConverter x:Key=”genderConverter” /> . seçenek düğmesi tanımından IsChecked=”True” özelliğini kaldırın ve customerData nesnesinin Gender özelliğine IsChecked özelliğini bağlamak için XAML kodunu ekleyin. aşağıda gösterildiği gibi.

male ve female denetimlerinin bağlanma özelliklerini sorgulayabilmeliydi.NET Framework’ün geçerli sürümündeki hatadan dolayı gereklidir. temizlenen seçenek düğmeleri de bağlantılarını kaybeder ve bu düğmeleri tekrar seçerseniz doğrulama artık çalışmaz. Bununla birlikte. saveCustomer_Click yöntemindeki kodu aşağıdaki gibi değiştirin: private void saveCustomer_Click(object sender.488 Kısım IV Windows Uygulamaları ile Çalışmak </Binding> </RadioButton.xaml.TextProperty). “Saved”). Bu durumda. } B