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

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

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

.

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

.

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

2. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. Sırasıyla Kısım I. uygulama dosyalarını kurun. II ve III’deki bölümleri çalışın. 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.xx Eğer Giriş Şu adımları izleyin . Ö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. 2. V ve VI’yı deneyiminiz ve ilginizin belirlediği ölçüde tamamlayın. 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. II ve III’deki bölümleri çalışın. uygulama dosyalarını kurun. Windows-tabanlı uygulamalar oluşturmak hakkında daha fazla bilgi için. C++ ya da Java gibi nesneyönelimli bir programlama dilinden geçiş yapıyorsanız 1. 2. 5. Belirli konular hakkında bilgiye ulaşmak için kitap dizini ya da içindekiler bölümünü kullanın. 4. . Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde tanımlandığı gibi. 2. 4. Kısım IV’ü okuyun. Visual Basic 6’dan geçiş yapıyorsanız 1. Kısım IV. uygulama dosyalarını kurun. 3. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. fakat C# konusunda yeniyseniz. Alıştırmalar üzerinde çalıştıktan sonra kitaba başvuruyorsanız 1. 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. Kısım IV. Web uygulamaları ve Web hizmetleri hakkında bilgi edinmek için Kısım VI’yı okuyun. Web uygulamaları ve Web hizmetleri hakkında bilgi edinmek için Kısım VI’yı okuyun. Bir sonraki “Uygulama Dosyalarını Kurmak ve Kullanmak” bölümünde anlatıldığı gibi. Kısım V’i okuyun. 6. 3. uygulama dosyalarını kurun. 1. 1. Veritabanına erişim hakkında bilgi için. Nesne-yönelimli programlama konusunda yeniyseniz C gibi yordamsal programlama dillerine aşina iseniz. 3. V ve VI’yı tamamlayın. Windows uygulamaları oluşturmak ve veritabanı kullanmak hakkında bilgi edinmek için. Kısım IV ve V’i okuyun. Deneyiminiz ve ilginizin belirlediği kadar. Sırasıyla Kısım I. 2.

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

xxii Giriş Önemli Windows XP kullanıyorsanız. Dosyalar ve derslerdeki adım-adım komutlar.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. CD-ROM sürücünüze takın. Kod Örnekleri Bu kitap ile birlikte verilen CD. Kitabın arka kapağının iç yüzünde bulunan CD’yi paketinden çıkararak. Bu. otomatik olarak açılmalıdır. Not Son kullanıcı lisans anlaşması.exe’yi çift tıklayın. ayrıca uygulayarak öğrenmenizi sağlayacak. yeni bilgileri kavramak ve hatırlamanın kolay ve etkili bir yoludur. alıştırma ile ilgili olmayan dosyaları yaratmak için zaman harcamayacaksınız. Eğer açılmazsa. n Microsoft Visual Studio 2008 Standard Edition. alıştırmaları yaparken kullanacağınız kod örneklerini içerir. Kod Örneklerini Kurmak Kod örneklerini ve gerekli yazılımı bilgisayarınıza kurmak için aşağıdaki işlem basamaklarını izleyin. Kod örneklerini kullanarak. 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. 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. . masaüstündeki Bilgisayarım klasörünü ya da Başlat menüsünü açın. Böylece alıştırmalarda kod örneklerini kullanabilirsiniz. Windows Vista işletim sisteminin kullanıcı arayüzündeki ve Windows Vista’nın güvenlik yönetimindeki farklılıklardır. biraz farklı görünebilir. bu kitapta tanımlanan bazı iletişim kutuları ve ekran görüntüleri. Bunun nedeni. önce CD-ROM sürücünüzün simgesini ve daha sonra StartCD. 1.

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

her satırı form üzerindeki metin kutusunda görüntülemek için while deyimini kullanır. SwitchStatement Bölüm 5 WhileStatement Bu proje. bir kaynak dosya içeriğini her defasında bir satır okuyarak. Bölüm 4 Selection Bu proje. önceki projedeki kodu yeniden inceleyecek ve kodun yöntemlerle nasıl yapılandırıldığını araştıracaksınız. karakterleri XML gösterimlerine çevirmek için switch deyimini kullanır. Bu proje. Bölüm 8 Parameters Bu program. Bölüm 2. takvim tarihini göstermek için struct tipi tanımlar. . ortak kurucular. böylece program artık başarız olmaz. 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. Ayrıca. yöntemler ve özel alanlar ile sınıflarınızı tamamlamanın temellerini ele alır. try ve catch anahtar sözcükleri uygulamayı daha güçlü yapar. kendi yöntemlerinizi yazmak. kendi sınıflarınızı tanımlamak. 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. Bu proje.xxiv Giriş Proje Bölüm 3 Methods DailyRate Tanım Bu projede. Bölüm 9 StructsAndEnums Bu proje. Bölüm 7 Classes Bu proje. 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. Bu basit program. ondalık sayıyı. “Değişkenler. değer parametreleri ve başvuru parametreleri arasındaki farklılığı araştırır. sekizlik gösterimine dönüştürmek için do deyimini kullanır. DoStatement Bölüm 6 MathsOperators Bu proje. ref ve out anahtar sözcüklerinin nasıl kullanılacağını gösterir. 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. Daha sonra.

C# kaynak dosyasını okumak ve dosya içeriğini çeşitli türde jetonlara (tanımlayıcılar. using deyimi ile kodun nasıl özel duruma karşı güvenli yapılacağını gösterir. görüntü otomatik olarak güncellenir. Bölüm 17 Delegates Bu proje. operatörler vb. ana penceresinin boyutunu görüntülemek için birkaç özellik kullanan basit Windows uygulaması sunar. sembolleri zengin metin kutusunda renkli sözdiziminde göstermek için anahtar arabirimlerden sınıfları türetir. temsilci geri çağrılarını kullanarak dijital biçimde zamanı görüntüler. eldeki oyun kartlarını gruplandırmak için ArrayList koleksiyon sınıfını kullanır. Bölüm 15 WindowProperties Bu proje. pencereyi yeniden boyutlandırdıkça. 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. sanal yöntemin nasıl tanımlanacağını gösterir. int tipi için bir dahili yöntemin nasıl yaratılacağını gösterir. ayrıca. . 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. 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. Bölüm 14 UsingStatement Bu proje. Daha sonra. Bölüm 13 Tokenizer Bu proje. devralmayı kullanarak basit bir taşıt hiyerarşisi yaratır. Bölüm 5. Bölüm 12 Vehicles ExtensionMethod Bu proje. olaylar kullanarak kod basitleştirilmiştir.) sınıflandırmanın benzetimini yapmak için sınıflar ve arabirimlerin hiyerarşisini kullanır. anahtar sözcükleri. Kullanıcı. “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. Bu proje.Giriş xxv Proje Bölüm 10 Cards Bölüm 11 ParamsArrays Tanım Bu proje. Bu proje. Bu proje. bir tamsayı değerini 10’luk tabandan farklı bir tabana çeviren yöntem sağlayan. Ayrıca. Kullanım örneği olarak.

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

Uygulama ayrıca. Bölüm 30 NorthwindServices Bu proje.NET formunun nasıl kullanılacağını gösterir.NET Web sitesi oluşturur.Giriş xxvii Proje Bölüm 26 Suppliers Tanım Bu proje. Northwind veritabanında. Şu Anda Yüklü Programlar (Currently Installed Programs) listesinden. Bölüm 27 Litware Bu proje. 4. ASP. WPF formu üzerindeki kontrollerde. Kod örneklerini kaldırmak için yönergeleri izleyin. 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. Program Ekle/Kaldır’ı (Add or Remove Programs) açın. Denetim Masası (Control Panel) . 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.NET Web formundan ADO. Kod Örneklerini Kaldırmak Bilgisayarınızdan kod örneklerini kaldırmak için aşağıdaki adımları izleyin. Products tablosundaki veriye Internet üzerinden uzaktan erişimi sağlayan. Bölüm 29 Northwind Bu proje. kullanıcının doğrulanması için Form tabanlı güvenliğin nasıl kullanılacağını gösterir. . 2. Kaldır’ı (Remove) tıklayın. bir önceki bölümdeki Litware projesinin genişletilmiş sürümüdür ve ASP. 1. ö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.NET Web uygulamasında kullanıcı girişinin nasıl onaylandığını gösterir. 3. Bölüm 28 Litware Bu proje. Windows Communication Foundation Web servis uygulamasıdır. Microsoft Visual C# Step by Step’i seçin.

Microsoft Press. yukarıdaki adreslerden Microsoft yazılım desteği verilmediğini unutmayın. Sokak No: 4 Yenimahalle/Ankara www.tr Posta adresi: Arkadaş Yayınevi Yuva Mahallesi 3702. kitaplar ve kitap ekinde verilen CD’ler için aşağıdaki Web sitesinde kullanıcı desteği sağlar: http://www.tr Lütfen. E-posta adresi: info@arkadas. lütfen.com. Microsoft Knowledge Base makalesine eklenecektir. Düzeltmeler ya da değişiklikler toplandıkça. e-posta yoluyla ya da posta yoluyla bize iletin.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.microsoft. .arkadas.com/learning/support/books/ Sorular ve Yorumlar Kitapla ya da yanında verilen CD ile ilgili soru. yorum ya da fikirleriniz varsa ya da yukarıdaki sitede cevabını bulamadığınız sorularınız varsa.com.

49 Bölüm 4 . . . . . . . . . . . . . 67 Bölüm 5 . . . . Yöntemler Yazmak ve Kapsam Uygulamak . . . . . . . . . 3 Bölüm 2 . . . . . . . . . . . . . . . . . . . 29 Bölüm 3 . . . . . . . . .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 . . . . . . . . . . . . . . 103 Kısım I 1 . . . . . . Hatalar ve Özel Durumları Yönetmek . . . İşleçler ve Deyimlerle Çalışmak . . . . . . . Karar İfadeleri Kullanmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C#’a Hoşgeldiniz . Bileşik Atama ve Yineleme İfadeleri Kullanmak . . . . . . . . . . . 85 Bölüm 6 . . . . . . . . . . . . . . . . . . . . . Değişkenler. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.

nasıl kullandığını anlayacaksınız.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#. C. 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. bu size tam olarak yardımcı olacak kitaptır! Kısım I’de. özel durumları incelikle ve kolay kullanılır biçimde. C# sözdizimini kısa sürede kavrayabilirsiniz. grafiksel kullanıcı arayüzünden çok. Not Konsol uygulaması.NET Framework mimarisinde önemli rol oynar ve kimileri C dilinin UNIX ortamında oynadığı rolle karşılaştırma yapar. C# temellerini öğreneceksiniz. Ayrıca if gibi seçim deyimlerini ve while gibi yineleme deyimlerini nasıl kullanacağınızı öğreneceksiniz. 3 . komut satırı penceresinde çalışan uygulamadır. Microsoft. C#. Farklı programlama dilleri kullanılarak derlenmiş modülleri tek bir modül gibi birleştiren projeler bile oluşturabilirsiniz. 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. Son olarak. Microsoft’un güçlü bileşen-yönelimli dilidir. 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. Umarız. Visual Studio 2008 programlama ortamını başlatacak ve konsol uygulamasını nasıl yaratacağınızı öğreneceksiniz. C#’ın hataların üstesinden gelmek için. İlk alıştırmada. Visual Studio 2008 Ortamını Kullanarak Programlamaya Başlamak Visual Studio 2008. C# sözdizimini oldukça aşina bulacaksınız. C++ ya da Java gibi dilleri biliyorsanız. Yöntemleri nasıl yazacağınızı ve yöntemlere bağımsız değişken göndermeyi göreceksiniz. sadece ayraç ve noktalı virgülleri doğru yere koymanız gerekir. Diğer dillerde programlamaya alışkınsanız.

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

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

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

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

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

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

) yazın. Main yöntemi şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console. Kapalı parantez ve noktalı virgül (.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. 5. IntelliSense. Parantez içindekini yazdıktan sonra. } 6. Her üye adının solunda. Main yöntemi şimdi şu şekilde görünmelidir: static void Main(string[] args) { Console.WriteLine(). İmleci hareket ettirin ve WriteLine yönteminden sonra parantez arasında tırnak işaretleri ile birlikte “Hello World” dizesini yazın.) koyduğunuzda. o sınıfın her bir üyesinin adını görüntüler. parantezi kapatmak kolay unutulabilir. } İpucu İçindekileri yazmadan önce parantez ve süslü parantezleri içi boş olarak ( ) ve { } şeklinde yazın. IntelliSense Simgeleri Sınıf adından sonra nokta işareti (. 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) . üyenin türünü gösteren bir simge bulunur.WriteLine(“Hello World”).

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

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

cs dosyasının üstünde bin ve obj olarak adlandırılmış girişler görünür. 3. Debug olarak adlandırılmış bir diğer klasör ortaya çıkar. Program. Solution Explorer’da. uygulamayı oluşturmak ve hata ayıklamak için kullanılan bazı diğer dosyalar ile birlikte. 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. uygulama çalışır fakat komut penceresi sizin bir tuşa basmanızı beklemeden aniden kapanır. Start Without Debugging’ı tıklayın. Solution Explorer’da.Bölüm 1 C#’a Hoşgeldiniz 13 2. . Bu girişler. bunun için herhangi bir kod yazmazsınız. bin and obj dosyalarına karşılık gelir. 5. Komut penceresi açılır ve program çalışır. Programı Debug menüsü üzerindeki Start Debugging komutunu kullanarak başlattıysanız. 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. Not “Press any key to continue…” uyarısı Visual Studio tarafından oluşturulmuştur. Komut penceresi kapanır ve Visual Studio 2008 programlama ortamına dönersiniz. 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). 4. Visual Studio bu klasörleri yaratır ve bu klasörler. doğrudan proje klasöründeki (Microsoft Press\Visual CSharp Step by Step\ Chapter 1\TextHello\TextHello). Debug menüsünde. programın uygulanabilir sürümünü içerirler. Not Ayrıca. bin girişinin solundaki artı işaretini (+) tıklayın. Uygulamanızı oluşturduğunuzda.

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

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

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

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

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

Visual Studio’nun Design View penceresini kullanmayı istemiyorsanız ya da Visual Studio’ya erişime sahip değilseniz. Visual Studio 2008 geçerli uygulamanızı kapatır ve yeni bir WPF uygulaması yaratır. . XML dilini biliyorsanız. 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. Aşağıdaki resimde gösterildiği gibi. 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. OK’i tıklayın. Name alanına WPFHello yazın. WPF Application simgesini tıklayın.Bölüm 1 C#’a Hoşgeldiniz 19 3. 4. XAML dili de size aşina gelmelidir. 5. Microsoft. XAML. formun XAML tanımını içeren başka bir pencere ile birlikte. New Project iletişim kutusunda. 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. Windows SDK ile birlikte yüklenmiş olan XAMLPad adı verilen bir XAML düzenleyicisi sağlar. bir XAML tanımı yazarak bir WPF formunu tam olarak tanımlayabilirsiniz. Aşağıdaki alıştırmalarda.

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

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

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

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

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

System. System.Linq.Configuration. App.Generic. System.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. Bu dosyayı çift tıklarsanız. Solution Explorer’da.Windows. XAML kodunda bir özellik StartupUri olarak adlandırılır ve aşağıda gösterildiği gibi. Design View penceresi “Intentionally Left Blank”(“Özellikle Boş Bırakılmış”) iletisini görüntüler. Main yönteminin nerede olduğunu ve uygulama çalıştığında görüntülenen formun nasıl elde edildiğini merak edebilirsiniz.xaml dosyasına başvurur: Solution Explorer’da.xaml adında bir diğer kaynak dosyaya dikkat etmiş olmalısınız. Bu noktada. fakat dosya XAML tanımına sahiptir. System. Window1. aşağıdaki kodu içerdiğini görürsünüz: using using using using using using System. . App.xaml dosyasına bitişik olan artı işaretini (+) tıklarsanız. Main yönteminin programın başlayacağı noktayı tanımladığını hatırlayın.Collections.Data.cs dosyası olduğunu göreceksiniz.xaml. Bu dosyayı çift tıklarsanız. ayrıca Application. System.

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

Button öğesini inceleyin. Adınızla sizi selamlayan ileti kutusu görünür. İleti kutusu kapanır. 9. 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. Formun XAML tanımını gösteren aşağıdaki sekmede. adınızı metin kutusuna yazın ve daha sonra OK’i tıklayın. Formu kapatın. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsü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. 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. Debug menüsünde. Form göründüğünde. Start Without Debugging’i tıklayın. Exit’i tıklayın. n . İleti kutusunda OK’i tıklayın. fakat hiçbirşeyi değiştirmemeye dikkat edin. 7.Bölüm 1 C#’a Hoşgeldiniz 27 5. Save iletişim kutusu görürseniz. 8.

Visual Studio projects location kutusunda. Console Application seçin. OK’i tıklayın . OK’i tıklayın. Location kutusunda proje dosyaları için bir dizin seçin. Projects and Solutions seçeneğini tıklayın. F6 Ctrl+F5 . Visual C# 2008 Express Edition kullanarak yeni grafiksel uygulama yaratmak Uygulama oluşturmak Uygulamayı çalıştırmak Build menüsünde. File menüsünde New Project iletişim kutusunu açmak için New’i tıklayın. Build Solution’ı tıklayın. proje dosyaları için bir dizin belirleyin. Proje için bir ad seçin. Debug menüsünde. Proje için bir ad seçin. Console Application seçin. Options iletişim kutusunda. Proje için bir ad seçin. Proje türü olarak Visual C# seçin. 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. Şablon olarak. Projects and Solutions seçeneğini tıklayın. Şablon olarak.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. proje dosyaları için bir dizin belirleyin. File menüsünde New Project iletişim kutusunu açmak için New’i tıklayın. OK’i tıklayın. OK’i tıklayın. Şablon olarak. WPF Application seçin. Location kutusunda proje dosyaları için bir dizin seçin. Tools menüsünde Options’ı tıklayın. WPF Application seçin. Tools menüsünde Options’ı tıklayın. Options iletişim kutusunda. Proje için bir ad seçin. Şablon olarak. Start Without Debugging’i tıklayın. Visual Studio projects location kutusunda. Proje türü olarak Visual C# seçin.

aşağıdaki ifade derlenmeyecektir: Console. yöntemler hakkında daha fazlasını öğreneceksiniz. yöntemi adlandırılmış ve sıralanmış ifadeler olarak düşünün. Bu kurallar topluca sözdizimi olarak bilinir. İşleçler ve Deyimlerle Çalışmak Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n n İfadeler. C#’daki ifadeler. Fakat şimdilik. Bölüm 3. Temel veri türleri ile çalışmak. bir eylem gerçekleştiren komuttur. 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. (Karşıt olarak. değerleri değiştirmek için işleçleri kullanmayı ve iki ya da daha fazla işleç içeren deyimleri denetlemeyi öğreneceksiniz.WriteLine(“Hello World”). C#’ın sunduğu aritmetik işleçleri. Bilgi depolamak için değişkenler kullanmak. ifadelerin ne yaptığının belirtimi topluca anlambilim olarak bilinir). “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. İfadeleri Anlamak Bir ifade (statement).Bölüm 2 Değişkenler. sonundaki noktalı virgül olmadan. Artı işareti (+) ve eksi işareti (-) gibi aritmetik işleçleri kullanmak. tanımlayıcılar ve anahtar sözcükleri anlamak. Bu bölümde ise ifadeler. her ifadenin bir noktalı virgül ile bitmesi gerektiğidir. Örneğin. C# sözdizimi kurallarından biri ve en önemlisi. anahtar sözcükler ve tanımlayıcılar gibi. 29 . iyi tanımlanmış bir kurallar kümesine uymalıdır. “Yöntemler Yazmak ve Kapsam Uygulamak” bölümünde. yöntem için bir örnektir. İfadeler yöntemlerin içinde bulunurlar. 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. Bir önceki bölümde gördüğümüz Main. Microsoft Visual C# sözdiziminin ve dil yapısının öğeleriyle tanışacaksınız. Değişkenleri artırmak ve azaltmak.

Örneğin. programlarınızın çok daha kolay okunmasını ve değiştirilmesini sağlar. Anahtar Sözcükleri Tanımlamak C# dili. Anahtar sözcükler aşağıda listelenmiştir. . Kitap boyunca ilerledikçe. result%. Bunun anlamı şudur: boşluk karakteri ya da satır başı karakteri gibi boşluk karakterleri ayraç olmak dışında bir anlam ifade etmez.30 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş İpucu C#. namespace ve using verilebilir. birçok C# anahtar sözcüğünün anlamını öğreneceksiniz. Bu tanımlayıcılar anahtar sözcükler olarak adlandırılır ve her biri özel bir anlama sahiptir. Bu yaklaşım. 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). Tanımlayıcı. Bununla birlikte. C# dilinde. footballTeam$ ve 9plan geçersiz tanımlayıcılardır. Tanımlayıcıları Kullanmak Tanımlayıcılar (identifiers). Önemli C# büyük küçük harfe duyarlı bir dildir: footballTeam ve FootballTeam aynı anlama gelen tanımlayıcılar değildir. en önemli C# ifadelerinin örneklerini göreceksiniz. bir harf ile (alt çizgi harf olarak kabul edilir) başlamak zorundadır. _score. ifadelerinizi istediğiniz stilde yazabilirsiniz. “serbest biçimli” bir dildir. rakam ve alt çizgi karakterini kullanabilirsiniz. Kitapta bölümler boyunca. Diğer bir deyişle. 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. 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. programlarınızda ad alanları. sınıflar. footballTeam ve plan9 geçerli iken. 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. result. basit ve tutarlı bir görünüm stili programın okunmasını ve anlaşılmasını kolaylaştırır. Anahtar sözcüklere örnek olarak class.

aşağıdaki tanımlayıcıları kullanır. maliyet adında bir değişken yaratabilir ve malların maliyet değerini bu değişkende saklayabilirsiniz. Daha sonra. siz yazdıkça mavi renk olarak görüntülenir. Değişkeni tuttuğu değere göre adlandırabilirsiniz. Programdaki her bir değişkene. bir dükkandaki malların maliyet değerini depolamak istiyorsanız. Değişkeni. fakat mümkün olduğunca bunu yapmaktan kaçınmalısınız. yani kendi yöntemleriniz. daha önce değişkende depolanan maliyet değeri olacaktır. kullanıldıkları ortamda değişkeni benzersiz olarak tanımlayan tek ve benzersiz bir ad vermek zorundasınız. C# ayrıca.Bölüm 2 Değişkenler. 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. anahtar sözcükler. İş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. Örneğin. . bilgisayarınızın belleğinde geçici bilgi tutan bir kutu gibi düşünebilirsiniz. değişkenleriniz ve sınıflarınız için tanımlayıcı olarak bu adları kullanabilirsiniz. Bu tanımlayıcılar C# tarafından kendi kullanımı için ayrılmamıştır. maliyet değişkenine başvurduğunuzda elde edilen değer.

Bir değişkenin adını ve türünü bir tanımlama ifadesi içinde bildirirsiniz. Microsoft Visual Basic . _skor ve FutbolTakimi adlarının tümü geçerli bir değişken adıdır fakat sadece ilk ikisi önerilir. diğerini de Degiskenim olarak adlandırmayın. age adında ve int (tamsayı) değerler taşıyan bir değişkeni bildirir. Örneğin. içinde ne tür bir değişken tutacağını da belirtmelisiniz. Değişkenleri Bildirmek Değişkenler değerleri tutar. bunları gerçekleştirilmesi zorunlu öneriler olarak düşünmelisiniz. Örneğin. Her zamanki gibi. camelCase gösterim biçimi olarak bilinir). depolayabileceği ve işleyebileceği çok sayıda farklı değer türüne sahiptir: tamsayı. C#. Not Yalnızca küçük-büyük harf ayrımına bağlı olarak değişen tanımlayıcılar kullanmak. n n Adı küçük harfle başlatın. . futbolTakimi. int age.NET gibi diğer dillerle birlikte çalışan programlar yazmak istiyorsanız. çünkü çok kolay karışıklığa neden olabilir. Yalnızca küçük-büyük harf ayrımına bağlı olarak değişen tanımlayıcı yaratmayın. Bazı öneriler aşağıda listelenmiştir: n n Tanımlayıcılarda alt çizgi kullanmayın.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. skor. 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. aşağıdaki ifade. n Örneğin. kayan nokta sayısı ve karakterler dizesi gibi. ilk kelimeden sonra gelen kelimenin ilk harfini büyük yazın (Bu. Macar gösterim biçimini kullanmayın. aynı anda kullanılan iki değişkenden birini degiskenim olarak. ifade sonunda noktalı virgül yer alır. bu önerilere uymalısınız. Macar gösterim biçimine aşina olabilir. Bir değişken bildirdiğinizde. (Microsoft Visual C++ yazılım geliştiriciler. 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. Birden fazla kelimeden oluşan tanımlayıcılarda.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Neticede.648. 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. Örneğin: count++. Bununla birlikte. ve 263 değeri 9.372. şimdilik. Visual Studio 2008’den şimdi çıkmak istiyorsanız. neden bu dilde var anahtar sözcüğü gibi bir özelliğin var olmasına izin verdiğini merak ediyor olabilirsiniz. Exit’i tıklayın. İşlenenleri belirli işleçlere zorlamak için deyimlerde ayraç kullanın. ++ ya da – – işleçlerini kullanın.223. Visual Studio 2008’i çalışır halde bırakın ve Bölüm 3’e geçin.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. 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. Örneğin: System.775.483.147.854.036.Int32. ardından atama işlecini yazıp sonra da değeri hesaplayan deyimi yazın. (Dipnotlar) 1 216 değeri 65. Örneğin: int outcome. n Bir sonraki bölümden devam etmek istiyorsanız. Bununla birlikte. Bir değişkenin değerini değiştirmek Değişkenin adını sola yazın. Örneğin: outcome = 42.Parse(“42”). sonuna da noktalı virgül ekleyin. sonuna da noktalı virgül ekleyin. var anahtar sözcüğünün C#’da geçerli bir yere sahip olduğunu göreceksiniz. 231 değeri 2. string ’i int ’e dönüştürmek Önceliği geçersiz kılmak System. . bana güvenin. Save iletişim kutusunu görüyorsanız.Int32. Örneğin: myInt4 = myInt3 = myInt2 = myInt = 10. ilerleyen bölümlerin birçoğu üzerinde çalıştığınızda. 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). File menüsünde.Parse yöntemini çağırın.536.808’e eşittir. Ö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. kapalı tür gerekli olana kadar değişken türünü açık bir şekilde belirtmeye devam edeceğiz.

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

parameterList. { }. int ya da string gibi. Parametreleri. bir türün adıdır ve yöntemin işlem sonucu olarak döndüreceği bilgi türünü belirler. methodName. yöntem adları için camelCase kuralına uymalısınız. yöntem çağrıldığında çalıştırılacak olan kod satırlarıdır. method body statements (yöntem gövde ifadeleri). yöntemi çağırmak için kullanılan addır. // yöntem gövde ifadeleri buraya gelir // . Kodunuzun derlenebilmesi için tüm yöntemlerinizi bir sınıf içinde yazmanız gerekir.. Şimdilik.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. C#'ın genel yöntemleri desteklemediğine dikkat etmeliler. parametreleri virgülle ayırmanız gerekir.. örneğin. displayCustomer . int rightHandSide) { // . 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. herhangi bir tür olabilir. dönen tür yerine void anahtar sözcüğünü kullanmanız gerekir.. var anahtar sözcüğü kullanamazsınız. Örneğin. Yazdığınız yöntem iki ya da daha fazla parametreye sahip olacaksa. C++ ve Microsoft Visual Basic ile program geliştirenler. Küme parantezleri. Herhangi bir değer döndürmeyen bir yöntem yazıyorsanız.. addValues (ekleDeğerler) adı geçerli bir yöntem addır fakat add$Values geçerli bir ad değildir. 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. . önce tür adı daha sonra da parametre adı olacak biçimde. parantez içinde değişken bildiriyormuş gibi yazarsınız. Yöntem adları da değişken adlarının uyması gereken tanımlayıcı kurallarına uymalıdır. n n n Önemli C. Bu. arasında yer alırlar.

. Deyimin türü. yöntem bir int türü döndürüyorsa.. } return ifadesi. } Yöntemin bir değer döndürmediğini göstermek için void anahtar sözcüğünün kullanıldığına dikkat edin. Örneğin: void showResult(int answer) { // yanıtı görüntüle . Örneğin: int addValues(int leftHandSide. return leftHandSide + rightHandSide. programınız derlenmez. yöntem tarafından belirtilen dönüş türü ile aynı olmak zorundadır. return anahtar sözcüğünden sonra noktalı virgül yazarsınız. Diğer bir deyişle.. Her zaman bir dönüş türü belirtmeniz ya da void anahtar sözcüğünü kullanmanız gerekir. return anahtar sözcüğünden sonra. yöntem içinde bir return ifadesi yazmalısınız. Önemli Visual Basic ile program geliştirenler. yöntemin bitmesine neden olduğundan. Yönteminizin bir değer döndürmesini istemiyorsanız (diğer bir deyişle. yöntemden çıkmak için return ifadesinin farklı bir biçimini kullanabilirsiniz. dönen değeri hesaplayan deyim ve sonunda noktalı virgül yer alır. 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. int rightHandSide) { // .. return ifadesinden sonra yer alan herhangi bir ifade çalıştırılmaz (return ifadesinden sonra herhangi bir ifade yazarsanız. dönüş türü void ise).. aksi takdirde. 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). derleyici sizi uyarı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 ifadesi de int türü döndürmelidir. genellikle yöntemin sonunda yer alır. return.

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

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

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

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

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

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

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

bu kodu yazdığınızda IntelliSense bu yöntemleri göstermez. Kısayol menüsünde. Sonraki ifade. 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. Aşağıda gösterildiği gibi. 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. bu nedenle. writeFee yöntemine verilen değerin. Code and Text Editor penceresinde. . başarısızlıkla sonuçlanır. gün sayısını elde etmek için readInt yöntemini (bunu da yazacaksınız) çağırır.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 59 run yöntemine eklediğiniz kod bloğu. kodu üretmek ve düzenlemek için yararlı komutlar içeren kısayol menüsü görünür. sonuçları ekranda görüntülemek için writeFee yöntemi (yöntem yazılmıştır) çağrılır. Son olarak. Generate Method Stub Wizard kullanarak yöntemleri yazın 1. Not Henüz readDouble. Henüz uygulamayı oluşturmaya çalışmayın. 2. Generate Method Stub’ı tıklayın. writeFee ya da calculateFee yöntemlerini yazmadınız. readInt. run yöntemindeki readDouble yöntem çağrısını farenin sağ düğmesiyle tıklayın.

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

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. ifadesini aşağıdaki kod ile değiştirin: Console. yani kullanıcının klavyeden girdiği string türü değer. readDouble yöntemi kodu ile benzerdir. 7. Aşağıdaki gibi. iki parametreyi çarparak ödenecek ücreti hesaplayan aşağıdaki ifade ile değiştirin: return dailyRate * noOfDays. } 8. readInt yöntemindeki throw new NotImplementedException().Parse(line).ReadLine(). ç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. return int. Aşağıda koyu renk olarak gösterildiği gibi. Generate Method Stub Wizard.Bölüm 3 Yöntemler Yazmak ve Kapsam Uygulamak 61 5. (Elbette. uygun olmayan parametre adlarını değiştirebilirsiniz. int noOfDays) { throw new NotImplementedException(). yöntemden dönen değer türünün object olmasıdır. Bölüm 7’de object türü hakkında daha fazlasını öğreneceksiniz. bu yöntem int değeri döndürür. calculateFee yönteminin tanımlamasını. calculateFee yöntemini.) Daha ilginç olanı. Tek fark. . 9. 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. Bu kod bloğu. } 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(). int. 6. double türü döndürecek şekilde değiştirin: private double calculateFee(double dailyRate. calculateFee yöntemi oluşturulur: private object calculateFee(double dailyRate. string line = Console.Write(p).Parse yöntemi kullanılarak tamsayıya dönüştürülür. object türü sadece “bir tür” anlamındadır ve bunu yönteme kod eklerken istediğiniz tür ile değiştirmelisiniz.

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

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

yöntemin üçüncü satırında görünür. 9.) . Step Out’u tıklayın. (Console penceresi Visual Studio arkasında gizlenmiş olabilir. 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. 5. (Soldan altıncı düğme. İpucu Tekrar tekrar Debug araç çubuğundaki Step Into düğmesine basmak yerine F11 tuşuna basabilirsiniz. 8. fakat tıklamayın.) İpucu Debug araç çubuğunda Step Over’a tıklamak yerine F10 tuşuna da basabilirsiniz. bir değişkenin istenilen değerde olduğundan emin olmak için bu özelliği kullanabilirsiniz.) Bu hareket. İmleç ilk ifadeye ilerler: Console. 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.Write(p). hata ayıklayıcının çağrılan yöntemin içine adım atmasına neden olur. Debug araç çubuğunda. 6. hata ayıklama yapmadan (yöntemin içine girmeden) bir sonraki ifadenin çalıştırılmasını sağlar. Denetim Visual Studio 2008’e döner.) Bu hareket. Bu defa. Ekran İpucu görünür. (Soldaki yedinci düğme. 7. 10. line değişkeninin geçerli değerini (“525”) görüntüleyen. Sarı imleç.ReadLine yöntemini çalıştırdığından Console penceresi etkin hale gelir ve bir şeyler yazmanızı bekler. Yöntemler içinde gezinirken. Sarı imleç readDouble yönteminin parantez açma ifadesine atlar. Debug araç çubuğunda Step Over’ı tıklayın. Console penceresinde 525 yazın ve daha sonra Enter’a basın. Tekrar Step Into’yu tıklayı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. sarı imleç yok olur ve program Console. Debug araç çubuğunda Step Into düğmesini tıklayın. (Soldan sekizinci düğme. 11. Debug araç çubuğunda Step Over’ı tıklayın.

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

int rightHandSide) { . Örneğin: return leftHandSide + rightHandSide. 3). Uygulama tamamlanır ve çalışması sona erer.. 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. 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. 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. n Bir sonraki bölüme geçmek istiyorsanız Visual Studio 2008’i çalışır durumda bırakarak. Save iletişim kutusunu görürseniz. Örneğin: addValues(39.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. 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. “Karar İfadeleri Kullanmak” başlıklı Bölüm 4’e geçin. n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.. Yöntemin içine bir return ifadesi yazın. . View menüsünde Toolbars’ı işaret edin ve daha sonra Debug’ı tıklayın. Yöntemin adını ve ardından da parantez içinde gereken bağımsız değişkenleri yazın. 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. Debug araç çubuğunda Step Into’yu tıklayın ya da Debug menüsünde Step Into’yu tıklayın. Örneğin: int addValues(int leftHandSide. } 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.

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

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

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. validPercentage (geçerliYüzde) değişkenine true değeri atar. || işlecinin sonucu. && işlecinin sonucu. Boolean deyimlerinin birleşimlerinden birinin true olup olmadığını belirlemek için || işlecini kullanın. true olur. 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. invalidPercentage (geçersizYüzde) değişkenine true değerini atar: bool invalidPercentage. aşağıdaki ifade ancak ve ancak percent değeri sıfırdan küçükse veya 100’den büyükse. Üzerinde işlem gerçekleştirdiği Boolean deyimlerinden biri true ise. Bunlar koşullu mantıksal işleçler olarak bilinir. Çünkü && işleci. daha iyi okunabilir ve anlaşılırdır. Örneğin. . iki Boolean deyimini ya da değerlerini tek bir Boolean sonuçta birleştirmektir. 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. İpucu Yeni başlayanların en sık yaptıkları hata. Bu iki işlecin amacı. Örneğin. ikinci deyim. Bu ikili işleçler. bool validPercentage. Örneğin. ancak ve ancak üzerlerinde işlem gerçekleştirdiği her iki değer de true ise true’dur.Bölüm 4 Karar İfadeleri Kullanmak 69 Koşullu Mantıksal İşleçleri Anlamak C#. >= ve <= işleçlerine göre önceliğe sahiptir Bununla birlikte. invalidPercentage = (percent < 0) || (percent > 100). 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. validPercentage = (percent >= 0) && (percent <= 100). 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.

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

if ifadesini kullanabilirsiniz. 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. .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.

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

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

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

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

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

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

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

} 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.. else if (day == 1) dayName = “Monday”. bu nedenle controllingExpression bunlardan sadece biri ile eşleşir. default : statements break. Not Her constantExpression değeri benzersiz olmak zorundadır.. else dayName = “Unknown”. Bu durumlarda çoğu zaman.. else if (day == 3) . isteğe bağlı olan default etiketinin altındaki ifadeler çalışır.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”. Uygulama break ifadesine kadar çalışır. . programınızı daha etkin ve kolay okunur yapmak için basamaklanmış if ifadelerini bir switch ifadesi olarak yeniden yazabilirsiniz. Hiçbir constantExpression değeri. 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. controllingExpression değeri. . else if (day == 2) dayName = “Tuesday”. switch İfadelerinin Sözdizimini Anlamak Bir switch (switch. case constantExpression : statements break.. controllingExpression değerine eşit değilse. bu noktada switch ifadesi biter ve program switch ifadesinin kapanan parantezinden sonraki ilk ifade ile devam eder. case ve default anahtar sözcüklerdir) ifadesinin sözdizimi aşağıdaki gibidir: switch ( controllingExpression ) { case constantExpression : statements break.

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

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

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

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

<. && işlecini kullanın.. If (seconds == 59) { seconds = 0. minutes++. If (inRange) process(). break. <=. > ya da >= işlecini kullanın. Örnek answer == 42 Age >= 21 bool inRange. || işlecini kullanın.. break. Bir if ifadesi ve bir blok kullanın. outOfRange = (number < lo) || (hi < number). } switch (current) { case 0: .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. Değişken türü olarak bool anahtar sözcüğünü kullanın. } Bir denetim deyiminin farklı değerlerini farklı ifadelerle ilişkilendirmek Bir switch ifadesi kullanın.. Bir if ifadesi kullanın.. . inRange = (lo <= number) && (number <= hi). case 1: . break... default : .

Bir değişkenin değerine 42 eklemek istiyorsanız. aşağıdaki ifade answer değişkenine 42 ekler. atama işleci ile toplama işlecini birleştirebilirsiniz. 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. for ve do yineleme ifadelerini yazmak. 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. Örneğin. Bu ifade çalıştıktan sonra. 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. Console. ifadeleri seçime bağlı olarak çalıştırmak için if ve switch yapılarının kullanımını öğrendiniz. Örneğin.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. answer değişkeninin değeri. Bu durumlarda değişkenin değerini güncellemek için kullanmanız gereken bazı özel atama işleçlerini de öğreneceksiniz.WriteLine(answer + 42). Bileşik Atama İşleçleri Kullanmak Aritmetik işleçler kullanarak yeni değerler yaratmayı görmüştünüz. 85 . yineleme işleminin kaç kez yinelendiğini denetlemek için bir değişkeni güncellemeniz gerekir. 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. answer değişkeninin değerini 42 olarak değiştirmek için atama işleci kullanır: answer = 42. Aşağıdaki ifade. “Karar İfadelerini Kullanmak” başlıklı Bölüm 4’te. Bir değişken kullanarak. önceki değerinin 42 fazlası olur: answer = answer + 42. Bir do ifadesinin içine girmek ve değişkenleri değişirken izlemek. while. Bu bölümde.

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

while ifadesinin sözdizimi aşağıdaki gibidir: while ( booleanExpression ) statement Boolean deyimi değerlendirilir ve true ise ifade çalıştırılır. sözdizimi kuralı bakımından if ifadesi ile birçok benzerlik gösterir (aslında. . 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. while ifadesi. daha sonra Boolean deyimi yeniden değerlendirilir. gerçekleştirilen yineleme sayısını kontrol eder. Deyimin değeri hala doğru ise ifade yeniden çalıştırılır ve Boolean deyimi yeniden değerlendirilir. bu ifadeleri parantez içinde blok halinde gruplandırmalısınız. anahtar sözcük dışında sözdizimi aynıdır): n n n n Deyim. Boolean deyimi false olana kadar.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. ifade çalışmaz. Not while döngüsündeki i değişkeni. bir Boolean deyim olmalıdır. while ifadesinin denetimi altında birden çok sayıda ifade gerçekleştirmek istiyorsanız. 0’dan 9’a kadar olan değerleri yazan bir while ifadesi şöyledir: int i = 0. Boolean deyiminin sonucu ilk işlemde yanlış olursa. yani while ifadesinden çıkıldığı zamana kadar bu işlem sürer. Aşağıdaki alıştırmada. Bu örnekte. Boolean deyiminin değerini hatalı yapacak ve döngüyü sonlandıracak bir ifade eklemek. i++. Uygulama daha sonra while ifadesinden sonraki ilk ifade ile devam eder. } Tüm while ifadeleri bir noktada sonlanmalıdır. 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. Boolean deyimi. başlangıç seviyesindeki programcıların yaygın olarak yaptığı bir hatadır. i++ ifadesi bunu yapmaktadır. Bu. parantez içinde yazılmalıdır.WriteLine(i). programın sonsuza kadar çalışmasına neden olur. while (i < 10) { Console.

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

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

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

for ifadesini kullanışlı bulacaksınız. i < 10. Boolean deyimi yeniden değerlendirilir ve böyle devam eder. Başlatma işleminin bir defa gerçekleştiğine. 0’dan 9’a kadar tamsayıları gösteren while döngüsünü. Boolean deyimini kullanmazsanız. 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.i++) { Console. Boolean deyiminin sonucu true ise. Boolean deyimi.WriteLine(i). ifade yeniden çalışır.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. .WriteLine(“somebody stop me!”). } Başlatma. varsayılan olarak true kabul edilir. Bu üç kısımdan herhangi birini unutmak daha zor olacağından. denetim değişkenini güncelleme) ifade Daha önce gösterilen. Koşul hala true ise. for döngüsü kullanarak yeniden yazabilirsiniz: for (int i = 0. ifade çalışır. } . for ifadesinin üç bölümünden istediğinizi kullanmayabilirsiniz. Denetim değişkeni güncellenir ve Boolean deyimi yeniden değerlendirilir. 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. Aşağıdaki for ifadesi sonsuza kadar çalışacaktır: for (int i = 0. i++) { Console. denetim değişkeni güncellenir. for ifadesinin sözdizimi aşağıdaki gibidir: for (başlatma. döngünün en başında bir defa gerçekleşir.

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

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

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

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

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

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

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

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

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

while (amount != 0).Bölüm 5 Bileşik Atama ve Yineleme İfadeleri Kullanmak 101 20. 23. Save iletişim kutusu görünürse. ”205” ve “5205”. Visual Studio 2008 programlama ortamına dönmek için formu kapatın. amount değeri şimdi 0’dır. bu nedenle amount != 0 deyimi false olacak ve do döngüsü sonlanacaktır. Sarı ok. do döngüsünün sürdürme koşulu üzerindedir. amount değeri 0 ve current değeri “5205” olur. n . 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. Tahmin edileceği gibi. 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”. 21. 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. Döngünün dördüncü yinelemesinin sonunda. 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. Hata ayıklayıcı aşağıdaki ifadeyi çalıştırır: while (amount != 0). Step Into’yu tıklayın. Debug araç çubuğundaki Continue düğmesini tıklayın. 22. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. 24. do döngüsü sonlanır ve sarı ok showStepsClick yönteminin sonundaki kapanan paranteze hareket eder. 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. ”05”.

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. Bileşik çıkarma işlecini kullanın. Örneğin: for (int i = 0. } Ya da for ifadesi kullanın. while ifadesi kullanın. } while (i < 10). i < 10. i++) { Console. i++. Örneğin: variable -= amount. i++. while (i < 10) { Console. Örneğin: int i = 0. Örneğin: variable += amount. Örneğin: int i = 0.WriteLine(i).WriteLine(i).WriteLine(i). . do { Console. } İfadeleri bir ya da daha fazla sayıda tekrar tekrar uygulamak do ifadesi kullanın.

UNIX gibi eski sistemler tarafından benimsenmiş tipik yaklaşım. Bununla birlikte. Bu oldukça zahmetlidir. piller biter.Bölüm 6 Hatalar ve Özel Durumları Yönetmek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n n n n try. catch ve finally ifadelerinin nasıl kullanılacağını öğreneceksiniz. Hatalarla Başa Çıkmak Bazen kötü şeylerin meydana gelmesi hayatın gerçeğidir. C# ve birçok diğer nesne-yönelimli programlama dilleri hataları bu yolla ele almaz. Program çalışırken hemen hemen her aşamasında hatalar meydana gelebilir. özel durumları bilmeniz gerekir. Daha sonra. öyleyse hataları çözmek için onları nasıl fark edeceksiniz? Yıllar boyunca. 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. 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. Bu bölümün sonunda. Bunun yerine. 103 . Bir finally bloğu kullanarak. özel durumlar (exceptions) kullanırlar. yöntemin başarılı olup olmadığını görmek için genel değişkeni denetlerdiniz. değişkenler bildirmek. 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. 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. tornavidalar hiçbir zaman bıraktığınız yerde olmaz ve uygulamalarınız önceden bilinmeyen şekilde davranır. “C# Dilini Anlamak” başlıklı Kısım 2’de kullanacağınız çok sağlam bir C# temeline sahip olacaksınız. Birçoğu programcı olarak sizin kontrolünüz dışında olan çok sayıda nedenden dolayı hatalar meydana gelebilir. değerler yaratmak için işleçleri kullanmak. her yöntem çağrıldıktan sonra. checked ve unchecked anahtar sözcüklerini kullanarak tamsayı taşmalarını denetlemek. Lastikler patlar. önceki bölümler bazı şeylerin ters gidebileceği olasılığını hesaba katmadı. “Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş” başlıklı Kısım 1’in bu son bölümünde. Yöntemler yazmak ve okumak. çok sayıda mekanizma geliştirilmiştir. 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. catch ve finally ifadelerini kullanarak özel durumları işlemek.

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

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

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

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

Visual Studio 2008’i başlatın. Debug. Left Operand metin kutusuna geçerli olmayan bir metin girin. Bir form açılır. programın şu anki durumunun sağlamlıktan ne kadar uzak olduğunu gösterecek. Debug düğmesini tıklayın dendiğinde Debug the program bağlantısını tıklayın. 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. (Windows Vista değil.108 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş Özel bir durum meydana geldiğinde. ö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. Debug menüsünde Start Without Debugging’i tıklayın. Left Operand metin kutusuna John yazıp Calculate düğmesini tıklayın. Yukardaki iletişim kutusunu görürseniz. Bir iletişim kutusunda. Debug düğmesi görünmeyecektir. bir try bloğundan sonraki genel catch işleyicisinin üstüne yerleştirmelisiniz. 3. Aşağıdaki alıştırmada bir try bloğu yazacak ve bir özel durumu yakalayacaksınız. “Değişkenler. Bir try/catch ifadesi yazın 1. Not Microsoft Visual C# 2008 Express Edition kullanıyorsanız. 4. Send Error Report ve Don’t Send düğmeleri olan farklı bir iletişim kutusu göreceksiniz. Farklı aritmetik işleçleri göstermek için kullanılmıştı. Exception için işleyici bulunursa.) . Bu çözümü. Programı kapatmak için Don’t Send düğmesini tıklayın. İşleçler ve Deyimlerle Çalışmak” başlıklı Bölüm 2’de görmüştünüz. işlenmemiş özel durum oluştuğu rapor edilir. 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. genel catch işleyici eşleşecektir. Özel catch işleyicilerinin hiçbiri özel durumla eşleşmezse. Windows XP kullanıyorsanız. daha özel catch işleyicilerini. Left Operand metin kutusunda girdiğiniz metnin uygulamanın başarısız olmasına neden olduğu. FormatException işleyicisi hiçbir zaman çalışmayacaktı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. Bu nedenle. Bunun anlamı şudur: FormatException için işleyiciden önce. 2.

Possible Debuggers listesinden MathsOperators – Microsoft Visual Studio: Visual Studio 2008’i seçin ve Yes’i tıklayın: 6. Visual Studio 2008 de kullansanız. Visual Studio 2008 kullanıyorsanız. Debug’ı tıklayın. Left Operand metin kutusuna John yazın ve Calculate’i tıklayın. Visual Studio Just-In-Time Debugger iletişim kutusundaki. Visual C# 2008 Express Edition kullanıyorsanız. 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: . Close Program’ı tıklayın. 7. Debug menüsünde Start Debugging’i tıklayın.Bölüm 6 Hatalar ve Özel Durumları Yönetmek 109 5.

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

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

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

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

Çarpma işlemi şimdi denetimlidir ve sessizce hatalı bir değer döndürmek yerine bir OverflowException oluşturur. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. İ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. } İpucu Bu catch işleyicinin mantığı. 8. 10.Message. . Multiplication’ı seçin ve Calculate’i tıklayın. monthName(2) “February” (Şubat) değerini döndürür.114 Kısım I Microsoft Visual C# ve Microsoft Visual Studio 2008’e Giriş 6. return ifadesini aşağıdaki gibi düzenleyin: return checked(leftHandSide * rightHandSide). Örneğin. 11. calculateClick yöntemini bulun. ancak bunu yapmadan önce C# dili . monthName(1) “January”(Ocak). FormatException catch işleyicinin mantığı ile aynıdır. Bununla birlikte.Text = oEx.NET Framework sınıf kütüphaneleri. kendinizinkini kolayca yaratabilirsiniz. Visual Studio 2008 programlama ortamına dönmek için Quit’i tıklayın. 9. 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. Dönen değer denetlenmiş olacak şekilde. Ö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. 7. calculateClick yöntemindeki FormatException catch işleyicisinin hemen sonrasına aşağıdaki catch işleyiciyi ekleyin: catch (OverflowException oEx) { result. Birçok durumda bu sınıflardan birinin sizin özel durumunuza uyduğunu ve onu kullanabileceğinizi göreceksiniz. 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. (Uyan bir tane bulamazsanız. Left Operand metin kutusuna 9876543. Right Operand metin kutusuna da 9876543 yazın. bunun gibi durumlar için tasarlanmış çok sayıda özel durum içerir.

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

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

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

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

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

.MaxValue. özel durum oluşsa dahi her zaman çalıştıklarından emin olmak Kodu bir finally bloğunun içine yazın. } 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: try { .. checked { number++. Örneğin: throw new FormatException(source). Örneğin: try { . } finally { // her zaman çalışır } . Örneğin: int number = Int32... } catch (Exception ex) { . } Bazı kodların. checked anahtar sözcüğü kullanı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.. } catch (FormatException fEx) { .. } Belirli bir özel durumu yakalamak Belirli özel durum sınıfını yakalayan bir catch işleyici yazın..

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

.

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

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

matematik sabitleri içeren alanlar ve matematik hesaplamaları gerçekleştirmek için yöntemler içerir. Bununla birlikte. // Bir Circle değişkeni yarat // Başlat new anahtar sözcüğünün kullanımına dikkat edin. Örneğin: Circle c. pi sayısı değerini (3. int ya da float türünde bir değişkeni başlatırken.14159265358979323846) içerir. Önemli sınıf ve nesne terimlerini karıştırmayın. olağan yöntemler (Area gibi) ve alanlar (radius gibi) içerir. ç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. Circle d. Bölüm 8’de ele alınan nedenlerden dolayı. 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. i = 42. Math. . C#’da değişkenlere sabit sınıf değerleri atamak için bir sözdizimi yoktur. Şimdilik. Sınıf gövdesi. sadece new anahtar sözcüğünün.Bölüm 7 Sınıflar ve Nesneleri Yaratmak ve Yönetmek 125 Not Math (Matematik) sınıfı. Circle sınıfının kullanımı. aşağıdaki gibi sınıfın bir örneğini. aslında burada hemen hemen yeni bir sözdizimi yok. 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. daha önce gördüğünüz diğer türlerin kullanımı ile aynıdır. c = new Circle(). c = new Circle(). Bunun bir nedeni. basit olarak bir değer atardınız: int i. Bununla birlikte. bir sınıf içindeki değişkenlere alan adı verildiğini hatırlayın. Sınıf bir türün tanımıdır. bir sınıfın yeni bir örneğini (daha çok nesne olarak adlandırılır) yarattığını bilmeniz yeterlidir. (42‘nin Circle eşdeğeri nedir?) Bir diğer neden ise. o türün program çalıştığında yaratılan bir örneğidir.PI alanı. 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. Daha önce. d = c. bu göründüğü kadar kolay değildir. Nesne ise. “Değerler ve Başvuruları Anlamak” başlıklı Bölüm 8’de ayrıntılarıyla incelenmiştir).

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

sadece. işletim sisteminden bir parça bellek alanı alması. } // varsayılan kurucu .) private tanımlayıcılar küçük harfle başlamalıdır. çalışma zamanı. iki public sınıf üyesi bildirmeyin. sınıf ile aynı adda. bir sınıfın örneğini yarattığınızda otomatik olarak çalışan özel bir yöntemdir. (İlk olarak Pascal dilinde kullanılmıştır. Bu nedenle private bir kurucu adı da büyük harfle başlamalıdır. Bu sistem. camelCase adlandırma kuralı olarak bilinir. sınıf tanımlamasını kullanarak nesneyi kurmak zorundadır. 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. Area. derleyicinin ürettiği varsayılan kurucu gerçekte hiçbir şey yapmaz. derleyici sizin için otomatik olarak varsayılan kurucu üretir. 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.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ı.) Kendi varsayılan kurucunuzu kolayca yazabilirsiniz. Kurucu (constructor). sınıf üyelerinin erişilebilirliğine dayanır: n public tanımlayıcılar büyük harfle başlamalıdır. Kurucularla Çalışmak Bir nesne yaratmak için new anahtar sözcüğü kullandığınızda. Bildirirseniz. bir değer döndürmeyen public bir yöntem ekleyin. 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 olduğundan “r” ile (“R” değil) başlar. Örneğin. Örneğin. Her sınıf. (Bununla birlikte. Çalışma zamanının. bir kurucuya sahip olmak zorundadır. Sınıf ile aynı ada sahiptir ve parametreler alabilir fakat bir değer döndürmez (void bile). Siz bir kurucu yazmazsanız. 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. public olduğundan “A” ile (“a” değil) başlar. Bu sistem. Önemli Adlarının arasındaki tek fark küçük/büyük harf kullanımı olan. radius.

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

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

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

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

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

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

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

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

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

(Statik olmayan alanlar her bir nesne oluşumu için yereldir. private int radius. bu nedenle NumCircles++. Bununla birlikte. public static int NumCircles = 0. bildiriminde static anahtar sözcüğünü kullanmaz ama yine de static’dir.NumCircles). statik olmayan (örnek) yöntemlerde ise ilk önce yöntemi çağırmak için bir nesne yaratmanız gerekir.. Bununla birlikte. Circle. bir alanı sadece. numaralandırma. } Tüm Circle nesneleri aynı NumCircles alanını paylaşır.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. (ya da bazen static değişkenler olarak adlandırılır). Bir const alanı. alan tanımlarken de static anahtar sözcüğünü kullanabilirsiniz. Paylaşılan Bir Alan Yaratmak Bir önceki bölümde bahsedildiği gibi. static alanlar genellikle class alanları olarak adlandırılmazlar. } public Circle(int initialRadius) // aşırı yüklenmiş kurucu { radius = initialRadius. 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. NumCircles++. Örneğin: Console. Circle nesnesi yerine Circle sınıfını belirterek NumCircles alanına erişirsiniz. bu kitabın kapsamı dışındaki nedenlerden dolayı.WriteLine(“Number of Circle objects: {0}”. tek bir sınıftan yaratılmış olan tüm nesneler tarafından paylaşılan bir alan yaratabilirsiniz.) Aşağıdaki örnekte. 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. Bu özellik ile.. Circle sınıfındaki NumCircles (DaireSayısı) adındaki static alan. her yeni örnek yaratıldığında aynı veriyi bir artırır. } . int ya da double gibi sayısal bir tür ya . sadece static alanlar olarak adlandırılır. NumCircles++. İpucu static yöntemler aynı zamanda class yöntemler olarak da adlandırılır. ifadesi.

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

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

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

var anahtar sözcüğünün. myAnonymousObject.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.) Şimdilik. 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”. sadece kullanışlı olduklarını bilin.Age}. Age = 42 }. myAnonymousObject nesnesini var anahtar sözcüğünü kullanarak açık şekilde yazarak bildirebilirsiniz: var myAnonymousObject = new { Name = “John”.WriteLine(“Name: {0} Age: {1}”. Age = 43 }. Bu kulağa garip geliyor belki ama kitabın sonraki bölümlerinde göreceğiniz bazı durumlarda. Derleyici. 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. özellikle de sorgu deyimleri kullandığınızda gerçekten oldukça kullanışlıdır. 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. deyimin türü derleyicinin anonim sınıf için ürettiği ad olur. Anonim Sınıflar Anonim sınıf (anonymous class). new anahtar sözcüğünü kullanarak. anonim sınıfların önemi budur! Bununla birlikte. myAnonymousObject. . Bir anonim sınıf tanımladığınızda. myAnonymousObject (benimAnonimNesnem) değişkeninin türü ne olmalıdır? Yanıtı siz bilmezsiniz. 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. Nesnedeki alanlara. derleyici sınıf için kendi adını üretir fakat bunu siz bilmezsiniz. Bu sınıf. (“Sorgu Deyimleri Kullanarak Bellek Verisinde Sorgulama Yapmak” başlıklı Bölüm 20’de sorgu deyimlerini öğreneceksiniz. alana verdiğiniz başlangıç değeri türünden alanların türünü ortaya çıkarır. Age = 42 }. Farklı değerlerle aynı anonim sınıfının diğer örneklerini de yaratabilirsiniz: var anotherAnonymousObject = new { Name = “Diana”.Name. aşağıdaki gibi noktalama işaretleri kullanarak erişebilirsiniz: Console. 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. Bu durumda.

iki anonim sınıf örneğinin aynı türde olup olmadığını bulmak için adları. bu nedenle her iki değişken de aynı anonim sınıfın örnekleridir.. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. sonra da açılan ve kapanan parantezleri ekleyin. aşağıdaki gibi bir atama ifadesi uygulayabilirsiniz anlamına gelir: anotherAnonymousObject = myAnonymousObject. 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. Sınıfın yöntemleri ve alanları bu parantezler içinde bildirilir. 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 Point { . türleri. Not Bu atama ifadesi. Anonim sınıfın içeriğinde oldukça fazla kısıtlama vardır. 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. sayıları ve alanların sırasını kullanır. Bu. Save iletişim kutusu görünürse. Bu durumda. myAnonymousObject ve anotherAnonymousObject değişkenleri aynı sayıda..142 Kısım II C# Dilini Anlamak C# derleyicisi. public alanların tümüne başlangıç değeri atanmak zorundadır. Anonim sınıflar sadece public alanlar içerebilir. ardından sınıfın adını. aynı adda ve aynı sırada alanlara sahiptir. static olamazlar ve herhangi bir yöntem belirleyemezsiniz. “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. } . beklediğiniz şeyi yapmayabilir.

Örneğin: class Point { public Point(int x.... public const double PI = . } } Bir kurucu çağırmak new anahtar sözcüğünü kullanın ve uygun parametrelerle kurucuyu belirtin. Örneğin: int pointsCreatedSoFar = Point. ardından bir nokta koyup static alanın adını yazın.. Örneğin: Point origin = new Point(0.PI * radius * radius.Örneğin: class Point { .. 0). } } Bir static yöntemi çağırmak Bir static alan bildirmek Sınıfın adını yazın. private static int objectCount.. Örneğin: double area = Math. . Örneğin: class Point { public static int ObjectCount() { .. Bir static yöntem bildirmek Yöntemin bildiriminden önce static anahtar sözcüğünü yazın.ObjectCount(). static anahtar sözcüğünü yoksayın.. Alanın bildiriminden önce static anahtar sözcüğünü yazın.. Örneğin: class Math { . int y) { . } Bir const alan bildirmek Alanın bildiriminden önce const anahtar sözcüğünü yazın. } Bir static alana erişmek Sınıfın 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. ardından bir nokta koyup yöntemin adını yazın.

.

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

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 adında int türü değişken tanımladığınız ve 42 değeri atadığınız zamanki durumu düşünün.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. refc değişkeni c değişkeni ile aynı Circle nesnesine başvuracaktır. refc ve c değişkeninin her ikisi de ona başvurur. // i’deki verinin kopyasını içerir i++. Aşağıdaki grafik her iki örneği de gösterir. Peki derleyici. diğeri copyi değişkeni için. c değişkeni Circle nesnesine başvurabilir. Özellikle. refc adında başka bir Circle bildirirseniz. bu değişken de Circle nesnesine başvurabilir. copyi ve i aynı değeri taşıyor olsa da. // i’yi bildirin ve başlatın int copyi = i. i değişkeni ile aynı değeri (42) tutacaktır. Buna kod içinde bakalım: int i = 42. c değişkenini refc’ye atarsanız. Sadece bir Circle nesnesi vardır. Circle refc = c. i değerini değiştirirseniz. Bununla birlikte. 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. c değişkenini Circle olarak bildirdiğinizde. yine de 42 değerini içeren iki bellek bloğu vardır: biri i değişkeni için. . copyi adında bir başka int değişkeni bildirirseniz. 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 alıştırmada bu farkı inceleyeceksiniz. copyi değeri değişmez. Circle nesnesindeki @ işareti bellekteki adrese başvuruyu gösterir: Burada açıklanan fark oldukça önemlidir. // 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.

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

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. 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. Programı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Pass sınıfına Reference adında bir public static yöntem ekleyin. Pass. Code and Text Editor penceresinde Pass. geçirilen bağımsız değişkenin kopyasını kullanır ve orijinal bağımsız değişken hiçbir şekilde etkilenmez. Parametreleri güncelleyen Pass. } 11. Uygulamayı kapatmak için Enter tuşuna basın.cs dosyasını görüntüleyin.Reference yöntemini çağırın.cs dosyasını görüntüleyin. param değişkenine 42 değerini atamalıdır: public static void Reference(WrappedInt param) { param. Pass.WriteLine(i).WriteLine yöntemine çağrı ile.Number değerini yazın.148 Kısım II C# Dilini Anlamak Pass. n n . Console. Console. Reference yönteminin gövdesi. bağımsız değişken olarak wi geçirin. Şimdi sınıf içine alınmış int parametresi geçirdiğinizde neler olduğunu göreceksiniz.Number = 42. Konsola iki defa 0 yazıldığından emin olun. Konsola wi. } } 10. 9. Pass. 8.Value yöntemi içindeki atama ifadesi.Value(i). 7. } 6. Bu yöntem param adında tek bir WrappedInt parametresi almalı ve dönüş türü void olmalıdır.Value yöntemine çağrıdan önce ve sonra Console. Code and Text Editor penceresinde Program. Code and Text Editor penceresinde WrappedInt. Tamamlanmış Entrance yöntemi şu şekilde görünmelidir: static void Entrance() { int i = 0.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.cs dosyasını görüntüleyin.WriteLine(i).

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

çöp toplamanın pahalı bir işlem olduğunu bilmeniz önemlidir. .. Aşağıdaki kod örneğinde. Circle copy = new Circle(99).0. 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. Bu durumda. if (copy == // what goes here?) copy = c. “Çöp Toplama ve Kaynak Yönetimini Kullanmak” başlıklı Bölüm 14’te çöp toplamayı ayrıntılı olarak öğreneceksiniz.. Circle copy.. // copy ve c aynı nesneye başvurur Buradaki if ifadesinin amacı. Sınıf gibi bir başvuru değişkenine başlangıç değeri atamak için. Bir değişken. çalışma zamanı çöp toplama olarak bilinen işlemi gerçekleştirerek belleği geri kazanabilir. // Başlatılmamış !!! . Fakat bu iyi bir programlama uygulaması değildir ve kodunuzda problemlere neden olabilir. 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). değişken bir başvuruya sahip değilse. . bir nesneye başvurmasını isteyeceğiniz bir durumla mutlaka karşılaşacaksınız: Circle c = new Circle(42). Bu çok iyidir fakat ya gerçekten yeni bir nesne yaratmak istemezseniz? Belki değişkenin amacı. 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). copy = c. // 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. Kod genelde aşağıdaki gibi görünür: int i = 0..150 Kısım II C# Dilini Anlamak Null Değerleri ve Null Türlerini Anlamak Bir değişken bildirdiğinizde. var olan bir nesneye bir başvuru sağlamaktır. double d = 0. Şimdilik. 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. başka bir yerde değişkene başlangıç değeri de atanabilir. her zaman başlangıç değeri atamak iyi bir fikirdir. Örneğin.

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

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

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

} static void Main() { int arg. } out parametresine yöntem tarafından bir değer atanması gerektiğinden. Bir yönteme out parametresi geçirdiğinizde. bağımsız değişkenine başlangıç değeri atanmadan yöntemi çağırmanıza izin verilir. çünkü DoWork yöntemi param değişkenine bir değer atar. yöntemin parametreye başlangıç değeri atamasını istediğiniz zamanlar olabilir. Bununla birlikte. Örneğin. yöntem bu parametreye bir değer atamak zorundadır. static void DoWork(out int param) { param = 42. ref anahtar sözcüğünü kullandığınızda olduğu gibi. Bunu out anahtar sözcüğü ile yapabilirsiniz. parametreye yaptığınız herhangi bir değişiklik. yöntemi çağırmadan önce bir ref parametresine değer atanıp atanmadığını kontrol eder. Bir parametrenin önüne out anahtar sözcüğünü ekleyebilirsiniz. out anahtar sözcüğü. böylece parametre. bağımsız değişkenin diğer adı olur. Bunun nedeni. ref anahtar sözcüğüne benzer. out anahtar sözcüğü output (çıktı) kelimesinin kısaltmasıdır.154 Kısım II C# Dilini Anlamak başlangıç değeri verilmediğinden kod derlenmeyecektir. aynı zamanda bağımsız değişkenin önüne de out anahtar sözcüğünü yazmak zorundasınız. 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. } out Parametreleri Yaratmak Derleyici. Bir out parametresine bir bağımsız değişken geçirdiğinizde. orijinal bağımsız değişkene de yapılır. Console. 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). çü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. .WriteLine(arg).

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

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

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

c ve o değişkeninin her ikisi de aynı Circle nesnesine başvurur.Object için takma ad) olması aslında aynı öğenin bellekteki iki farklı görünüşünü sağlar: Circle c.Object önemli bir sınıftır. . c değişkeninin türünün Circle olması ve o değişkeninin türünün object (System. c için ve param için ayrılmış olan bellek otomatik olarak yığına geri verilir. System ad alanındaki Object sınıfıdır.Object sınıfının önemini tam olarak anlamak için. Aşağıdaki örnekte. Kodunuzda.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. Oluşturursa. Circle nesnesi için ayrılmış bellek yeniden kullanılabilir hale getirilir ve kurucudan dönen değer null olur . object o.Object yazabilirsiniz. c = new Circle(42). ikisi de aynı şeydir.NET Framework’deki en önemli başvuru türlerinden biri. C#. Çalışma zamanı. tüm sınıfları System.158 Kısım II C# Dilini Anlamak Not Circle kurucusu da bir özel durum oluşturabilir. System. System. Yöntem sona erdiğinde. Daha kestirmedir ve sınıflar için eşanlamlı diğer anahtar sözcüklerle (System. System. parametreler ve yerel değişkenler kapsam dışına çıkar. o = c. Şimdilik.Object sınıfını kullanabileceğinizi kabul edin.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. “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. object anahtar sözcüğünü kullanabilir ya da 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 sınıfının takma adı olarak object anahtar sözcüğünü sağlar.Object yerine object anahtar sözcüğünü kullanmayı tercih edin. İpucu System.Object Sınıfı Microsoft .

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

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

“Generics’e Giriş” başlıklı Bölüm 18’de kutulamaya alternatif işlemleri göreceksiniz.. object o = wi. if (o is WrappedInt) . Kutulama kullanışlıdır fakat bilinçsiz kullanımı programın performansını ciddi olarak bozabilir. dönüştürme ile eşleşmiyorsa. Buradaki kilit nokta. 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. Verileri Güvenli Olarak Dönüştürmek Dönüştürme işlemini kullanarak. Bu özel durumu yakalamalı ve işlemelisiniz. sizin fikrinize göre. kutulama ve kutulamayı kaldırma işlemlerinin pahalı işlemler olduğunu unutmayın. çalışma zamanı bir önceki bölümde tanımlandığı gibi InvalidCastException özel durumunu oluşturur. ö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. Bellekteki nesne türü. . Bununla birlikte. “sizin fikrinize göre” tümcesidir.. Denetleme için gereken miktar nedeniyle ekstra öbek belleği ayırmak gerektiğinden. 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. 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().Bölüm 8 Değerleri ve Başvuruları Anlamak 161 Daha sonraki örneklerde kutulama ve kutulamayı kaldırmayı kullanacaksınız. C# derleyici.

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

y). Tüm bu problemlerden kaçınmak için C#’a başvuru değişkenleri eklenmiştir. Gerçekten istiyorsanız. birçok var olan sistemlerde. C#’da işaretçileri kullanmaya devam edebilirsiniz. işaretçinin başka bir işleme ait olan belleğe başvurup başvurmadığını denetlemekte başarısızdır.. . &y). 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. aşağıdaki ifadeleri ve & işlecini kullanabilirsiniz: int *pi. Ayrıca. C ve C++ dillerini öğrenen programcıların karşılaştıkları önemli sorunlardan biri işaretçilerin kullandığı sözdizimini anlamakla ilgilidir. Bazı ortamlar (Microsoft Windows olmayan).. ne zaman & kullanılacağı oldukça kafa karıştırmaktadır. Aşağıda gösterildiği gibi. işaretçilerin kötü yönetimiyle sonuçlanan güvenlik çatlakları da vardır. y = 100. 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. pi işaretçisini kullanarak i tamsayı değişkenini işaret etmek için. ancak kodu güvensiz (unsafe) olarak işaretlemeniz gerekir.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. Örneğin. int i = 99. } Console. pi = &i. 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. unsafe { swap (&x. 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. y is now {1}”. } . * işlecinin aritmetikteki çarpma işleminin yanı sıra en az iki anlamı vardır ve ne zaman *. Bu kod i değişkeninin değerini 100 olarak güncelleştirir çünkü pi. x.WriteLine(“x is now {0}. İşaretçilerle ilgili diğer bir konu. gizli kalması gereken veriyi tehlikeye atabilme riski meydana getirir. i değişkeni ile aynı bellek konumuna işaret etmektedir.

Bu konu Bölüm 14’te ayrıntılı olarak anlatılmaktadır. . Bir başvuru türü değişkeni kopyalamak Yalnızca kopyayı oluşturun. 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. 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. 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. 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.Object sınıfının bir değişkeninin değere (42 gibi) atanmasının. Değişken değer türü olduğundan.164 Kısım II C# Dilini Anlamak public static unsafe void swap(int *a. 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. System. int copyi = i. aynı değerin iki kopyasını elde edersiniz. Save iletişim kutusu görünürse. 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. Circle refc = c. int *b) { int temp. Örneğin: Circle c = new Circle(42). 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. *b = temp. Değişken başvuru türü olduğundan aynı nesneye başvuran iki başvuru elde edersiniz. } Güvensiz kod içeren programları derlerken /unsafe seçeneğini belirtmeniz gerekir. temp = *a. Bu bölümde. Ayrıca. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Örneğin: int i = 42. *a = *b.

Console. parametreyi bağımsız değişkenin kopyası değil diğer adı yapar. DoWork(ref arg).. 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. Kutulanmış değere başvuran nesne başvurusunu değerin türüne dönüştürün. } Alternatif olarak.. Örneğin: WrappedInt wi = new WrappedInt(). Örneğin: int i = (int)o.. Örneğin: static void Main() { int arg = 42. Örneğin: int? i = null. Console. parametreyi bağımsız değişkenin kopyası değil diğer adı yapar.. } 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. Örneğin: WrappedInt wi = new WrappedInt()... } Bir değeri kutulamak Bir değerin kutulamasını kaldırmak Object türünde bir değişkeni değere atayın. Bağımsız değişkenin önüne ref anahtar sözcüğünü yazın. if (temp != null) . object o = wi. Bu.WriteLine(arg). DoWork(out arg). .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. object o = wi. Örneğin: Object o = 42. . Bu.WriteLine(arg)... WrappedInt temp = o as WrappedInt. 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. Örneğin: static void Main() { int arg = 42.

.

yaz. 0. Bir değer türü değişken. Kodda 0 tamsayı değerini kullandıysanız. Bir numaralandırma türü yaratmak ve kullanmak. Numaralandırmalarla Çalışmak Programınızda yılın mevsimlerini sunmak istediğinizi varsayalım. Bölüm 7’de. Örneğin. değerini doğrudan yığın üzerinde tutarken bir başvuru türü değişken öbek üzerindeki bir nesneye başvuruyu tutar. bu 0 değerinin ilkbaharı gösterdiği çok açık olmayacaktır. season (mevsim) adında bir int değişken bildirirseniz. C#. Fall (Sonbahar) ve Winter (Kış) 167 . Bir yapı türü bildirmek Bir yapı türü yaratmak ve kullanmak Bölüm 8’de. 2 ve 3 dışında tamsayılar atayabilirsiniz. kalıp değerleri Spring (İlkbahar). 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. kendi değer türlerinizi nasıl yaratacağınızı öğreneceksiniz. C# daha iyi bir çözüm sunar. sınıflar tanımlayarak kendi başvuru türlerinizi nasıl yaratacağınızı öğrendiniz. Summer (Yaz).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. Ayrıca çok sağlam bir çözüm de değildir. Bu sistem çalışacaktır fakat fazla sezgisel değildir. 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. sonbahar ve kışı sunmak için 0. Bu bölümde. 1. iki değer türünü destekler: numaralandırma (enumeration) ve yapı (structure). Microsoft Visual C#’da bulunan iki temel türü öğrendiniz: değer türleri ve başvuru türleri. 1. 2 ve 3 tamsayı değerlerini kullanabilirsiniz. Aşağıda. İlkbahar. Her ikisine de sırayla bakacağız.

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

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

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

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

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

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

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

Örneğin. sözdizimi açısından benzerdir fakat birkaç önemli farklılık vardır.. } Bir yapı için kendi varsayılan kurucunuzu bildirememenizin nedeni.. aşağıda Time sınıf olsaydı derlenecekti ama bir yapı olduğundan derlenmeyecektir: struct Time { public Time() { . varsayılan olmayan tüm yapı kurucularınızdaki tüm alanlara açık bir şekilde değer atamalısınız. Yani. Bir yapı için derleyici tarafından üretilmiş varsayılan kurucu her zaman alanlara 0. böylece kodunuzun verimliliğini artırmak istediğinizde sadece gerçek değerin adresini kopyalama seçeneğine sahip olursunuz. varsayılan olmayan bir kurucu sağlayarak alanlara farklı değerler atayabilirsiniz. Daha karmaşık veriler için sınıfları kullanın. aksi takdirde derleme hatası alırsınız. derleyicinin her zaman bir tane üretmesidir. } // derleme zamanı hatası . Bununla birlikte.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. 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. Bir sınıfta.. derleyici ancak siz kendi kurucunuzu yazmazsanız varsayılan bir kurucu yazar. varsayılan olmayan yapı kurucunuzda alana başlangıç değeri atamazsanız. 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.. } // derleme zamanı hatası: seconds başlatılmamış . derleyici sizin için değer atamaz. Yapı ve Sınıf Farklarını Anlamak Bir yapı ve bir sınıf.. minutes = mm. minutes.. int mm) { hours = hh. Bu farklılıkların bazılarına bakalım: n Bir yapı için varsayılan bir kurucu (parametreleri olmayan bir kurucu) bildiremezsiniz. false ya da null atar –tıpkı sınıflarda olduğu gibi. Bu varsayılan değerleri kullanmak istemiyorsanız. private int hours. Örneğin. seconds. } . Bu nedenle.

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

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

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

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

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.

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

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

// iterate remaining 10 using a foreach statement foreach (int number in numbers) // dönüştürme gerekmez { Console. i < numbers. öğe. dizin 3) numbers.. dizin 6 (10) numbers. i++) { int number = (int)numbers[i]. } 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. // değerin kutulamasını kaldıran dönüştürmeyi gör Console.Count. // şimdi 7. 99).WriteLine(number). .. Bir ArrayList kullandığınızda Count özelliğini.WriteLine(number). // ikinci parametre eklenen öğe) numbers.Remove(7).RemoveAt(6).Count-1. bir dizideki öğelerin sayısını sorgulamaktan farklıdır. } .. // bir for ifadesi kullanarak geri kalan 10 öğede yineleme yap for (int i = 0. bir dizi kullandığınızda ise Length özelliğini sorgularsınız. öğe olan öğeyi kaldır. // değeri 7 olan ilk öğeyi kaldır (4..Insert(numbers.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. .

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

Bir öğe yığına üstten katılır (push işlemi) ve yığını yine üstten terk eder (pop işlemi).. } . .Count > 0) { int number = (int)numbers. Stack numbers = new Stack(). 3. // yığın boyunca yinele foreach (int number in numbers) { Console.Bölüm 10 Dizileri ve Koleksiyonları Kullanmak 197 Stack Koleksiyon Sınıfı Stack (yığın) sınıfı.. .Collections...WriteLine(number + “ has been popped off the stack”).Push(number). // yığını boşalt while (numbers. (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. } . LIFO) mekanizmasını gerçekleştirir. klasik son giren ilk çıkar (last-in first-out.Pop(). 2}) { numbers..WriteLine(number + “ has been pushed on the stack”). 7. 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.. Console. using System.. // yığını doldur foreach (int number in new int[4]{9.WriteLine(number).. } 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 .

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

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

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

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

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

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

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

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

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

Aşırı Yükleme (Overloading). Nesneyönelimli kavramlarına aşina iseniz. farklı türlerde bağımsız değişkenler üzerinde aynı eylemi gerçekleştirmek istediğiniz bazı durumlarda çok yararlıdır. kısa sürede can sıkıcı bir hal alır. 207 .WriteLine’dır. bu problemi çözmek için nesne-yönelimli yaklaşım. public static void WriteLine(decimal parameter) .. Console. Neyse ki..WriteLine sürümünü çağırmanız mı gerekir? Bu.. aynı kapsamda aynı adla iki ya da daha çok sayıda yöntem bildirmenin teknik terimidir. parametre dizileri kullanışlıdır. Özellikle. bütün durumları kapsamaz.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. Ve bu kadar çok yinelenen tüm bu aşırı yüklenmiş yöntemler sizi endişelendirmiyor mu? Endişelendirmeli. 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) . 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). 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. Microsoft Visual C#’daki klasik aşırı yükleme örneği. mümkün olduğunda farklı türlerde bağımsız değişkenler alabilen yöntemler yazmak isterseniz. Neticede. bir öncekinden bir fazla parametre alan Console. } Aşırı yükleme işlemi ne kadar yararlı olursa olsun. aşırı yükleme. 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. Bir yönteme aşırı yükleme yapmak... public static void WriteLine(double parameter) . değişenin parametrelerin türleri değil sayıları olduğu durumları çok kolay işleyemez. bu cümle sizde hayal kırıklığı yaratmış olabilir.. Örneğin. aşırı yüklenmiş yöntemleri tanımlamaktır. ya birçok değeri konsola yazmak isterseniz? Her değer için.

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() { ...

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

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

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

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

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

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

TakeOff(). Airplane sınıfını görüntüleyin.Drive(). 20.. myCar. Bu ifadeler.WriteLine(“Flying”). Code and Text Editor penceresinde.Drive(). Start Without Debugging’i tıklayın. Car sınıfının bir oluşumunu yaratır ve yöntemlerini test eder. Aşağıdaki gibi. konsol penceresinde.WriteLine(“\nJourney by car:”). Airplane sınıfındaki Drive yöntemini geçersiz kılın: public override void Drive() { Console.Land(). Car myCar = new Car(). myPlane. myPlane. aşağıdaki resimde gösterildiği gibi.StartEngine(“Brm brm”)..Accelerate(). 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. 21. } .StopEngine(“Whirr”). Programın. myCar. myCar. myCar. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın.Brake(). Debug menüsünde. Entrance yönteminde biraz önce yazdığınız kodun hemen arkasına aşağıda koyu harflerle gösterilen ifadeleri ekleyin.StopEngine(“Phut phut”). myCar. static void Entrance() { . myPlane. Çünkü sınıfların her ikisi de bu yöntemi geçersiz kılmaz. } 19.Bölüm 12 myPlane. Console. } Kalıtım ile Çalışmak 231 18.

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

..Drive yöntemini çağırır. her int değişkenin tanımını. bir sınıftan yeni bir sınıf yaratarak. o sınıfın işlevselliğini genişletmenizi sağlar. genişletilmiş türdeki veriye başvuran herhangi bir ifadede hemen kullanılabilir hale gelir. 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. Ş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. Bu statik yöntemler. Uygulamayı kapatmak ve Visual Studio 2008’e dönmek için Enter’a basın. hangi Drive yönteminin çağrıldığını bulur..Bölüm 12 Kalıtım ile Çalışmak 233 Drive yöntemi sanaldır. System. ek statik yöntemlerle genişletmenizi sağlar. System.) Bunu yapmanın bir yolu. İlk durumda.Drive yöntemini çağırır. 28. bu nedenle uygulama Airplane. System. } } // bunu denemeyin! Teori şudur: NegInt32. Vehicle nesnesi bir Airplane’a başvurur. Vehicle nesnesi bir Car’a başvurur. bu nedenle çalışma zamanı (derleyici değil). Örneğin. İkinci durumda. Bir uzantı yöntemi mevcut bir türü (sınıf ya da yapı). Int32’den kalıtımla alan (int türü System. (Aynı görevi gerçekleştirmek için tek bir eksi işlecini (-) kullanabileceğinizi biliyorum.Int32 { public int Negate() { .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.Int32 türü ile ilgili tüm işlevselliği miras alacaktır. n Bu noktada uzantı (extension) yöntemleri çok kullanışlıdır. bu nedenle uygulama Car. 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.Int32 türü aslında bir sınıf değil. bazen yeni davranışlar eklemek için kalıtım kullanmak. Bununla birlikte. Negate yöntemine ek olarak. fakat sabredin. bir yapıdır ve yapılarla kalıtımı kullanamazsınız. türü NegInt32 olacak şekilde değiştirmeniz gerekir. en uygun mekanizma değildir özellikle var olan kodu etkilemeden bir türü hızlıca genişletmeniz gerekiyorsa.

WriteLine(“x. 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. bu kullanım. 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. int türünü genişlettiğiniz anlamına gelir. this anahtar sözcüğünün önüne eklenen parametrenin int olması. Bu dosya. Bu uzantı yöntemi. parametre olarak int türü geçiren Utils.” 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. C# derleyicisi. x.Negate yöntemini de çağırabilirsiniz: int x = 591. Burada. // to do yorum satırı dışında boştur. Negate yöntemini çağıran ifadede herhangi bir yerde Util sınıfına başvurmanıza gerek olmadığına dikkat edin. Aşağıdaki alıştırmada. 10 tabanında bir sayı içeren int değişkeninin değerini. Daha sonra yönteme başvurmak için “. fakat Negate yöntemini bir uzantı yöntemi olarak tanımlayan parametreyi ekleyen. Visual Studio 2008’de açın.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.Negate(x)). 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. Ayrıca. Uzantı yöntemlerini bir statik sınıf içinde tanımlamanız gerektiğini hatırlayın.WriteLine(“x. farklı sayı tabanındaki gösterimine çevirir. kapsam içindeki statik sınıfların tümünden uzantı yöntemlerini otomatik olarak ortaya çıkarır. Console. } } Sözdizimi biraz garip görünüyor.Negate {0}”.Negate()). this anahtar sözcüğüdür. Util sınıfının ait olduğu ad alanını belirten bir using ifadesi ekleyin). Util. Bir uzantı yöntemi yaratın 1. daha önce gördüğünüz sıradan sözdizimini kullanarak. Code and Text Editor penceresinde Util. int türüne bir uzantı yöntemi ekleyeceksiniz. Sınıf. Uzantı yöntemini kullanmak için. 2.Negate {0}”. Console. verilen bir tür için. .

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

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

Örneğin: class Mammal { public virtual void Breathe() { ... Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. } . ardından iki nokta üst üste ve temel sınıfın adını yazın. Örneğin: class Derived : Base { . } 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... } .. 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... 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...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. Örneğin: class Derived : Base { .. Save iletişim kutusu görünürse.. public Derived(int x) : Base(x) { . } Sanal bir yöntem bildirmek Yöntemi bildirirken virtual anahtar sözcüğünü kullanın.. } .

Örneğin: static class Util { public static int Negate(this int i) { return –i. İlk parametre. önünde this anahtar sözcüğü ile genişletilmiş türde olmak zorundadır. Örneğin: class Whale : Mammal { public override void Breathe() { .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.... } Bir tür için uzantı yöntemi tanımlamak Statik sınıfa statik ortak yöntem ekleyin.. } } . } .

sealed anahtar sözcüğünü kullanarak bir sınıfın temel bir sınıf olarak kullanılamayacağını bildirmek. nesneleri saklamak için bir uygulama sağlayan yeni bir koleksiyon sınıfı tanımlamak istediğinizi varsayın. Bu nedenle 239 . Koleksiyon sınıfını tanımladığınızda. koleksiyondaki nesnelerin sıralanma şeklinin koleksiyona değil. 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. 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. nesnelerin kendi türlerine bağlı olmasıdır. bu yöntemler için kendi uygulamasını sağlamak zorundadır. Fakat bu belirtilmemiş nesneleri sıralamanın bir yolunu bulmanız gerekir. durum bu değil.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. bu nedenle sanal yöntem çok fazla kullanılmayacaktır. Bununla birlikte. bir soyut sınıfın başlıca yöntemlerini belirleyebilirsiniz. genişletilebilir programlama çerçeveleri oluşturmanızı sağlayan anahtar teknikler sağlarlar. Bir an düşünürseniz. bu nedenle soyut sınıftan kalıtımla alan bir sınıf. Arabirimleri Anlamak İçerdiği nesnelerin türüne bağlı olan bir sırada. Bir sınıftan kalıtımla almak güçlü bir mekanizmadır. sadece bir arabirimden kalıtımla alan bir sınıfın sağlamak zorunda olduğu yöntemler ve özellikleri belirtir. Yöntemlerin gövdesini yazarak bir yapı ya da sınıf içinde bir arabirim uygulamak. Soyut sınıflar. fakat kalıtımın gerçek gücü bir arabirimden kalıtımla almasından gelir. problem. Bir arabirim herhangi bir kod ya da veri içermez. kod ve veri içerebilmeleri dışında. Bununla birlikte. Çoğu kez. 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. bir sınıfın yöntemlerinin adları ve imzalarını. yöntemin uygulanmasından tamamen ayırabilmenizi sağlar. Bir soyut sınıf içinde yaygın uygulama ayrıntılarını yakalamak. soyut sınıfları arabirimlerle kullanırsınız. birçok yönden arabirimlere benzer. Genellikle koleksiyon sınıfı ile sınıfın tuttuğu nesneler arasında kalıtıma benzer bir ilişki yoktur. Bir arabirim kullanmak. Birlikte.

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

Horse sınıfında bu arabirimi uygulayabilirsiniz: class Horse : ILandBound { . bir sınıf ya da yapının uygulama detayı olarak düşünülür.NumberOfLegs() { return 4. 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). 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. (Yıkıcılar ”Çöp Toplama ve Kaynak Yönetimini Kullanmak” başlıklı Bölüm 14’te anlatılmıştır.) Herhangi bir yöntem için bir erişim değiştiricisi belirtemezsiniz. bazı uygulamaları da kalıtımla almış olacaktı.. sınıflar ya da arabirimler gibi) yuvalayamazsınız. bir arabirimin bunların herhangi birinden kalıtımla alınmasına izin verilseydi. } } . Kurucu da. Bir yıkıcı. bir sınıf ya da yapının uygulama detayıdır. bir arabirimin hiçbir zaman hiçbir uygulama içermediğidir. Örneğin. Bir arabirim içinde yıkıcı tanımlamanıza izin verilmez. bir nesne oluşumunu yıkmak için kullanılan ifadeleri içerir. Bir arabirim içinde hiçbir türü (numaralandırmalar. Yapılar ve sınıflar uygulamalar içerirler. 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(). arabirimden kalıtımla alan ve arabirim tarafından belirtilen tüm yöntemleri sağlayan bir sınıf ya da yapı bildirirsiniz. Bir arabirim içinde kurucu tanımlamanıza izin verilmez. n n n n n Bir Arabirim Uygulamak Bir arabirim uygulamak için.. yapılar.Bölüm 13 Arabirimler Yaratmak ve Soyut Sınıflar Tanımlamak 241 Arabirim Kısıtlamaları Hatırlanması gereken konu. } Daha sonra. Fakat bir arabirim başka bir arabirimden kalıtımla alınabilir. Bir alan. Bir arabirimdeki tüm yöntemler dolaylı olarak ortaktır.

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

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

. türetilmiş sınıfların parçalarının ortak uygulamaları paylaşmaları oldukça yaygındır. Horse sınıfını şu şekilde tanımlayabilirsiniz: class Horse : Mammal. birden fazla arabirimden kalıtımla alınırsa. Örneğin.WriteLine(“Chewing grass”).. çok sayıda farklı sınıflar tarafından uygulanabilir. C# uygulamanızda kaç farklı memeli türü modellemek istediğinize bağlı olarak. aşağıdaki iki sınıftaki yineleme çok açıktır: class Horse : Mammal. ILandBound. 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. IGrazable { . bir yapı ya da bir sınıf.ChewGrass() { Console... // geviş getirme için kod }. Bu gibi durumlarda. Yinelemeden kaçınmak ve kodun bakımını kolaylaştırmak için kodu yeniden düzenlemelisiniz.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. IGrazable { .. Bu yeniden düzenlemenin yolu. ortak . // geviş getiren at için olan kodun aynısı }. void IGrazable. } Soyut Sınıflar ILandBound ve IGrazable arabirimleri. ILandBound. } class Sheep : Mammal. Örneğin.WriteLine(“Chewing grass”). Bir sınıf yine de tüm arabirimlerinden kalıtımla aldığı yöntemlerin tümünü uygulamak zorundadır. arabirimler temel sınıftan sonra listelenir. ILandBound. Bir arabirim. IGrazable { . void IGrazable. Bir sınıf ayrıca bir temel sınıfa sahipse.ChewGrass() { Console. } Kodda meydana gelen yineleme bir uyarı işaretidir. arabirimleri virgülle ayırarak yazarsınız..

).. // geviş getirme için ortak kod } } class Horse : GrazingMammal. ILandBound { . kalıtımla alınmasıdır...WriteLine(“Chewing grass”).. void IGrazable. GrazingMammal sınıfında. Soyut yöntem.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. kod derlenmez: GrazingMammal myGrazingMammal = new GrazingMammal(. ILandBound { .. açıkça sınıfın soyut olduğunu bildirmeniz gerekir. Bir sınıfın oluşumlarının yaratılmasına izin verilmediğini bildirmek için. IGrazable { . bu yöntemi geçersiz kılmak zorundadır. Örneğin: abstract class GrazingMammal : Mammal.. GrazingMammal sınıfı.) Türetilmiş bir sınıf. } 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. abstract anahtar sözcüğünü kullanarak. soyut yöntemler içerebilir. Bu gerçekten mantıksız. sınıf hiyerarşisine yeni bir sınıf ekleyebilirsiniz. ortak varsayılan uygulamayı sağlamak için vardır. GrazingMammal sınıfı. IGrazable { . } class Sheep : GrazingMammal. temelde sanal yönteme benzer. Gerçekte.. } Bir GrazingMammal nesnesi oluşturmaya çalışırsanız.. Tek amacı. (Bölüm 12’de sanal yöntemleri görmüştünüz. ortak işlevselliklerin bir soyutlamasıdır. sanal yöntem olarak DigestGrass yöntemini tanımlar. bir yöntem gövdesi içermemesi dışında. Soyut bir sınıfta varsayılan bir uygulama sağlamak mantıklı değilse . kendi haklarına sahip bir girişten çok.. Örneğin: class GrazingMammal : Mammal.ChewGrass() { Console. 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.. // derlenmez Soyut Yöntemler Bir soyut sınıf.

. Bir arabirim ya da soyut bir sınıf yaratırsanız. C#.. gelecekte kalıtımla alınacak bir şeyler yazıyorsunuz demektir. sealed override olarak bildirirsiniz. Bir geçersiz kılma (override) yöntemi. bir yöntemin ilk uygulamasıdır. Sadece bir override yöntemi mühürleyebilirsiniz. } Mühürlenmiş Sınıflar Kalıtımı her zaman akıllıca kullanmak kolay değildir. Pratik yaptıkça ve deneyim kazandıkça. Örneğin: sealed class Horse : GrazingMammal. Not Bir yapı dolaylı olarak mühürlenmiştir. mühürlenmemiş bir sınıfta tek bir yöntemi mühürlenmiş olarak bildirmek için de kullanabilirsiniz. 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. temel bir sınıf olarak kullanmak amacıyla bilerek bir sınıf tasarlamadığınız sürece. (Yöntemi. ILandBound { .. override ve sealed anahtar sözcüklerini şu şekilde düşünebilirsiniz: n n n n Bir arabirim (interface). Bunu yapmanın başka bir yolunu bulmak için. } Herhangi bir sınıf. herhangi bir sanal yöntem bildiremez ve soyut bir sınıf mühürlenemez. Bir yapıdan asla türetemezsiniz. abstract class GrazingMammal : Mammal. Mühürlenmiş Yöntemler sealed anahtar sözcüğünü. . 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.. Bir sanal (virtual) yöntem. Bu.) interface. esnek.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. bir soyut yöntem yararlı olacaktır. türetilmiş bir sınıfın daha sonra mühürlenmiş yöntemi geçersiz kılamayacağı anlamına gelir. Sealed (Mühürlenmiş) sınıf. Bir mühürlenmiş (sealed) yöntem. virtual. bir yöntemin adını tanıtır. Buradaki sorun. bir yöntemin diğer bir uygulamasıdır. temel sınıf olarak görev yapması imkansızdır. bir sınıfın temel sınıf olmaması gerektiğine karar verdiyseniz. kullanımı kolay arabirim. . bir yöntemin son uygulamasıdır. derleme hatası meydana gelir. geleceği önceden tahmin etmenin zor olmasıdır. IGrazable { abstract void DigestGrass(). Horse sınıfını temel sınıf olarak kullanmaya kalkarsa.

Kodda yuvalanmış küme parantezlerinin derinliğini gösteren karmaşıklık ziyaretçi sınıfı. 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ı. Çerçeve.”). Addison Wesley Longman. . }. 3. Belgeler klasörünüzde yer alan \Microsoft Press\Visual CSharp Step by Step\Chapter 13\ Tokenizer klasöründeki Tokenizer projesini açın.cs dosyasını görüntüleyin. anahtar sözcükler. 2. Bu çerçeve. Microsoft Visual Studio 2008’i başlatın. Sekmeleri boşluklara dönüştüren ve küme parantezlerini doğru olarak hizalayan bir yazıcı ziyaretçi sınıfı. Not Bu çerçeve. 1995) kitabında belgelendirilen Visitor modelini uygular. tokens olarak adlandırılan bir özel dizi alanı içerir: private { new new new new . WhitespaceToken(“ “). IdentifierToken(“System”). 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. Her yöntemdeki satır sayısını. şunları yaratabilirsiniz: n n Zengin metin kutusunda kaynak dosyayı gösteren görüntüleyici ziyaretçi (visitor) sınıfı. ilk olarak Erich Gamma. 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ı. Richard Helm. 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ı. özel görevleri gerçekleştirmek için. Her bir tanımlayıcının yazılışını denetleyen heceleyici ziyaretçi sınıfı. n n n n Kalıtım hiyerarşisini ve amacını anlayın . SourceFile sınıfı. tipik bir derleyicinin gerçekleştirebileceği bazı görevleri yerine getirir. Code and Text Editor penceresinde SourceFile.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. IVisitableToken[] tokens = KeywordToken(“using”). bir C# kaynak dosyasını okumak ve dosyanın içeriğini tokens (simgeler) (tanımlayıcılar. Örneğin. sırayla her bir simgeyi “ziyaret etmek” için bir teknik sağlar. PunctuatorToken(“.. 1..

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

Aşağıdaki gibi. Solution Explorer tarafından kullanılan pencerede görünür.ToString()). Class View penceresinde.Accept(ITokenVisitor visitor) { visitor. visitor nesnesinin uygun gördüğü şekilde. 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. } Not VisitIdentifier yöntemi. IVisitableToken arabiriminin genişlettiği arabirimler (IToken ve IVisitable).VisitIdentifier(this. Accept yöntemini uygular: void IVisitable. Class View penceresinde. Aşağıdaki alıştırmada. Bu pencere. sınıflar ve arabirimleri görüntüler. (Gerçekte SourceFile. şu şekilde görüntülenir: 8. proje tarafından tanımlanan ad alanları. Arabirimleri sınıflardan ayırmak için kullanılan simgelere dikkat edin. 7. Bu ad alanındaki sınıflar ve arabirimler listelenir. Code and Text Editor penceresinde bu sınıfı görüntülemek için Go To Definition’ı tıklayın. IVisitableToken arabirimini genişletin ve daha sonra Base Types düğümünü açın.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. Tokenizer projesini genişletin ve daha sonra {} Tokenizer ad alanını açın.cs dosyasında yer almaktadır. Bu dosyadaki diğer simge sınıfları da aynı yolu izler. IdentifierToken sınıfını farenin sağ düğmesiyle tıklayın ve daha sonra.

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

ColorSyntaxVisitor visitor = new ColorSyntaxVisitor(codeText). Open düğmesi sadece SourceFile sınıfında kodlanmış veriyi kullanır. 2. Bu örnekte. 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. formun kodunu görüntülemek için View Code’u tıklayın. openClick yöntemini bulun. 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. RoutedEventArgs e) { SourceFile source = new SourceFile(). her simgeyi bir renkle gösteren ColorSyntaxVisitor nesnesidir. Formu farenin sağ düğmesiyle tıklayın ve sonra Code and Text Editor penceresinde. Not Geçerli uygulamada. 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.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. Bu form. } SourceFile sınıfının Accept yönteminin tüm simgeler üzerinde yinelenerek. Kullanıcı Open düğmesini tıkladığında bu yöntem çağrılır. SourceFile sınıfında gösterilen biçimde simgeleştirir. sıradan metin kutusu gibidir. Open düğmesi. openClick yöntemine aşağıda koyu harflerle gösterilen kodu ekleyin: private void openClick(object sender. basit biçimlendirilmemiş metinden çok biçimlendirilmiş içerik görüntüleyebilmesi dışında. . Tümüyle işlevsel uygulamada. belirtilen ziyaretçiyi kullanarak her simgeyi işlediğini hatırlayın.Accept(visitor). ziyaretçi. 3. Not Zengin metin kutusu. source.

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

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

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

. 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ı. yapının saklayabileceği yöntemleri içeren System. geçersiz (hayır) ve zorunlu (gerekli) anahtar sözcük bileşenlerini özetlemektedir. sanal yöntemleri içeren System. sınıflar ve arabirimler yaratırken kullanılabilecek çeşitli geçerli (evet).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.Object’ten dolaylı olarak türeyebilir. yapı.

. abstract anahtar sözcüğü ile.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. } 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(). } } Soyut yöntemler içeren.. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.. Örneğin: sealed class Horse { .. 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.. Her soyut yöntem için. } 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. Örneğin: abstract class GrazingMammal { abstract void DigestGrass(). n Bölüm 13 Hızlı Başvuru Bunun İçin Bir arabirim bildirmek Şunu Yapın interface anahtar sözcüğünü kullanın. 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.. Örneğin: interface IDemo { string Name().Name() { . } public string IDemo. yöntem gövdesi olmadan bir yöntem bildirin. } .. Save iletişim kutusu görünürse.Description() { ...

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

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

instanceCount--. struct Tally { ~Tally() { . 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). } // derleme zamanı hatası Derleyici... } // derleme zamanı hatası n Bir yıkıcıyı hiçbir zaman parametrelerle bildiremezsiniz ve yıkıcı bir parametre alamaz. } . public ~Tally() { .instanceCount++. Diğer bir deyişle derleyici aşağıdaki yıkıcıyı: class Tally { ~Tally() { .. } } . } public static int InstanceCount() { return this.. otomatik olarak bir yıkıcıyı Object..instanceCount. kendinizin bir yıkıcı çağırmayacağınızdır. } // derleme zamanı hatası } n Bir yıkıcı için bir erişim değiştiricisi (public gibi) belirtemezsiniz..Finalize yönteminin geçersiz kılma biçimine dönüştürür.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.. Bir struct gibi veri türlerinde bir yıkıcı bildiremezsiniz. Bunun nedeni de.. } ~Tally() { this. } 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.. private static int instanceCount = 0. ~Tally(int parameter) { ..

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

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

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

Close(). art arda girilen karakterleri okumak için bir teknik sağlar. string line.ReadLine()) != null) { Console. ReadLine yöntemi null döndürür. ReadLine yöntemi metnin bir sonraki satırını bir dize olarak okur. } reader. } } finally { reader. try { string line. karakter akışını sonlandıran. 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. Bu durum sık meydana gelirse. Akışta başka bir şey kalmamışsa.ReadLine()) != null) { Console. while ((line = reader. dosya işlemeyi bitiremez ve başka dosya açamazsınız. bu örnekle ilgili bir sorun vardır: özel durum-güvenli değildir.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. Close adında bir sanal yöntem içerir. 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). while ((line = reader. Close yöntemi çağrılmayacaktır.Close(). Bir önceki örneğin bu yöntemi kullanan biçimi aşağıdaki gibidir: TextReader reader = new StreamReader(filename).IO ad alanının TextReader sınıfıdır. System. TextReader sınıfı. özel durum olsa da olmasa da her zaman çağrıldığından emin olmanın yolu. dosya işleme ve ilgili kaynakları serbest bırakmak için önemlidir. Özel Durum-Güvenli Yok Etme Bir yok etme yönteminin (Close gibi). reader ile işiniz bittiğinde. } . Close yöntemini çağırmak.WriteLine(line). Bu sınıf. yok etme yöntemini bir finally bloğu içinde çağırmaktır. ReadLine ya da WriteLine çağrılması bir özel durum oluşturursa.WriteLine(line). Bununla birlikte.

264 Kısım II C# Dilini Anlamak Bu biçimde bir finally bloğu kullanmak. serbest bırakıldıktan sonra bir kaynağı kazayla kullanabileceğinizdir. aynı anahtar sözcük iki farklı anlam taşımaktadır. başvuruyu null olarak başlatmayı unutmayın ve başvurunun finally bloğunda null olmadığından emin olun. n n n using ifadesi tüm bu sorunları çözmek için tasarlanmıştır. using İfadesi using ifadesi. çözümün anlaşılmasının zor olduğu ve gerekli olduğunda her seferinde yinelenmesi gerektiğidir. Bunun anlamı. 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. while ((line = reader. Bir nesne yaratabilirsiniz ve bu nesne using ifadesi bittiğinde yok edilir.) Bazı durumlarda.ReadLine()) != null) { Console. Kaynağa yapılan başvuru finally bloğundan sonra da kapsam içinde kalır.) Çözümün bir sanalını yaratamazsınız. Ne yazık ki. Bunun anlamı. kaynak başvurularının bildirimlerinin sırasını değiştirmeniz gerekebilir. kaynakların ömrünü denetlemek için açık bir teknik sağlar. (Örneğin. kodu değiştirmeniz gerekir. 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. } } .WriteLine(line). Önemli Bu bölümde gösterilen using ifadesini kapsama bir ad alanı getiren using yönergesi ile karıştırmayın.

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

private bool disposed = false. yararlı bir “yedek” gibi çalışır.disposed) { throw new ObjectDisposedException(“Example: object has been disposed”).. } } } public void SomeBehavior() // örnek yöntem { checkIfDisposed(). } public virtual void Dispose() { if (!this.. çağrılacağından emin olabilirsiniz. çünkü programcının bir using ifadesi yazmayı unutmamasına bağlıdır.SuppressFinalize(this). 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. GC.266 Kısım II C# Dilini Anlamak Bir Yıkıcıdan Dispose Yöntemini Çağırmak Bir sınıf yazarken. 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. } } private Resource scarce. ~Example() { Dispose(). } . } . Bunu nasıl yapabileceğinizi gösteren bir örnek aşağıdadır: class Example : IDisposable { . . private void checkIfDisposed() { if (this... Dispose yöntemini yıkıcıdan çağırarak her zaman çağrılacağından emin olabilirsiniz. Bununla birlikte..disposed = true.. Diğer taraftan.disposed) { try { // kıt kaynağı burada serbest bırak } finally { this. Bu. Dispose yöntemini çağırmayı unutabilirsiniz fakat en azından program kapatılırken bile olsa.

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

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

Text += line + “\n”. .Clear().Close çağrısına gerek yoktur.CancelEventArgs e) { string fullPathname = openFileDialog.FileName.Bölüm 14 Çöp Toplama ve Kaynak Yönetimini Kullanmak 269 fileName.Text = src. Dosyanın açılmasından sonra bir özel durum oluşursa.ReadLine()) != null) { source.ComponentModel. using ifadesinin doğal olarak bitmesini ya da özel durum nedeniyle sonlanmasını sağlar. Bu. 10. System. Save iletişim kutusu görünürse. } } } using ifadesi tamamlandığında. reader. openFileDialogFileOk yöntemini değiştirin ve dosyayı işleyen kodu bir using ifadesi içine yerleştirin. yöntem sonlanacak fakat dosya uygulama bitene kadar açık kalacaktır. openFileDialog ve source değişkenleri Window1 sınıfının üç özel alanıdır. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. StreamReader sınıfının Dispose yöntemi tarafından otomatik olarak çağrılacağından. fileName. reader. while ((line = reader. TextReader nesnesini kapatan ifadeyi kaldırın. using (TextReader reader = new StreamReader(fullPathname)) { string line. Debug menüsünde Start Without Debugging’i tıklayın. source. 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.Close’a yapılan çağrının gerçekleşeceğinin kesin olmamasıdır. 9. private void openFileDialogFileOk(object sender. Uygulamanın önceki gibi çalıştığından emin olun ve daha sonra formu kapatın.Name. 11. Bu koddaki sorun. FileInfo src = new FileInfo(fullPathname). 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 Example { ~Example() { . } } . } } Bir yıkıcı çağırmak Çöp toplayıcıyı zorlamak (önerilmez) Bir kaynağı bilinen bir zamanda bırakmak (özel durum uygulamayı keserse. Bir yok etme yöntemi (bir kaynağı yok eden bir yöntem) yazın ve onu programda çağırın...... public virtual void Close() { ..Close().. değiştiriciye (public gibi) erişememelidir ve parametresi olmamalıdır ya da bir değer döndürmemelidir. } } class Example { void Use() { TextReader reader = . Yöntem.Collect’i çağırın. Örneğin: class TextReader { .GC.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. Sadece çöp toplayıcı bir yıkıcı çağırabilir.. // okuyucuyu kullan reader. System. bellek kaybetme riskini göze alarak) Bir yıkıcı çağıramazsınız..

) { // okuyucuyu kullan } } } . } } IDisposable void Dispose() çağır void Close() class Example { void Use() { using (TextReader reader = . public virtual { // Close’u } public virtual { .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 : { .......

.

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

.

Özellikler bildiren arabirimler yaratmak. numaralandırmalar ve sınıflar kullanarak yeni türleri C# dilinde nasıl oluşturacağınız gösterildi. bu yolla bir alana erişim için sözdizimi doğal değildir. bu bilgi üzerine oluşturuldu. Özellikler bu uygunsuzluğu gidermek için tasarlanmıştır. bir program çalıştığında. bölümler. normal olarak bir atama ifadesi kullanırsınız. Bununla birlikte. Bir değişken okumak ya da yazmak istediğinizde. Bu yaklaşım.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. Bu bölümde. get erişimcileri bildirerek özelliklere okuma erişimini denetlemek. özellikler içeren arabirimler uygulamak. ç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. Yapılar ve sınıflar kullanarak. C# nesnelerinin ömrünü anlamış olmalısınız. set erişimcileri bildirerek özelliklere yazma erişimini denetlemek. bir sınıftaki alanları gizlemek için özellikleri nasıl tanımlayacağınız ve kullanacağınız ele alınacaktır. 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. Bu kitabın ilk iki kısmında C# dilinin temel sözdizimi sunuldu ve yapılar. Ayrıca. bir değişken) aynı etkiye erişmek için bir yöntem çağırmak biraz acemiliktir. Otomatik olarak alan tanımlarına dayalı özellikler üretmek. Önceki bölümlerde. 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. Nesneleri başlatmak için özellikler kullanmak. “Bileşenler Yaratmak” başlıklı Kısım III’te. 275 . bu nedenle bir alanda (sonuç olarak.

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

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

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

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

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

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 { ... } } }

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

Dizinleyicilere okuma erişimini denetlemek için get erişimcileri bildirmek. (Benim gibi eski bir C program geliştiriciyseniz. İçsel olarak. bir int. Arabirimlerden kalıtımla alınan yapı ve sınıflarda dizinleyiciler kullanmak. Ancak. 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. Sorun tamsayılarla ilgili ya da daha doğru belirtmek gerekirse int türü ile ilgili. İlk olarak bir sorun tanımlayacağız ve dizinleyici kullanmayan kötü bir çözüm göreceğiz. Dizinleyicileri bildiren arabirimler yaratmak. Özellikler. Ancak. 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. yalnızca bir tamsayı değeri taşıması için bir int’i kova olarak kullanırsınız. Önceki bölümde bir sınıftaki alanlara denetimli başvuru sağlamak için özellikleri kullanıp uygulamak açıklanmıştı. Bir dizinleyici için kullandığınız sözdizimi. Dizinleyicilere yazma erişimini denetlemek için set erişimcileri bildirmek. 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. bazı programlar bir int içindeki tek tek bitleri değiştirirler. Dizinleyici Kullanmayan Bir Örnek Normalde bir tamsayı değeri taşıması için bir int kullanırsınız. bir örnek üzerinde çalışalım. Dizinleyici Nedir? Bir dizinleyici (indexer). değerini. Diğer bir deyişle. tek bir değer içeren alanları yansıtmak için yararlıdır. Gelin. programcılar int türünü bazen başka amaçlar için kullanırlar. tümüyle bir dizi için kullandığınız sözdiziminin aynısıdır. her bitin 0 ya da 1 olabildiği 32 bitlik bir sırada tutar. bundan sonra gelenler tanıdık olmalıdır!) 295 .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. Çoğu zaman bu içsel ikili gösterim konusunu düşünmeniz gerekmez. akıllı bir dizidir.

Çok karmaşıktırlar ve çözüm çok basittir. bit OR (|) işlecini kullanabilirsiniz. Tekil bir işleçtir. Bazı durumlarda programcılar bir değerin doğru olduğunu belirtmek için 1. 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. n NOT (~) işleci bir bit benzeri tamamlayıcısıdır. 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. <<. bits adlı int’in 6.296 Kısım III Bileşenler Yaratmak Not Bazı eski programcılar int türlerini bellekten tasarruf etmek için kullanabilir. Örneğin. aşağıdaki deyim. dizindeki bit 0 ise deyim false. sağdan sola doğru bitlerin konumunu sayar. sıradaki bittir. dizindeki bit’i. çalışıyor olsalar bile neden ve nasıl çalışıyor olduklarının çok açık olmamasıdır. Bit Benzeri ve Kaydırma İşleçleri Bu örneklerde gösterilen bazı ilginç simgeleri fark etmişsinizdir. | ve &. ~. dizindeki bit de sağdan 6. 1 ise true sonucunu verecektir. Aşağıdaki karmaşık ifade |= birleşik atama işlecine dayanır: bits |= (1 << 6) Bu örneklerle ilgili sorun. . Benzer şekilde. Bu oldukça karmaşık bir deyim. 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. Örneğin. Tek bir int 32 bit tutar ve her bit 0 ya da 1 olabilir. 6. ama 6. &= 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. Çözüm getirdiği problemin bir soyutlamasını yapamaz. yanlış olduğunu belirtmek içinse 0 kullanırlar ve daha sonra bir Boolean değerler kümesi olarak bir int kullanırlar. Özellikle. bu nedenle 0 biti en sağdaki bit ve 6. dizindeki biti 1 olarak ayarlamak istiyorsanız.

204&24 işleminin sonucu 8’dir (204’ün karşılığı 11001100’dır. İkili bir işleçtir. 24’ün karşılığı ise 00011000’dır. bit benzeri OR işlecine benzer. . (İki 1 değeri 0 sonucunu verir – bu da işlecin “özel” bölümüdür. Bu yüzden. Örneğin. dizindeki bit’i true yapmak için şunu yazabilmeliyiz: bits[6] = true Ne yazık ki. bir int üzerinde köşeli parantez kullanamazsınız. Bir ikili işleçtir ve işleç değişkenlerinin her ikisi de “1” ise o biti “1” yapar. yani bir dizinleyici tanımlayan bir tür üstünde. 6. Sonuçta sorunun çözümü bool değerlerden oluşan bir dizi gibi davranan. 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. 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. 24’ün karşılığı ise 00011000’dır. Bir ikili işleçtir ve iki işleç değişkeninden herhangi biri “1” ise o biti “1” yapar. 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.Bölüm 16 n Dizinleyicileri Kullanmak 297 << işleci sola kaydırma işlemi uygular. AND (&) işleci bir bit benzeri AND (ve) işlemi uygular. İpucu IntBits küçük ve hafif olduğundan onu bir sınıf olarak değil. Gelin bu yeni türe IntBits diyelim. Sorun.) Bu yüzden 204^24 işleminin sonucu 212’dir (11001100^00011000 işleminin sonucu 11010100’dır). dizindeki bit’i almak için yazmamız gereken şudur: bits[6] Ve. fakat int türü kullanılarak uygulanan yeni bir tür yaratmaktır. XOR (^) işleci. 8 ise 00001000’dır). yapı olarak yaratmak daha akıllıcadır. OR (|) işleci bir bit benzeri OR (ya da) işlemi uygular. Köşeli parantezi yalnızca bir dizi ya da bir dizi gibi davranan başka bir tür üzerinde kullanabilirsiniz. 220 ise 110011100’dır). Bunun tam karşıtı olan bir de sağa kaydırma işleci >> vardır. hisseden ve kullanılan. 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. örneğin. bir int’i bir int gibi kullanmak istemeyip 32 bitlik bir dizi gibi kullanmak istememizdi. En soldaki iki bit atılır ve sağdan iki sıfır eklenir. 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. AND.

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

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. Sıradan özelliklerdeki gibi. 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. true (1) olmalı bits[0] = true. // 6 dizininde bool al. aşağıdaki örneği düşünün: bool peek = bits[6]. Bu ifade. Örneğin: bits[6] = true. 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. 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. Not Dizinleyici ve özellikler. Benzer biçimde. static özellikler bildirmenize izin verilse de static dizinleyiciler geçersizdir. 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. get ve set erişimcilerini kullanmaları açısından birbirine benzer. Doğrudan ve uzatmadan sorunun özünü yakalar. Bir dizinleyici birden çok değeri olan bir özellik gibidir. . // 62 111110’un ikili temsilidir IntBits bits = new IntBits(adapted). // 3 dizininde bit’i false (0) olarak ayarla // değiştirilen değer şimdi 111011. Örneğin. bool). value türü dizinleyicinin türüyle aynıdır (bu durumda. // 0 dizininde bit’i true (1) olarak ayarla bits[3] = false.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. 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. Ancak.

. Bu kod çalışır çünkü dizinleyici hem bir get hem de bir set erişimcisi bildirir. n Dizinleyiciler (yöntemler gibi) aşırı yüklenebilirken.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.. Bu durumda get ve set erişimcileri kullanılır. // derleme zamanı hatası .. sözdizimi dizi sözdizimine benzer. } // Tamam İpucu Anahtar/değer çiftlerine bağlı olarak bileşik arama uygulayan Hashtable gibi birçok koleksiyon sınıfı. Örneğin. diziler yüklenemez: public Name this [ PhoneNumber number ] { . bunu kullanabilirsiniz: Hashtable ages = new Hashtable().. 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. // bits bir dizinleyici içerir Method(ref bits[1]). Örneğin. 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. ages[“John”] = 42.Add(“John”. } n Dizinleyiciler ref ya da out parametreleri olarak kullanılamazlarken dizi öğeleri kullanılabilir: IntBits bits. otomatik olarak aşağıdaki koda dönüştürülür: bits[6] = bits[6] ^ true. Ancak. aşağıdaki ifadeyi düşünün: bits[6] ^= true. ages.. } public PhoneNumber this [ Name name ] { . 42).. ama diziler yalnızca tamsayı girdi kullanabilir: public int this [ string name ] { . dizinleyicilerle diziler arasında bazı önemli farklar vardır: n Dizinleyiciler sayı olmayan girdi kullanabilirler. Bu kod. şunun yerine: Hashtable ages = new Hashtable(). Dizinleyicilerle Dizileri Karşılaştırmak Bir dizinleyici kullandığınızda.

} set { this.Data. bu karmaşık ve bellek kullanımı açısından pahalı bir işlem olabilir. .data = value. .. . } } } Bununla birlikte. myData değişkenindeki öğelere yaptığınız her değişiklik data dizisine yapılır.Bölüm 16 Dizinleyicileri Kullanmak 301 Özellikler. public int[] Data { get { return this.Clone() as int[]. Dizinleyiciler bu soruna doğal bir çözüm sunmaktadır: tüm diziyi bir özellik olarak göstermeyin. myData[1]++. } } } Şimdi bu özelliği kullanan aşağıdaki kodu düşünün: Wrapper wrap = new Wrapper(). int[] myData = wrap. . myData[0]++ ifadesinin etkisi data[0]++ ile aynıdır. public int[] Data { get { return this.. İstediğiniz bu değilse.data = value. yalnızca bağımsız öğelerini bir dizinleyici içinden kullanılabilir kılın: struct Wrapper { private int[] data.. bir dizi özelliğine sahip yapıya bakın: struct Wrapper { private int[] data. Aşağıdaki Data (Veri) adlı.. ayarlanan değerin bir kopyasını almalısınız..data. . myData[0]++. Ancak..) struct Wrapper { private int[] data. (Clone yöntemi. 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[]. bir tamsayı diziye dönüştürmeniz gereken bir nesne döndürür. 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.. 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. } set { this.data.. Bu zararsız görünmektedir.

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

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

Code and Text Editor penceresinde PhoneBook. } . Formu kapatın ve Visual Studio 2008’e dönün. Bu düğmeler şu anda hiçbir iş yapmaz. Debug menüsünde Start Without Debugging’ i tıklayın. get erişimcisinin gövdesini boş bırakın. Bu yöntem daha büyük iki dizi yaratır. Amacı adlar için bir tutucu görevi görmektir. Dizinleyicileri yazın 1.. Name yapısına çok benzer..cs kaynak dosyasını görüntüleyin. Code and Text Editör penceresinde PhoneNumber. 7. 5. PhoneBook.. Ad. sonuncusu da bir telefon numarası verildiğinde ad bulmak için.304 Kısım III Bileşenler Yaratmak 3. 4. PhoneNumber yapısını inceleyin.. Bu yöntem Add düğmesi tıklandığında çağrılır. Text adlı salt okunur dize özelliği kullanılarak ad alınabilir. 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. kurucuya bir dize olarak sağlanmıştır. Code and Text Editor penceresinde Name. (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). Proje oluşturulup çalıştırılır. PhoneBook sınıfı ayrıca. telefon defterine ad ve telefon numarası ekleyen bir Add yöntemine sahiptir. 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. Form ayrıca üç düğme içerir: biri bir ad/telefon numarası çifti eklemek için. Name ve Phone Number olarak adlandırılmış iki boş metin kutusu gösteren bir form belirir. Dizinleyici şöyle görünmelidir: sealed class PhoneBook { . diğeri bir ad verildiğinde telefon numarasını bulmak için.cs kaynak dosyasını görüntüleyin.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. Name yapısını inceleyin. 6. public Name this [PhoneNumber number] { get { } } . Göreviniz bu düğmeleri çalışır duruma getirmek için uygulamayı tamamlamak.cs kaynak dosyasını görüntüleyin ve PhoneBook sınıfını inceleyin. var olan dizilerin içeriğini bunlara kopyalar ve ardından eski dizileri atar.

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

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

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

. Örneğin: interface IRawInt { bool this [ int index ] { get. bunun anlamı adın telefon defterinde bulunamadığıdır. 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.. Bu kez Phone Number kutusu boştur.. 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. public bool this [ int index ] { get { . } set.308 Kısım III Bileşenler Yaratmak 5. Örneğin: struct RawInt { .. Save iletişim kutusu görünürse.. } . 7. } set { .. } } .. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Dizinleyicinin gövdesi bir get ve/veya set erişimcisi içerebilir.. } Bir arabirimde bir dizinleyici tanımlamak Dizinleyiciyi get ve/veya set anahtar sözcükleri ile tanımlayın. 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. Formu kapatın ve Visual Studio 2008 programlama ortamına dö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. Name kutusuna tümüyle yeni bir ad girip Search by Name’ i tıklayın. ardından anahtar sözcük this’i ve köşeli parantez arasında dizinleyici bağımsız değişkenlerini ekleyin.

. bool IRawInt... } } . Örneğin: struct RawInt : IRawInt { .. } ] .. } ] 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... public bool this [ int index { get { ..... } set { .. } } .. } set { ...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. ancak dizinleyici erişilebilirliğini belirtmeyin. Örneğin: struct RawInt : IRawInt { ..this [ int index { get { .

.

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

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. private WeldingMachine welder. .. gerektiğinde tüm makineleri kapatacak bir yöntem sağlamaktır! Not API. Bir yazılımı denetleyebilmeniz için yazılım tarafından sağlanan bir yöntem ya da yöntemler topluluğudur. private PaintingMachine painter. birbirine kaynak yapan. . işlev işaretçilerinin aksine. üretimde (metal folyoları biçimlendiren ve büken. Sizin göreviniz. temsilciler tür güvenlidir.NET Framework’u bir API’ler topluluğu olarak düşünebilirsiniz çünkü . gibi) farklı görevler gerçekleştirilen birçok farklı makine içerir. Not C++ biliyorsanız bir temsilci. makineler tarafından kullanılan farklı sistemleri tek bir denetleme programında birleştirmektir. “Application Programming Interface”in kısaltmasıdır. PaintOff(). Otomasyonlu Fabrika Senaryosu Otomasyonlu bir fabrika için denetim sistemlerini yazdığınızı varsayalım.312 Kısım III Bileşenler Yaratmak çalıştığında farklı bir yöntem çalıştırabilir. 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. Temsilcileri anlamanın en iyi yolu onları işbaşında görmektir. boyayan vb.NET çalışma zamanı katmanı ve Microsoft Windows işletim sistemini denetlemenizi sağlayan yöntemler sağlar. işlev işaretçisine benzer. Bunlar aşağıda özetlenmiştir: StopFolding(). Her makine uzman kişilerce üretilip kurulmuştur. Ancak. bu yüzden gelin bir örnek üzerinde çalışalım. Fabrika.. . Makinelerin tümü bilgisayar denetimli olup her dağıtıcı makinelerini denetlemeniz için bir dizi API (Uygulama Programlama Arabirimi) sağlamıştır. Her makinenin güvenle kapanmak için kendine özgü bilgisayar denetimli bir süreci (API) vardır. Odaklanmaya karar verdiğiniz yönlerden birisi.

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

stopMachinery += welder. Temsilciyi aşağıdaki gibi çalıştırarak yöntemi çağırabilirsiniz public void ShutDown() { this..StopFolding. Temsilciye yöntemi eklersiniz.stopMachinery(). Temsilcinin başvurduğu yöntem parametre alıyorsa bunları bu aşamada belirtmeniz gerekir.FinishWelding. bu aşamada yöntemi çağırmanız söz konusu değildir. tek bir özel yöntemle açıkça başlatabilirsiniz: this. this. Not Başlatılmamış bir temsilciyi çalıştırmaya çalışırsanız bir NullReferenceException özel durumu oluşur.stopMachinery += painter.stopMachinery -= folder.stopMachinery()’yi çalıştırmak otomatik olarak her yöntemi sırayla çağırır. this. Başlatılmamış temsilci üzerinde += işlecini kullanmak güvenlidir. Bunları aşağıdaki gibi temsilciye eklemek için += işlecini kullanmanız yeterlidir: public Controller() { this. Shutdown yönteminin kaç adet makine bulunduğunu ya da yöntemlerin adlarının ne olduğunu bilmesi gerekmez.. Bir temsilci kullanmanın asıl yararı birden çok yönteme başvurabilmesidir. .stopMachinery = new stopMachineryDelegate(folder. } Controller sınıfının Shutdown (Kapat) yöntemindeki this. Otomatik olarak başlatılacaktır.StopFolding). Yalnızca yöntemin adını belirttiğinize ve herhangi bir parantez ya da parametre eklememeniz gerektiğine dikkat edin. aşağıdaki gibi new anahtar sözcüğünü kullanarak bir temsilciyi.StopFolding. -= işlecini kullanarak bir yöntemi temsilciden silebilirsiniz: this. . Ayrıca.PaintOff.stopMachinery += folder. } Bir temsilciyi çalıştırma bir yöntem çağrısı yapmayla aynı sözdizimini kullanır.314 Kısım III Bileşenler Yaratmak Bu sözdizimine alışmak biraz zaman alabilir. 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. (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. ancak buna erişim sağlamak için bir okuma/yazma özelliği sağlayın: public delegate void stopMachineryDelegate(). stopMachineryDelegate türünü genel yapmanız ve Controller dışındaki sınıfların temsilciye yöntem eklemesinin bir yolunu bulmanız gerekir.. public stopMachineryDelegate StopMachinery { get { return this. } } n Ayrı Add ve Remove yöntemleri uygulayarak tam bir kapsülleme sağlayın. Birkaç seçeneğiniz vardır: n stopMachinery temsilci değişkenini genel yapın: public stopMachineryDelegate stopMachinery. . Ancak. Add yöntemi bir yöntemi parametre olarak alıp temsilciye eklerken Remove yöntemi belirtilen yöntemi temsilciden kaldırır.stopMachinery -= stopMethod. } public void Remove(stopMachineryDelegate stopMethod) { this. . n stopMachinery temsilci değişkenini özel olarak tutun.stopMachinery = value. } set { this.. } Nesne yönelimli programcılıktan ödün vermeyenlerdenseniz büyük olasılıkla Add/Remove yaklaşımını benimseyeceksiniz. makine yöntemlerini Controller kurucusundaki temsilciye ekler.stopMachinery += stopMethod.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 315 Geçerli düzen. Controller sınıfinı çeşitli makinelerden tam bağımsız kılmak için.

. Ticker. FoldingMachine folder = new FoldingMachine(). control... Dijital saat uygulamasını tamamlayın 1.. Start’ı. PaintingMachine painter = new PaintingMachine(). control. Bu bölümü gece yarısı okumuyorsanız. control.. Bu dosya bir saatin iç çalışma düzenini modelleyen Ticker adlı bir sınıf içerir. 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().Add(painter. 4. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step by Step\Chapter 17\ Delegates klasöründe yer alan Delegates projesini açın.FinishWelding).ShutDown().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. Start ve Stop yöntemleri henüz geliştirilmemiştir.PaintOff). Bir dijital saat gösteren form görünür. Hiçbir şey olmaz.. 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. 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.Timers..Add(welder.StopFolding).Add(folder. Formu kapatın ve Visual Studio 2008 ortamına geri dönün. control. 6. Microsoft Visual Studio 2008’i başlatın. Sizin göreviniz bu yöntemleri geliştirmektir 5. . Temsilciler Kullanmak Şimdiki alıştırmada. Bu temsilci nesnesini. Saat o anki saati “00:00:00” olarak gösterir.Timer nesnesi kullanır. 3. Daha sonra. her saniye bağlı temsilciyi çağıran Ticker adında bir sınıfa bağlayacaksınız. WeldingMachine welder = new WeldingMachine(). saat yanlış zamanı göstermektedir. Proje oluşturulur ve çalıştırılır. sonra da Stop’u tıklayın. . Debug menüsünde Start Without Debugging’ i tıklayın. . 2.cs kaynak dosyasını açıp Code and Text Editor penceresinde görüntüleyin. Her saniye bir titreşim göndermeyi sağlayan ticking adlı bir System.

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

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

stopMachinery += folder. Tekrar Start’ı tıklayın.StopFolding. aynı sözdizimini kullanarak. Formu kapatın ve Visual Studio 2008 ortamına geri dönün. . folder nesnesinin StopFolding (DurdurKatlama) yöntemini stopMachinery (durdurMekanizma) temsilcisine eklemek için aşağıdakini yaptık: this. Görüntü işlemeye devam eder ve zamanı her saniye güncelleştirir.Start yöntemini çağırıyor olmasıdır.StopFolding(0). // Hemen kapat } Daha sonra. Saat durmadan önce bu başvuruların tümünü kaldırmanız gerekir.stopMachinery += folder. aşağıdaki gibi. 15. 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). Örneğin. 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. temsilciye RefreshTime yöntemine bir başvuru eklersiniz. Temsilcinin imzasıyla eşleşen uygun bir yöntem varsa bu yaklaşım çok yararlıdır. // 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. Stop’u da aynı sayıda tıklamanız gerekir. Bunun nedeni. StopFolding’i çağıran ama kendisi hiçbir parametre almayan başka bir yöntem yaratmaktır: void FinishFolding() { folder. 16. daha önce gösterilen otomasyonlu fabrika senaryosuna dönersek. Bir Yöntem Bağdaştırıcısı Yaratmak Bu problemi çözmenin yolu. Start’ı her tıkladığınızda. stopMachinery temsilcisine StopFolding yöntemi yerine FinishFolding yöntemini ekleyebilirsiniz: this. Start düğmesinin artık RefreshTime yöntemini Ticker temsilcisine bağlayan Clock.FinishFolding.Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 319 Not Start’ı birden çok tıklarsanız.

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

böylece ++ işlemi ifade ile kısıtlı kalır. ifade bir değer döndürebilir. ama döndürmeyebilir de. int y) { x++. y) => { x++. () => folder. derleyici parametre türleri çıkarır. } // // // // // (ref int x. stopMachinery temsilcisini çağırdığınızda. } // // // // // Lambda deyiminin bilmeniz gereken bazı özellikleri aşağıda özetlenmiştir: . birçok orijinal ilke yine de uygulanır. lambda deyimlerinin uygulanmasında.StopFolding(0) .Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 321 bir deyim içeriyorsa. 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. Parametre x değeri tarafından geçirilir.StopFolding(0) // // // // (x. Lambda deyimler aslında. Lambda Deyimlerinin Biçimi Lambda deyimler. return x / y. lambda deyimi tarafından tanımlanan kod çalışacaktır. C# dili. x => { return x * x . Bir yöntem çağırma ifade hiçbir parametre almıyor. Birden çok parametre. işlevleri (işlevi. return x / y. 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.stopMachinery += () => folder. küme parantezlerini ve noktalı virgülü kullanmayabilirsiniz (ifadeyi tamamlamak için yine de bir noktalı virgül gerekmektedir): this. Lambda Calculus sözdizimini ve anlam bilimini geliştirmiş olmakla birlikte. 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. } // 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. çok sayıda farklı biçim alabilir.

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

NET Framework’te olaylar önemli eylemleri tanımlayıp yakalamanıza ve durumu işlemek için bir temsilci ayarlamanıza olanak verir. bir temsilci türünün nasıl bildirildiğini. . bu hikayenin yarısıdır.NET Framework’deki birçok sınıf. Birçok durumda. 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. Temsilciler herhangi bir sayıda yöntemi dolaylı olarak başlatmanıza izin verse de temsilciyi açık biçimde başlatmanız gerekir. . temsilcinin nasıl çağrıldığını ve temsilci örneklerinin nasıl yaratıldığını gördünüz. Örneğin. Ancak. her makinenin ısısını izleyen bir sınıf olabilir. 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. Bir WPF formu üzerine yerleştirebileceğiniz denetimlerin çoğu ve Windows sınıfının kendisi. ö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. Bir olay bildirmek için aşağıdaki sözdizimini kullanın: event delegateTypeName eventName Örneğin.. . Bir olayı. 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 fabrikada bir olay kaynağı. işte otomasyonlu fabrikadaki StopMachineryDelegate temsilcisi. } . önemli bir şey olduğunda temsilciyi otomatik olarak çalıştırmak yararlı olur. Ayrıca kendi olaylarınızı da tanımlayabilirsiniz. Bir Olay Bildirmek Bir olayı. Çağrılan olay bir yöntemler listesi barındırır. Bu. bir makine aşırı ısındığında stopMachinery temsilcisini başlatmak ve makineyi durdurmak önemli olabilir. Bu yöntemler “makine aşırı ısınması” olayını işlemeye ve gerekli önlemi almaya. olaylar sergiler. Bu yöntemlere bazen aboneler denir. Ancak. bir alanı bildirir gibi bildirirsiniz. otomasyonlu fabrika senaryosunda. 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. olay için Controller sınıfından daha mantıklı bir yerdir): class TemperatureMonitor { public delegate void StopMachineryDelegate(). olay kaynağı olarak düşünülmüş bir sınıfta bildirirsiniz..Bölüm 17 Program Akışını Kesmek ve Olayları İşlemek 323 Bildirimleri Olaylarla Etkinleştirmek Bir önceki bölümde.

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

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

. } Bu kod genellikle sizden saklanır.. public partial class Example : System. 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..okay.. private void okayClick(object sender.Windows. Aşağıdaki örnek. } 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). { public event RoutedEventHandler Click... okayClick’de yazmaktır.Click += new System. 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.IComponentConnector. Yapmanız gereken. uygulama mantığınızı. Example.. okayClick’e okay düğmesinin Click özelliğini atadığınızda.Windows.Window. .326 Kısım III Bileşenler Yaratmak Button sınıfı şunun gibi görünür: public class ButtonBase: .. Olaylar.Windows. okay adlı bir düğme. System. } public class Button: ButtonBase { . } ...Button okay. imzası bir void dönüş türü ve iki bağımsız değişkeni olan bir temsilci türüdür. Visual Studio 2008’te Design View kullandığınızda ve formun Extensible Application Markup Language (XAML) tanımında.) { .Markup.Windows.Windows.Windows. this.Markup. .. . olay işleme yöntemi.xaml. İlk bağımsız değişken her zaman . Bu düzenleme.Window { ..Connect(... void System.. Visual Studio 2008 bu kodu sizin için üretir.. seçilen bir yöntem için temsilci yaratma ve bu temsilciyi gerekli bir olaya bağlama işini kolaylaştırır.RoutedEventHandler(this.IComponentConnector { internal System.okayClick)..Controls.

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

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

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

Örneğin: class MyEventHandlingClass { . ardından türün adını (tür bir temsilci türü olmalıdır) ve olayın adını ekleyin.eventHandlingMethod.. abonelik yöntemini belirterek derleyicinin yeni temsilciyi otomatik olarak oluşturmasını sağlayabilirsiniz: public void Start() { myClass. private void myMethod() { . Bir temsilciyi çağırmak Bir yöntem çağrısıyla aynı sözdizimini kullanın. } Ayrıca. . Örneğin: myDelegate del... } . del()... Örneğin: delegate void myDelegate(). } private MyClass myClass = new MyClass().. } private void 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.330 Kısım III Bileşenler Yaratmak Temsilcinin. ardından türün adını (temsilcinin adını) ve parantez içinde bağımsız değişkeni ekleyin. Örneğin: delegate void myEvent()..eventHandlingMethod). public void Start() { myClass. class MyClass { public event myDelegate MyEvent.MyEvent += this. 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. myDelegate del = new myDelegate(this. Bağımsız değişken imzası tam olarak temsilcinin imzasına uyan bir yöntem olmalıdır. } . Bir olay bildirmek event anahtar sözcüğünü yazın...MyEvent += new myDelegate (this.myMethod).

Örneğin: class MyEventHandlingClass { .MyEvent != null) { this. } Ya da: public void Stop() { myClass.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. } .MyEvent -= new myDelegate (this. . } } . } private void eventHandlingMethod() { .. private void RaiseEvent() { if (this.eventHandlingMethod).. Olayın türünü eşleştirmek için bağımsız değişkenleri sağlamalısınız.MyEvent()......eventHandlingMethod. public void Stop() { myClass. Örneğin: class MyClass { public event myDelegate MyEvent. Olayın null olup olmadığını denetlemeyi unutmayın. } private MyClass myClass = new MyClass()..MyEvent -= this. } Bir olayı başlatmak Olay bir yöntemmiş gibi parantezleri kullanın.

.

object türünü herhangi bir türün değerini depolamak için kullanabilirsiniz. System. Nesnelerle İlgili Sorunlar Generics’i anlamak için bunların çözmeyi amaçladığı.Collections. Bu bilgiyi oldukça genelleştirilmiş sınıf ya da yöntemler yaratmak için kullanabilirsiniz. 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. Aşağıdaki kod parçası Circle nesnelerinin bir kuyruğunu oluşturup yönetmeyi göstermektedir: 333 . Bir yönteme herhangi bir tür değer geçirmeniz gerektiğinde object türünü kullanarak parametreler tanımlayabilirsiniz. bu tür hataları önlemenize yardımcı olması için tasarlanmış bir özellik olan Generic’i öğreneceksiniz. (Bölüm 10’da koleksiyon sınıflarını gördünüz) Ayrıca.Object sınıfından kalıtımla alırlar. Örneğin. özellikle object türünü kullanırken oluşan sorunlara yakından bakmak yararlıdır. Tüm başvuru türleri otomatik olarak (doğrudan ya da dolaylı olarak) . Parametre olarak belirtilen türlere dayanarak bir generic sınıfı örneklerini yaratmak. System.NET Framework’teki System. Bu bölümde.Queue sınıfında şunu fark edersiniz: Hemen her şeyi içerebilen kuyruklar yaratabilirsiniz.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. 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. Generic bir arabirim uygulamak. 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. Üzerinde çalıştığı verinin türünden bağımsız bir algoritma uygulayan bir generic yöntem tanımlamak. object türünü herhangi bir değer ya da değişkene başvuru olarak kullanabilirsiniz.

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

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

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

öğelere dizi gösterim biçimini kullanarak erişmenize olanak veren bir dizinleyici sağlar.Queue<T> sınıfıyla karşılaştırın.Collections. set. } Dizinleyicinin. System. Bu sınıfı bir tür parametresiyle (Queue<int> ya da Queue<string> gibi) kullandığınızda aslında derleyicinin. 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. Person john = new Person(). Bu aşağıdaki gibi tanımlanır: public virtual TValue this[ TKey key ] { get..Generic.Queue sınıfı genelleştirilmiş bir sınıftır. Collections.Bölüm 18 Generics’e Giriş 337 (Sözlük) sınıfı.) 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). Bu sınıfın tek bir uygulaması vardır ve yöntemleri object parametreleri alıp object türleri döndürür. 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 { . directory[“John”] = john. Dictionary sınıfıyla ilgili ayrıntılı bilgi için Visual Studio 2008 belgelerini okumalısınız. Bunu System. string ve diğer birçok türle kullanabilirsiniz.... Person>(). Generic Queue sınıfında olduğu gibi. Generic sınıfın bu türe özel sürümleri (Queue<int>. Person author = directory[“John”]. . Generic bir sınıfı.. Not Generic sınıflarla aynı sözdizimini kullanarak generic yapı ve arabirimleri de tanımlayabilirsiniz. Dictionary<string. . ancak bunların tümü aynı sınıfın örnekleridir. anahtar ya da TKey türü kullanarak TValue türü değerlere eriştiğine dikkat edin. } . 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. Örneğin. işlevselliği generic sınıf tarafından tanımlanan tamamen yeni bir sınıf yaratmasına neden olursunuz.. Bu sınıfı int. derleyici Person yapıları dışındaki değerleri depolama girişimlerini yakalar ve anahtarın her zaman bir string türü olduğunu garantiler. Queue<string> vb. Person> directory = new Dictionary<string.

ya boş olan ya da üç öğe içeren. Kuramsal olarak. bir PrintableCollection sınıfı tanımlıyorsanız.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. kendileri de ikili ağaç olan iki alt ağaç. Bunu yapmadan önce. Bir ikili ağaç. 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. Bunun yerine. Bu çok pratik bir alıştırmadır çünkü bu sınıf System.Collections. 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. İkili Ağaçlar Kuramı Aşağıdaki alıştırmalarda. kullanımınıza hazır bazı generic sınıflar içerir. kendi kendine başvuran) bir veri yapısıdır: node (düğüm) olarak adlandırılan bazı verilerle. Örneğin. recursive (özyinelemeli. İkili ağaç. Şekil 18-1 küçük bir ikili ağacın yapısını göstermektedir. Bu bölümde de bunu yapacaksınız.Generic ad alanında eksik olan sınıftır. 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.NET Framework sınıf kütüphanesi. Örneğin. . biraz arka plandaki teoriyi görelim. ancak ikili ağaçları ayrıntılı biçimde anlatmak bu kitabın amacı değildir. İkili ağaçların incelikleri üzerine yazılmış ciltler dolusu kitap vardır. ilgili ayrıntılara bakmakla yetineceğiz. bir ikili ağaç gösteren bir sınıf tanımlayıp kullanacaksınız. 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 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. Bir sınırlama kullanarak. Bir Generic Sınıf Yaratmak . 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. tüm yapı sonsuza dek sürebilir. Bu koşulu bir constraint (sınırlama) kullanarak belirtebilirsiniz. Ayrıca kendi generic sınıflarınızı da tanımlayabilirsiniz.

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 . Aynı türde sırasız nesneler dizisiyle başlarsanız. 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. T. N. 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. geçerli düğmünün. İkili ağaçların gerçek güçleri bunları veri sıralamak için kullandığınızda açığa çıkmaktadır.Bölüm 18 Generics’e Giriş 339 ŞEKİL 18-1 Bir ikili ağaç.

ŞEKİL 18-2 Sıralı bir ikili ağaç oluşturmak. Sıralı bir ikili ağaç oluşturduktan sonra. 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. Şekil 18-2. Boş bir ikili ağaç ve sıralanmamış bir nesneler dizisiyle başlarsanız. metin için bu bir dize karşılaştırması olabilir. beş tamsayıdan bir ağaç oluşturma işlemindeki adımları göstermektedir. Sayısal veriler için büyüktür ifadesi basit bir aritmetik karşılaştırma olabilir. “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. öğeyi sol ya da sağ ağaca eklemek için kendini çağırır. öğenin değerine ve ağaçtaki geçerli düğüme bağlı olarak. her düğümü sırayla ziyaret ederek ve bulunan veriyi yazdırarak içeriğini görüntüleyebilirsiniz. Sonraki bölümde. Not Büyüktür ifadesinin tanımı öğe ve düğümdeki veri türüne bağlıdır. 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.

hemen her tür veriyi tutabilen bir ikili ağaç sınıfı tanımlamak için generic kullanacaksınız. Tek kısıtlama. İkili ağaç sınıfı birçok farklı uygulamada yararlı bulacağınız bir sınıftır. bir sınıf kitaplığı olarak kullanacaksınız.dll” sonekli bir dosyadır. 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. Bir birleştirme genellikle “. . Tamsayıların şimdi artan sırayla görüntülendiğine dikkat edin. İkili ağaç sınıfını sınarken bunu yapacaksınız. kaynak kodu kopyalamaya ve yeniden derlemeye gerek kalmadan başka yerlerde yeniden kullanabilirsiniz. ŞEKİL 18-3 Sıralı bir ikili ağaç yazdırmak. Diğer proje ve uygulamalar. derlenmiş sınıflardan (yapı ve temsilci gibi diğer türlerden) oluşan ve bir birleşimde depolanan bir kümedir. veri türünün farklı örnekler arasındaki değerleri karşılaştırması için bir yöntem sağlaması gerektiğidir. Generics Kullanarak İkili Ağaç Sınıfı Oluşturmak Aşağıdaki alıştırmada. Daha sonra bu sınıfı. Bu yüzden. bunu kendi içinde bir uygulama değil. Bir sınıf dosyası.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.

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

IComparable arabiriminin Area yöntemine erişebilmesi bir dönüştürme kullanımını gerektirir. Aşağıdaki kod bu arabirimi Circle sınıfında nasıl uygulayabileceğinizi göstermektedir: class Circle : System.Bölüm 18 return -1. .IComparable<Circle> { .Area() > other. bool Equals(T other). Bu arabirimde Equals adlı ek bir yöntem bulunduğuna dikkat edin. if (this. 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.IComparable<T> arabirimini System. IComparable arabirimine tercih etmeniz gerekir. değilse false döndürmelidir.Area() == other.. System. 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. her iki örnek de eşitse true. . } } CompareTo ve Equals yönteminin parametreleri IComparable<Circle> arabiriminde belirtilen türle eşleşmelidir.Area()) return 0. System ad alanı ayrıca aşağıdaki yöntemleri içeren generic IComparable<T> arabirimini tanımlar: int CompareTo(T other).IComparable arabirimini incelerseniz.NET Framework’teki birçok türün yaptığı gibi her ikisini de uygulayabilirsiniz. } public bool Equals(Circle other) { return (this.. public int CompareTo(Circle other) { if (this. Genel olarak. Ancak bu yaklaşım tür-güvenli değildir. Bu yöntem. Ancak.Area()) return 1.CompareTo(other) == 0). Ayrıca. } } Generics’e Giriş 343 System. System. Parametre bir Circle değil başka tür bir nesneyse bu dönüştürme başarısız olur. return -1.

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

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

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

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

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

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

Are.NET Framework’ü generic yöntemler yaratmak için de kullanabilirsiniz. Takas edilen veri türüne bakılmaksızın. Bu şekilde tür güvenli genelleştirilmiş yöntemler tanımlayabilir ve dönüştürme (ve bazı durumlarda kutulama) zahmetinden kurtulabilirsiniz. tree2. Hello. World. Feeling. tree2. tree2.Insert(“I”). 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.Insert(“Today”). tree2. ref T second) { . You 13. I. You.WalkTree(). Debug menüsünde Start Without Debugging’ i tıklayın. Bir Generic Yöntem Yaratmak Generic sınıflar tanımlamanın yanı sıra . Örneğin. tree2. 11. Çözümün derlendiğini doğrulayın ve varsa hataları düzeltin.Insert(“You”).Insert(“!”). Bu kez veri alfabetik olarak sıralanır. 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).350 Kısım III Bileşenler Yaratmak Tree<string> tree2 = new Tree<string>(“Hello”).Insert(“Hope”).Insert(“Well”). bu işlevsellik yararlı olduğundan onu generic bir yöntem olarak tanımlamak iyi olur: static void Swap<T>(ref T first. 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: !. Generic yöntemleri. Hope. } Bu ifadeler dizeleri tutmak için başka bir ikili ağaç yaratır. tree2. Today. tree2. Visual Studio 2008’e dönmek için Enter tuşuna basın.Insert(“Are”). tree2.Insert(“You”). How. tree2. 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).Insert(“Feeling”). aşağıda gösterilen generic Swap<T> yöntemi. Build menüsünde Build Solution’ ı tıklayın. tree2. tree2. tree2. parametrelerdeki değerleri değiş tokuş etmek için kullanılabilir. tree2.Insert(“World”). onu bazı sınama verileriyle doldurur ve ardından ağacı yazdırır. 12.Insert(“How”).Insert(“Are”). Are. Well.

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

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

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

Örneğin: InsertIntoTree<char>(charTree. 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. Örneğin: static void InsertIntoTree<TItem> (Tree<TItem> tree. Örneğin: public class Tree<TItem> where TItem : IComparable<TItem> { ... . } 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. } Bir generic yöntem tanımlamak Tür parametrelerinin her biri için türler sağlayın.. Save iletişim kutusu görünürse. params TItem[] data) { ... } Bir generic yöntem tanımlamak Tür parametreleri kullanarak yöntemi tanımlayın. ‘Z’.354 Kısım III Bileşenler Yaratmak File menüsünde Exit’i tıklayın. Örneğin: public class Tree<TItem> { .. Bir tür parametresi kullanarak sınıfı tanımlayın. ‘X’). Örneğin: Queue<int> myQueue = new Queue<int>(). 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.

Collections. Farklı dizilerdeki koleksiyon öğelerinin içine girebilen ek yineleyiciler sağlamak. 2 }. numaralandırılabilir koleksiyon tam olarak nedir? Bunun bir yanıtı. 355 .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. 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. Kendi koleksiyon sınıflarınızı tanımlamaya başladığınızda bu konu önem kazanır. System. Not C#’taki tüm dizilerin aslında System. foreach ifadesini yalnızca bir koleksiyonun içeriğine erişmek için hızlı ve uygun bir yöntem olarak kullandınız. Peki. IEnumerable arabirimini kullanan bir koleksiyon sınıfıdır. Array sınıfı. 3. yazmanız gereken kodu basitleştiren şık bir düzenek sağlar.IEnumerable arabirimini kullanan bir koleksiyon olduğudur. } foreach yapısı. bu sürecin çoğunun otomatik olarak yapılmasına yardımcı olan yineleyiciler sağlar. Kod aşağıdakine benzemekteydi: int[] pins = { 9. 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.WriteLine(pin). Koleksiyondaki Öğeleri Numaralandırmak Bölüm 10’da. C#. Bir yineleyici yaratarak bir numaralandırıcıyı otomatik olarak uygulamak. 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). System.Array sınıfının örnekleri olduğunu unutmayın. öğeleri basit bir dizide listelemek için foreach ifadesini kullanmanın bir örneğini gördünüz. Orada. 7. Neyse ki. ancak artık bu ifadenin gerçekten nasıl çalıştığı konusunda biraz daha bilgi edinmenin zamanıdır. foreach (int pin in pins) { Console.

başka bir öğe varsa true. Önemli İlk bakışta. işaretçiyi listedeki ilk öğenin öncesine geri döndürmek içinse Reset yöntemini kullanırsınız. İşaret edilmekte olan öğeye erişmek için Current özelliğini. void Reset(). IEnumerator arabirimi.356 Kısım III Bileşenler Yaratmak IEnumerable arabirimi GetEnumerator adlı tek bir yöntem içerir: IEnumerator GetEnumerator(). bir Reset yöntemi içermez.NET Framework 2. 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. Benzer biçimde. System. . aşağıdaki özellik ve yöntemleri belirtir: object Current { get. Not IEnumerator<T> arabiriminin IEnumerator arabiriminden bazı başka farkları da vardır. Birbirine karıştırmayın. } bool MoveNext().Collections. GetEnumerator yöntemi. listede sonraki (ilk) öğeye taşımak için MoveNext yöntemini çağırırsınız. Numaralandırıcı nesne koleksiyon nesnelerini adımlamak (numaralandırmak) için kullanılır. . Ancak. İşaretçiyi aşağıya. Dolayısıyla. . yoksa false döndürür. IEnumerator arabiriminin Current özelliğinin tür güvenli olmayan bir davranış sergilediğini. ancak IDisposable arabirimini genişletir. ad benzerliklerinden dolayı. Başta işaretçi ilk öğeden öncesini gösterir. çünkü belirli bir tür yerine bir nesne döndürdüğünü fark etmişsinizdir.IEnumerator arabirimini kullanan bir numaralandırıcı nesnesi döndürmelidir. foreach ifadesi tam olarak bunu yapar. bir listedeki öğeleri gösteren bir işaretçi gibi düşünün. IEnumerable<T> ve IEnumerator<T> arabirimlerini karıştırmak çok kolaydır. 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.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. bir Enumerator<T> nesnesi döndüren bir GetEnumerator yöntemi içeren IEnumerable<T> arabirimi vardır. MoveNext yöntemi. Numaralandırıcıyı. İyi bir gözlemciyseniz. kendi numaralandırılabilir koleksiyon sınıfınızı yaratmak istiyorsanız.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.

Bu gereksinimleri karşılamak için. TreeEnumerator sınıf tanımını değiştirin. 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. 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. MoveNext yöntemine yapılan sonraki çağrılar durumu uygun biçimde güncelleştirebilir. Bu nedenle. tür parametresi sınıfın numaralandırdığı Tree<TItem> nesnesi için geçerli bir tür olmalıdır. 4. 2. TreeEnumerator. ö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. IComparable<TItem> arabirimini uygulama ile kısıtlanmalıdır. Bölüm 8’de yarattığınız BinaryTree projesinin çalışan bir kopyasını içerir. 3. Class şablonunu seçin ve Name için TreeEnumerator. Aşağıdaki gibi görünmelidir: class TreeEnumerator<TItem> : IEnumerator<TItem> where TItem : IComparable<TItem> { } . Ne yazık ki. 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. Projeye yeni bir sınıf ekleyin: Project menüsünde Add Class’ı tıklayın. bu dolambaçlı durum ikili ağacın öğelerinde yineleme yapan kullanıcıdan gizlenir! TreeEnumerator sınıfını yaratın 1. 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. Dolayısıyla. Ayrıca. TreeEnumerator sınıfı bir Tree<TItem> nesnesi için bir numaralandırıcı oluşturur. Bu çözüm. yanılırsınız. Böylece.Bölüm 19 Koleksiyonları Numaralandırmak 357 Bir Numaralandırıcıyı Elle Uygulamak Sonraki alıştırmada. Microsoft Visual Studio 2008’i başlatın. Kuşkusuz. Asıl sorun bir numaralandırıcıyı tanımlarken yapının neresinde olduğunuzu anımsamanız gerektiğidir. 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. 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.cs dosyasını gösteren Code and Text Editor penceresinde.cs yazıp Add komutunu tıklayın. Dolayısıyla.

private Queue<TItem> enumData = null. 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.RightTree != null) { populate(enumQueue. 6. “Bir Tür Parametresi ile Tanımlanan Bir Değişken Başlatmak” başlıklı bölümde açıklanmıştır.358 Kısım III Bileşenler Yaratmak 5.. default anahtar sözcüğü. } enumQueue. 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.LeftTree). } . } 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 . Tree<TItem> tree) { if (tree. MoveNext yöntemi her öğeyi bu kuyruktan sırayla döndürür.. .RightTree). data adlı tek bir Tree<TItem> parametresi alan bir TreeEnumerator kurucusu ekleyin. private TItem currentItem = default(TItem). 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. Aşağıdaki populate adlı özel yöntemi. enumData kuyruğunu ağaçtaki düğümlerden alınan değerlerle dolduracaksınız. tree.currentData = data. TreeEnumerator<TItem> sınıfına.NodeData). } } Bu yöntem bir ikili ağaçta gezinirken içerdiği veriyi kuyruğa ekler. Temel fark olarak.LeftTree != null) { populate(enumQueue. tree.Enqueue(tree. NodeData değerleri ekrana yazdırılmak yerine kuyrukta depolanır. } 7. kurucudan sonra ekleyin: private void populate(Queue<TItem> enumQueue.

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

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

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

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

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

Ve her öğeyi sırayla döndürür. BasicCollection<T> sınıfının IEnumerable<T> arabirimini uyguladığına da dikkat edin. Önemli nokta.Collections. data dizisindeki öğeler içinde döner.Add(datum). using System.Collections.GetEnumerator() { // Bu örnekte uygulanmaz } } GetEnumerator yöntemi oldukça açık görünmektedir. Basit Bir Yineleyici Aşağıda gösterilen BasicCollection<T> sınıfı. Sonuçta. Sınıf.GetEnumerator() { foreach (var datum in data) yield return datum. Bu noktada yineleme tamamlanmıştır. ancak daha yakından bakmayı gerektirir. Ç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. bir yineleyici uygulamanın temel ilkelerini göstermektedir. 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. 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. döngü durur ve GetEnumerator yöntemi sonlanır. } IEnumerator IEnumerable. GetEnumerator yöntemi bir yineleyici kullanılarak uygulanır: using System. Bunun yerine. class BasicCollection<T> : IEnumerable<T> { private List<T> data = new List<T>(). veri tutmak için bir List<T> kullanır ve bu listeyi doldurmak için FillList yöntemini kullanır.364 Kısım III Bileşenler Yaratmak yalnızca. } IEnumerator<T> IEnumerable<T>. . yield ifadesini yöntemi geçici olarak durduran ve çağırana bir değer geçiren bir çağrı gibi düşünebilirsiniz.Generic. yield anahtar sözcüğü her yinelemenin döndürmesi gereken değeri gösterir. veri tükenir. yield anahtar sözcüğünün kullanımıdır. using System.

FillList(“Twas”. “slithy”. foreach (string word in bc) Console.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. Twas . “the”. slithy. } } Bu özelliği aşağıdaki gibi başlatabilirsiniz: BasicCollection<string> bc = new BasicCollection<string>(). and. Örneğin. foreach (string word in bc.FillList(“Twas”. i >= 0. the. “and”.Reverse) Console. Aslında oluşturulan bu kodu görmezsiniz (derlenmiş kodu içeren birleşimin derlemesini kaldırmadığınız sürece). “and”. brillig.1. Bu kod bc nesnesinin içeriğini aşağıdaki sırada yazdırır: Twas. i--) yield return data[i]. Derleyici. yineleyici tarafından oluşturulan numaralandırıcıyı her zamanki gibi başlatabilirsiniz: BasicCollection<string> bc = new BasicCollection<string>(). Bu kod bc nesnesinin içeriğini ters sırada yazdırır: toves.WriteLine(word). GetEnumerator yöntemindeki kod bir iterator (yineleyici) tanımlar.Bölüm 19 Koleksiyonları Numaralandırmak 365 Bu genel anlamıyla normal bir yöntem değildir. brillig. “toves”). Bu uygulama GetEnumerator yöntemi tarafından belirtilen işlevsellikle tam olarak eşleşir. the. “brillig”.WriteLine(word). 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. “toves”). 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. “slithy”. ancak yazmanız gereken kodun sağladığı rahatlığı ve kodun kısalığını düşününce bu ödediğiniz küçük bir bedeldir. bc. bc. “the”. “brillig”. and. slithy. Aşağıdaki kod bloğunda görüldüğü gibi.

. Bölüm 18’de oluşturduğunuz BinaryTree projesinin bir başka kopyasını içerir. Implement Interface’i işaret edin ve ardından Implement Interface Explicitly seçeneğini tıklayın. IEnumerable<TItem>. Code and Text Editor penceresinde Tree. MoveNext yöntemi tarafından ağaçtaki verinin bir kuyruğa önceden işlenmesinin gerektiği önceki alıştırmaların aksine. Visual Studio 2008’i kullanarak.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. Tree<TItem> sınıfına bir numaralandırıcı ekleyin 1.LeftTree) { yield return item.GetEnumerator() { if (this. IEnumerable<TItem>. 2.GetEnumerator yöntemleri sınıfa eklenir. } 3. Bu çözüm.NodeData. Sınıf tanımındaki IEnumerable<TItem> arabirimini farenin sağ düğmesiyle tıklayın.LeftTree != null) { foreach (TItem item in this. 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. 4. 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. } } yield return this. GetEnumerator yönteminin içeriğini aşağıda gördüğünüz gibi değiştirin: IEnumerator<TItem> IEnumerable<TItem>.GetEnumerator ve IEnumerable.GetEnumerator yöntemini bulun.cs dosyasını görüntüleyin.. 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> { . .

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

11.. Debug menüsünde Start Without Debugging’i tıklayın.. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.cs dosyasını Code and Text Editor penceresinde görüntüleyin. Program. Program çalışınca değerler öncekiyle aynı sırada görüntülenir: –12. Save iletişim kutusu görünürse. Örneğin: public class Tree<TItem> : IEnumerable<TItem> { . 15 8..368 Kısım III Bileşenler Yaratmak 5. 14.. 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. 6. 5. 10. –8. 10. IEnumerator<TItem> GetEnumerator() { . 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. EnumeratorTest projesi için Program. 0. Visual Studio 2008’e dönmek için Enter’a bası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. 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. 5. Bu yöntemin bir Tree<int> nesnesi gösterdiğini. } } . Çözümü oluşturun ve varsa hataları düzeltin. 7.

. } ...) yield return .. Örneğin: public class TreeEnumerator<TItem> : IEnumerator<TItem> { ... } } bool MoveNext() { . Örneğin: IEnumerator<TItem> GetEnumerator() { for (.. } } 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.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.. TItem Current { get { ...

.

Bu bölümde. birçok uygulama tarafından kullanılabilen önemli bir yaklaşımdan. Tümleşik Sorgu Dili (Language Integrated Query ya da LINQ) olarak adlandırılır. Ancak. belirli kriterlerle eşleşen bir koleksiyondaki öğeleri aramak gibi yaygın görevleri nasıl yerine getirirsiniz? Örneğin. LINQ genişletilmiş yöntemler ve sorgu işleçleri kullanmak. uygulama geliştirme sürecini kolaylaştırmaya karar verdiler. Bununla birlikte. veriyi işleyen kodda da çok sayıda değişiklik yapmanız gerekebilir. veri sorgulama ve işleme için. C#’ın bazı özellikler içermesine karar vermişlerdir. 371 . bir LINQ sorgusunun sonuçlarını önbelleğe nasıl alabileceğinizi açıklamak. 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.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. Customer nesnelerinin bir koleksiyonuna sahipseniz. bu strateji. bu konularda uzun sure düşündüler ve bir uygulamanın veriyi kodun kendisinden sorgulaması için kullanacağı bazı özellikler sağlayarak. n n C# dilinin birçok özelliğini gördünüz. bir uygulamadaki kodun işlenen verinin yapısına oldukça sıkı bağlı hale gelmesine neden olabilir. birçok uygulama bu işlemleri gerçekleştirmek için kendi mantığına sahiptir. yazmak zorunda olduğunuz kod miktarını en az tutmak için. Tarihsel olarak. Bu özellikler. C# dilinin bu ileri seviye özelliklerini nasıl kullanacağınızı öğreneceksiniz. C#’ın veri sorgulama için sağladığı destekten bahsetmedik. LINQ’nun bir sorguyu ertelemesini ve hemen uygulanmasını nasıl sağlayacağınızı. 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ı.NET Framework tasarımcıları. Bununla birlikte. Microsoft . Veri yapısı değişirse. Tümleşik Sorgu Dili (LINQ) Nedir? Tüm uygulamaların veri işlemesi gerekir.

yazılım geliştiricinin veritabanından almak istediği. sorgulanan verinin temel yapısını değiştirebilirsiniz. Yapısal Sorgu Dili (Structured Query Language. Sorgulama işlemlerini gerçekleştiren kodu değiştirmeniz gerekmeden. fakat veritabanı yönetim sisteminden nasıl alacağını tam olarak bilmediği verinin. SQL ifadeleri çağıran bir uygulama veritabanının veriyi nasıl depoladığı ya da veriyi nasıl bulduğu ile ilgilenmez. Örneğin. sözdizimi ve anlambilimi bakımından SQL’e oldukça benzer ve aynı avantajları sağlar. LINQ. SQL) ifadelerini veritabanı yönetim sistemine dağıtırlar. bu bölümde ilişkisel anlamda LINQ kullanımına yoğunlaşılmıştır. Veritabanı yönetim sistemi tarafından kullanılan biçim değişebilir (örneğin. Bu ayrıntılar veritabanı yönetim sisteminin kendisi tarafından denetlenir. fakat yazılım geliştiricinin uygulama tarafından kullanılan SQL ifadelerini değiştirmesi gerekmez. Bununla birlikte. bir XML belgesinde bulunan veri gibi hiyerarşik olarak organize edilmiş veriyi işleyebilir. veritabanını sorgulamak için kullanılan dili. ileri seviye tanımını sağlar. daha esnektir ve daha fazla çeşitte mantıksal veri yapılarını işleyebilir. Bir SQL Server veritabanına erişen yazılım geliştiriciler. LINQ. SQL. Bu nedenle.372 Kısım III Bileşenler Yaratmak LINQ dili tasarımcıları. 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 . yeni bir sürüm yayınlandığında). LINQ dili SQL’e oldukça benzer olmakla birlikte. Microsoft SQL Server gibi ilişkisel veritabanı yönetim sistemlerini ele alarak. veritabanındaki verinin içsel biçiminden ayırır.

new { CustomerID = 5. Not Gerçek dünya uygulamasında. CompanyName = “Grand Industries” }. new { CustomerID = 9. FirstName = “Jackie”. Ancak. new { CustomerID = 3. new { CustomerID = 2. CompanyName = “A Bike Store” }. LastName = “Gee”. LastName = “Harris”. HashTable. new { CustomerID = 7. CompanyName = “A Bike Store” }. new { CustomerID = 8. LastName = “Carreras”. LastName = “Liu”. bir veritabanından bilgiyi elde etmek için . 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. IEnumerable arabirimini geliştiren bir veri yapısında saklanmasını ister. Numaralandırılabilir olduğu sürece ne tür yapı (bir dizi. bu bölümdeki örnekler. CompanyName = “Fitness Hotel” }. “Veriyi Yönetmek” başlıklı Kısım V’te. new { CustomerID = 6. FirstName = “Donald”. FirstName = “Keith”. LastName = “Lang”. CompanyName = “Bike World” }. veriyi bir dosya ya da veritabanından okuyarak bu dizileri yerleştireceksiniz. new { CustomerID = 10. FirstName = “Lucy”. . FirstName = “Janet”. new { CustomerID = 4. LastName = “Blanton”. Bölüm 19’da açıklandığı gibi. CompanyName = “Bike World” }. CompanyName = “Distant Inn” } }. CompanyName = “Grand Industries” }. LastName = “Blackwell”. LastName = “Gates”. FirstName = “Eric”. LastName = “Leavitt”. aşağıdaki kod örneğinde gösterildiği gibi. müşteri ve adres bilgisinin customers ve addresses dizilerinde tutulduğunu varsayar. var customers = new[] { new { CustomerID = 1. FirstName = “Elsa”. CompanyName = “Grand Industries” }. CompanyName = “Fitness Hotel” }. LastName = “Harrington”. FirstName = “Orlando”.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. FirstName = “Donna”. NET Framework tarafından sağlanan özellikler hakkında daha fazlasını öğreneceksiniz. FirstName = “David”.

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

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

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

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

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

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

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

aşağıdaki gibi başka bir şekilde ifade edebilirsiniz: var customerFirstNames = from cust in customers select cust. SQL’e çok benzeyen bir sözdizimi kullanarak LINQ özelliklerini kullanmanızı sağlayabilmek için C# diline sorgu işleçleri eklediler. Sizi bu sıkıntıdan kurtarmak için. Sonuç. LastName = Blanton. from ve select sorgu işleçlerini kullanarak. 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.Select(cust => cust. yani addresses dizisinde var olmayan bir şirket müşterisine sahip olabilirsiniz ve hatta bir şirket addresses dizisinde birden fazla adresde yer alabilir.Bölüm 20 { { { { { { { { FirstName FirstName FirstName FirstName FirstName FirstName FirstName FirstName = = = = = = = = Sorgu Deyimlerini Kullanarak Bellekteki Veriyi Sorgulamak 381 Donna. Country = United Kingdom } Eric. LastName = Liu. her müşterinin uygun şirkete sahip olduğu ve her şirketin de benzersiz bir adrese sahip olduğu varsayılabilir. . LastName = Gates. Bu durumlarda. müşteri ilk adlarının numaralandırılabilir koleksiyonudur. Derleme zamanında. Country = United Kingdom } Jackie. Bu bölümde önceki örneklerde gördüğünüz gibi. 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. from işlecinin select işlecinden önce gerçekleştiğine dikkat edin. LastName = Carreras. LastName = Blackwell. elde ettiğiniz sonuç kesin fakat beklenmeyen bir sonuç olabilir. Sözdizimi. Country = Canada } Lucy. 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. C# derleyicisi. SQL biliyorsanız. Birleştirme işlemleri en iyi şekilde. Sorgu İşleçlerini Kullanmak Önceki bölümlerde. LastName = Harrington.FirstName). LastName = Leavitt.FirstName. Country = United Kingdom } David. deyimi uygun Select yöntemine dönüştürür. Koleksiyonlar aynı seviyede veri bütünlüğü sağlamaz. İlişkisel veritabanında. birleştirdiğiniz veri arasındaki ilişkileri tam olarak anladığınızda çalışır. her müşterinin ilk adını elde edebilirsiniz: IEnumerable<string> customerFirstNames = customers. Country = United States } Donald. Bu ifadeyi.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. Country = Canada } Elsa. Country = United States } Janet. C# tasarımcıları. System. LastName = Lang.

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

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

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

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

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

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

Select(d => d. var employeesByDept = from e in empTree group e by e. var ITEmployees = from e in empTree where String. Sorgu işleçlerini kullanarak BinaryTree’den veri elde edin 1. Entrance yönteminde. Visual Studio 2008’e dönmek için Enter tuşuna basın. Start Without Debugging’i tıklayın.Equals(e. Uygulama sonucunun daha önceki ile aynı olduğunu doğrulayı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(). 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. “IT”)).Equals(e.Department). Dept: IT Id: 4. Visual Studio 2008’e dönmek için Enter tuşuna basın.Department). var depts = (from d in empTree select d.Department). 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. 5. Name: Janet Gates. Start Without Debugging’i tıklayın. 2.GroupBy(e => e. 4.Department.Select(emp => emp). Name: Keith Harris.Distinct(). Debug menüsünde.Where(e => String. 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.388 Kısım III Bileşenler Yaratmak 22.Department. “IT”) select e. Ç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.Department. Debug menüsünde. 3.

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

FirstName = “Lucy”.Insert(new Employee { Id = 2. } İ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 = “Marketing” }). LastName = “Gates”. Department = “IT” }). 3. empTree ikili ağacı oluşturan ifadeden ayrı olarak. Bir önceki basamakta yazdığınız ifadelerden hemen sonrasına aşağıdaki kodu ekleyin: empTree. empTree ikili ağacını oluşturduktan sonra. empTree. FirstName = “Keith”. Bu ifadeler. LastName = “Gee”. .Insert(new Employee { Id = 5. Console. FirstName = “Eric”.Insert(new Employee { Id = 7. açıklama satırına dönüştürün: static void Entrance() { Tree<Employee> empTree = new Tree<Employee>(new Employee { Id = 1.390 Kısım III Bileşenler Yaratmak 2. kod bloğunu açıklama satırına dönüştürebilirsiniz. LastName = “Liu”. FirstName = “Orlando”. Department = “Sales” }). Entrance yönteminin içeriğini.Insert(new Employee { Id = 6. FirstName = “David”. LastName = “Harris”. empTree.WriteLine(“All employees”).. Console.Insert(new Employee { Id = 4. LastName = “Blanton”. Aşağıda gösterildiği gibi. empTree. Entrance yöntemine aşağıdaki ifadeleri ekleyin: Console. foreach (var emp in allEmployees) Console. LastName = “Harrington”. LastName = “Lang”.WriteLine(“All employees”).WriteLine(emp). empTree ağacına yeni bir çalışan ekler ve daha sonra allEmployees koleksiyonu üzerinden yeniden tekrarlar. empTree. 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. 4.WriteLine(emp). Department = “IT” }). empTree. foreach (var emp in allEmployees) Console.Insert(new Employee { Id = 3. FirstName = “Janet”. Bu kod. Department = “Marketing” }). FirstName = “Donald”..WriteLine(“\nEmployee added”). Department = “Sales” }). var allEmployees = from e in empTree select e. // comment out the rest of the method . Department = “IT” }).

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

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.Country. Dept: Marketing Lucy Harrington. uygulamanın allEmployees koleksiyonu üzerinde ikinci yinelemesinde. Dept: IT Orlando Gee. .392 Kısım III Id: Id: Id: Id: Id: Id: Bileşenler Yaratmak 1. Örneğin: var customerFirstNames = from cust in customers select cust. 2. Örneğin: var usCompanies = from a in addresses where String.CompanyName).CompanyName. görüntülenen listenin Donald Blanton adını kapsamadığına dikkat edin. Select(usComp => usComp. 4. Örneğin: var customerFirstNames = customers. Dept: Sales Keith Harris. Name: Name: Name: Name: Name: Name: Janet Gates. Örneğin: var usCompanies = addresses.Where(addr => String. 3. sorgunun Donald Blanton adı empTree ikili ağacına eklenmeden önce değerlendirilmesi ve sonuçların ön belleğe alınmasıdır. Ya da where sorgu işlecini kullanın. 5. Dept: IT David Liu. 9.Country.Select(cust => cust. 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. “United States”)).FirstName. Ya da from ve select sorgu işleçlerini kullanın. 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.Equals(a. 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. Visual Studio 2008’e dönmek için Enter tuşuna basın. Dept: Marketing Eric Lang.FirstName). Bunun nedeni.Equals(addr. Dept: Sales Bu defa. “United States”) select a. n n 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. 6.

İki farklı koleksiyonda tutulan veriyi birleştirmek Birleşecek koleksiyonu.Country.ToList<Employee>() select e.FirstName. Join(addresses. addrs.CompanyName select a.CompanyName. Ya da orderby sorgu işleci kullanın.CompanyName equals c.CompanyName. c. . Örneğin: var companiesGroupedByCountry = addresses. Select(c => new { c. custs.GroupBy(addrs => addrs.FirstName. addrs => addrs. Örneğin: var citiesAndCustomers = customers. 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.FirstName. Ya da join sorgu işlecini kullanın. Select(comp => comp. Bir LINQ sorgusu için sonuçların hemen üretilmesini sağlamak. c.OrderBy(addr => addr.Country }).CompanyName }).Country). (custs.CompanyName). a.LastName.LastName. custs => custs.LastName.CompanyName.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.Country }. Örneğin: var citiesAndCustomers = from a in addresses join c in customers on a. Ya da group by sorgu işlecini kullanın. c. Örneğin: var companyNames = from a in addresses orderby a. Örneğin: var companiesGroupedByCountry = from a in addresses group a by a. Sonuçları içeren bir liste ya da dizi oluşturmak için ToList ya da ToArray yöntemini kullanın.CompanyName). Örneğin: var companyNames = addresses. addrs) => new {custs. Örneğin: var allEmployees = from e in empTree. birleşme kriterini ve sonuç için alanları belirleyen Join yöntemini kullanın.CompanyName select new { c.

.

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

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

Hour rhs) { return new Hour(lhs. 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. İşleçler asla çok biçimli olamaz ve virtual.operator+(a. Hour b) { return Hour. Örneğin. } ..value).. 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. override ya da sealed niteleyiciler kullanamazlar. bu sözdiziminin geçerli C# dili olmadığına. + 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). ikili işleçler için (left-hand side (sol taraf) ve righthand side (sağ taraf) anlamında) lhs ve rhs kullanabilirsiniz. Bir ikili işleci yalnızca kendi iç yazım sistemiyle kullanabilirsiniz (işlenenler arasında simge olacak biçimde).Bölüm 21 public static Hour operator+ (Hour lhs. 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. İşleç statiktir. } şuna dönüştürür: Hour Example(Hour a. Bu örnekte. işleçlerin hiçbir zaman gizli bir this parametrelerinin olmadığına dikkat etmelidirler). private int value. } İşleç Aşırı Yüklemesi 397 Aşağıdaki noktalara dikkat edin: n n İşleç geneldir. // yalancı kod } Ancak. abstract. Hour b) { return a + b. C# derleyicisi aşağıdaki kodu: Hour Example(Hour a. bir tamsayıyı (saat miktarını) bir Hour nesnesine . n İpucu İyi biçimlendirilmiş işlevsellik (işleçler gibi) bildirirken parametreler için bir adlandırma standardı belirlemek çok yararlıdır. bir yalancı kod olduğuna dikkat edin. Ancak.value + rhs. Bütün işleçler genel olmalıdır. Bütün işleçler statik olmalıdır. her iki parametre de Hour nesnesidir. Diğer bir deyişle.

. } ... Hour sum = a + b. (a + b) deyimini geçerli yapabilmek için bir Hour (a. ikinci parametre tamsayı olabilir). ama bir int ile bir Hour’u doğrudan toplamak kadar açık ya da kısa değil.value = initialValue. } .. bir int ile bir Hour’u toplayabileceğinizdir. public static Hour operator+ (Hour lhs. Örneğin: Hour a = .value).... Simetrik İşleçler Yaratmak Bir önceki bölümde. } public static Hour operator+ (Hour lhs.value + rhs. } . ilk parametresi Hour ve ikinci parametresi int olan bir + ikili işleç bildirmelisiniz. Hour rhs) { return new Hour(lhs. tek yapmanız gereken int’i Hour’a dönüştürmek için ilk önce Hour kurucusunu kullanmaktır.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.. Hour nesnesinin iki örneğini toplamak için bir + ikili işlecinin nasıl bildirileceğini gördünüz... Hour yapısının bir int’ten bir Hour yaratan bir kurucusu vardır. private int value. Aşağıdaki kod önerilen yaklaşımı göstermektedir: struct Hour { public Hour(int initialValue) { this. int b = ... Hour sum = a + new Hour(b).. solda) ile bir int’i (b. Bu kural derleyiciye. sağda) toplamanın ne demek olduğunu bildirmelisiniz. int rhs) { return lhs + new Hour(rhs). şunun gibi: Hour a = . int b = ... 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. Bunun anlamı. Bu tamamen geçerli bir kod. Diğer bir deyişle..

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

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

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

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. . Bu bellek kullanımı ve çöp toplama maliyeti açısından pahalı olabilir. Bu öneri sadece artırma işleci için değil.value + 1). now’u otomatik olarak güncelleştirmek postfix’i de güncelleştirir! Hour bir yapıysa. 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. } . Dolayısıyla. atama ifadesi postfix = now şimdi postfix (sonek) değişkeninin now ile aynı nesneye başvurmasını sağlar. private int value. sınıfları tanımlarken işleç aşırı yüklemelerini sınırlandırmanız önerilir. Hour bir sınıfken artırma işlecinin doğru uygulaması aşağıdaki gibidir: class Hour { public Hour(int initialValue) { this. public static Hour operator++(Hour arg) { return new Hour(arg. 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). tüm işleçler içindir. yeni bir nesne yarattığına dikkat edin. } ..operator++(now). // yalancı kod C#’ta geçerli değil Hour bir sınıfsa. now = Hour.. Hour postfix = now. Bu çalışsa da artırma işlecinin derleyici çevirisinin her kullanışında yeni bir nesnenin yaratılmasıyla sonuçlanır.. Yeni nesnedeki veri artırılır ancak özgündeki veri değiştirilmeden kalır.value = initialValue. } operator++’ın şimdi orijinal veriye bağlı olarak. 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..

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

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

Şimdiki sorun. operator==’ın bir biçimini bildirdiğiniz halde gerekli olan operator!= eşini bildirmemiş olmanızdır. 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++.Minute.pulsed. Code and Text Editor penceresinde.value == rhs. 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.. int rhs) { return lhs. Minute. } İlk göreviniz bu işleci Minute yapısı için uygulamaktır.cs dosyasını açın. operator!=’in sol işlenen olarak Minute ve sağ işlenen olarak da int kabul eden bir sürümünü uygulayın. int)’ requires a matching operator “!=” to also be defined. Bu işlecin dönüş türünün bool olması gerektiğini unutmayın. 6. Build menüsünde Build Solution’ı tıklayın.. Bu ifade. . Build menüsünde Build Solution’ı tıklayın. public static bool operator==(Minute lhs. Oluşum hata verir ve aşağıdaki hata iletisini görüntüler: Operator ‘==’ cannot be applied to operands of type ‘Operators. Oluşum hata verir ve farklı bir hata iletisini görüntüler: The operator ‘Operators. Tamamlanmış işleç aşağıdaki gibi görünmelidir: struct Minute { . 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.operator ==(Operators. } 8. } . private int value. this. 9..Minute. Bu konu Bölüm 17’de açıklanmıştır). 7. Sorun.Minute’ and ‘int’..tick += tock.Bölüm 21 İşleç Aşırı Yüklemesi 405 Clock sınıfının kurucuları aşağıdaki ifadeyi içerir. 5.

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

bir double kapalı biçimde bir int ’e dönüştürülemez: class Example { public static void MyIntMethod(int parameter) { . public static implicit operator int (Hour from) { return this.0). Example. } 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 dönüştürme işleci public ve static olmalıdır. operator anahtar sözcüğünden önce belirtilmiş bir dönüş türü yoktur. Aşağıda..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).. bir Hour’un kapalı biçimde bir int’e dönüştürülebileceğini bildiren bir işleç görebilirsiniz: struct Hour { . // 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. } } .5 olduğunu düşünün. Açık bir dönüştürme bazen daraltma dönüştürmesi (narrowing conversion) olarak da adlandırılır. 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. } private int value. aşırı yüklenmiş işlecin sözdizimine benzer.MyIntMethod((int)42. C#.0). 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. 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.value.MyIntMethod(42. Kullanıcı Tanımlı Dönüştürme İşleçleri Uygulamak Kullanıcı tanımlı bir dönüştürme işlecinin sözdizimi.

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

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

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). public static implicit operator Second (int arg) { return new Second(arg). .410 Kısım III Bileşenler Yaratmak 3. } public static bool operator!=(Second lhs. } . 7. } 6. } 4. Uygulamanın hala doğru olarak çalıştığını doğrulayın. Dönüştürme işleci aşağıdaki gibi görünmelidir: struct Second { . Debug menüsünde Start Without Debugging’i tıklayın. public static bool operator==(Second lhs.. adımda vurgulanan if (this.value == rhs.. Code and Text Editor penceresinde. Tek fark.value. Second rhs) { return lhs. 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.value != rhs.Second’ and ‘int’ Bir Second ve bir int’i karşılaştıran işleçleri kaldırmak 1.. int’ten Second ’a dönüştürme yapan Second yapısına kapalı bir dönüştürme işleci ekleyin. second == 0) ifadesinin derlenmemesine neden olur. 5. kapalı bir dönüştürme işleci kullanmak kapalı dönüştürme işleci kullanmamaktan potansiyel olarak daha yavaştır. Oluşturma başarısız olur ve aşağıdaki hata iletisini verir: Operator ‘==’ cannot be applied to the operands of type ‘Operators. Second yapısında. Second rhs) { return lhs.value. 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 { ..... Build menüsünde Build Solution’ ı tıklayın.. } . Build menüsünde Build Solution’ı tıklayın .

.. public static implicit operator Hour(int arg) { . Örneğin: struct Hour { . Hour rhs) { . Örneğin: struct Hour { .. } Bir dönüştürme işleci bildirmek public ve static anahtar sözcüklerini yazı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..Bölüm 21 İşleç Aşırı Yüklemesi 411 8.. 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.. Uygulamayı kapatın ve Visual Studio 2008 programlama ortamına dönün. public static bool operator==(Hour lhs. 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..... 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ü. n n Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın.. 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. } . 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. } . } .

.

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

.

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. Özellikle. 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. WPF formları ve denetimlerinin özelliklerini tasarım anında ya da çalışma anında değiştirmek. Bu bölümde.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. Bir WPF Uygulaması Yaratmak Örnek olarak. İlerleyen 415 . Ayrıca.Windows ad alanındaki nesneleri nasıl kullanacağınızı göreceksiniz. C# kullanarak programların nasıl yazılacağını ve bileşenlerin nasıl yaratılacağını öğrendiniz. Artık başlıca dil yeteneklerini edindiğinize göre Kısım IV. formun görünümüne ve tümüyle çalışıyor olmasına odaklanarak uygulamayı çok basit tutacaksınız. WPF formları ve denetimleri tarafından açığa çıkarılan olayları işlemek. 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. metin kutuları ve düğmeler gibi sık kullanılan WPF denetimleri ile çalışmak WPF denetimleri için modeller tanımlamak. Son olarak.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. Etiketler. 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. birçok GUI uygulamasının ortak bileşenlerini kullanarak basit bir WPF uygulaması oluşturmayı öğreneceksiniz. bir kullanıcının. WPF uygulamaları yaratmak için System. Önce. WPF formları ve denetimlerinin başlattığı olayların bazılarını nasıl durduracağınızı ve işleyeceğinizi öğreneceksiniz. Genişletilmiş yöntemler. şirketinizin standartlarına kolayca uygun hale getirilen kullanıcı arabirimi oluşturmak için WPF modellerinin kullanımını öğreneceksiniz. bu yetenekler üzerinde bilgilerinizi nasıl geliştireceğinizi ve Microsoft .

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

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

Window1 formunda Window1 metnini tıklayın. Common kısmında. denetimleri dikey düzenlemede yerleştirir. XAML bölmesinde. Bir diğeri. Farklı yerleşim stilleri sağlayan başka bölmeler de mevcuttur. içerdiği denetimlerin yerleşimini yönetir. Design View penceresinde. metin kutuları ve etiketler gibi denetimleri formdaki bölmeye yerleştirin. Window öğesinin Grid adında bir alt öğe içerdiğine dikkat edin.Grid denetimi için özellikler görüntülerse. düğmeler. Window1 formunu tıklayın ve daha sonra da Toolbox sekmesini tıklayın.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. Bu bölümde. Properties penceresinde. 4. form çalıştığında uygulanan C# kodu yazarak bu değerleri ve birçok başka özelliği değiştirebilirsiniz. 2. bölme türüne uygun olarak denetimler otomatik olarak yeniden boyutlandırılır ve yeniden konumlandırılır. Örneğin.Window denetimi için özellikler görüntüler. Bir WPF uygulamasında. kullanıcı çalışma zamanında pencereyi yeniden boyutlandırırsa denetimlerin nasıl yerleştirileceğini yönlendirmektir. 5. StackPanel otomatik olarak. Ayrıca. Bölme. XAML bölmesinde. Design View penceresinde Window1 formunu tıklayın. WPF uygulama şablonu tarafından eklenen varsayılan bölme Grid ’dir. 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. Button’u tıklayın ve daha sonra formun sağ üst kısmını tıklayın.Windows. Varsayılan ayar olarak. Bununla birlikte. Properties penceresi System. Bir yerleştirme bölmesinin başlıca amacı. 3. Bu işlem kılavuz yerine formu seçer ve ardından Properties penceresi System. 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. denetimleri sürükleyebildiğiniz tek bir hücre tanımı olarak düşünebilirsiniz. Not Grid bölmesi esnektir fakat karmaşıktır. Grid bölmesini. sonraki adımda inceleyeceğiniz bir alt denetim içerir. formun Title özniteliğindeki değerin değiştiğine ve Design View penceresinde. her denetim doğrudan bir öncekinin altına geçecek şekilde. 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. Not Window1 formu. tasarım zamanında denetimlerinizin konumunu tam olarak belirleyebilirsiniz. bazı şeyleri basit tuttuk ve sadece tek bir hücre kullandık.Controls. formun başlık çubuğunda yeni başlığın görüntülendiğine dikkat edin. .Windows.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

72. 72. 0.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 275 21 420. 0 Top Left 75 23 29. 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. 0 Top Left 75 21 121. 134. 25. 0 Top Left 75 21 380. 25. 0 Top Left 175 23 29. 0. 0.

20. 0. 0 Top Left 258 151 224 16 0. 134. 0 120 16 0. 174. 10. 0. 0 120 200 310. 0. 0. 174. 0.436 Kısım IV Windows Uygulamaları ile Çalışmak Denetim Özellik HorizontalAlignment Width Değer Left 90 23 121. 0 120 16 0. 0 Top Left 275 200 29. 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 . 0 120 16 0. 20. 0. 20.

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

sonraki alıştırmada bu açılan kutuyu doldurmak için kod yazacaksınız. Form çalıştığında aşağıdaki resimdeki gibi görünmelidir: Methods liste kutusunun şu anda boş olduğuna dikkat edin. Kulelerin listesi şu anda boştur. 3. 6. Aşağıdaki denetimlere bellRingersStyle stilini uygulayın: n n n n firstName lastName add clear 4. 5. Debug menüsünde Start Without Debugging’i tıklayın. Aynı şekilde.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. Tower açılan kutusundaki aşağı oku tıklayın. otomatik olarak stilin bu denetimlerde görüntülenen öğeler tarafından kullanılmasına neden olur. Formu kapatın ve Visual Studio 2008’e dönün. Sonraki alıştırmada liste kutusunu doldurmak için kod ekleyeceksiniz. .

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

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

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

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

bu olaya tepki veren kodu yazmalısınız. Bir takvim göreceksiniz. Ayrıca. Bir yöntemi ikinci defa tıklarsanız. Bir WPF Formda Olayları İşlemek Microsoft Visual Basic. uygulamanızla ilgili olduğunu hissettiğiniz olayları yakalamak ve bu olaylara tepki gösteren kodlar yazmaktır. Düğmenin birşeyler yapmasını istiyorsanız. Bu bölümdeki alıştırmaların sonuncusunda bu işlevselliği ekleyeceksiniz. Yılı tıklayarak. . Tower açılır kutusunu tıklayın. kendi olaylarınızı nasıl yayınlayacağınızı ve onlara nasıl abone olacağınızı gördünüz. Sık rastlanan bir örnek. 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. Bölüm 17’de. Debug menüsünde Start Without Debugging’i tıklayarak projeyi oluşturun ve çalıştırın. 15. 16. 17.Bölüm 22 Windows Presentation Foundation’a Giriş 443 11. ayı seçmek için okları kullanabilirsiniz. daha sonra bunlardan birini seçebilirsiniz. Methods liste kutusunda. ayları açılır liste olarak görüntülemek için ay adını tıklayabilirsiniz. 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. Varsayılan değer geçerli tarih olacaktır. Bir tarihi tıklayarak. Add ve Clear düğmelerini tıklayın. 12. 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. Çan kulelerinin listesini göreceksiniz. Experience grup kutusundaki her seçenek düğmesini tıklayın. uygun onay kutusunu seçmek için yöntemlerden bazılarını tıklayın. Aynı anda birden fazla seçenek düğmesi seçebileceğinize dikkat edin. Bu. Bu düğmeler şu an hiçbir şey yapmaz. sayısal yukarı aşağı denetimi kullanarak yılı seçebilirsiniz. Windows Forms’da Olayları İşlemek Bir program geliştirici olarak göreviniz. uygun onay kutusu temizlenecektir. 13. Formu kapatın ve Visual Studio 2008’e dönün. Member Since tarih/zaman seçicisinin sağ tarafındaki aşağı okunu tıklayın. bu bölümün son alıştırmasında yapacağınız şeydir. 14. Form açıldığında.

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

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

NET Framework’de ve C#’da string veri türü sabittir. Burada kullanılan Show yöntemi. Clear düğmesini tıklayın ve formdaki denetimlerin varsayılan değerlere sıfırlandığını doğrulayın. Ayrıca. bir aşırı yüklenmiş yöntemdir ve ileti kutusunda göstermek için belirleyebileceğiniz çeşitli simgeler ve düğmeler içerir. üyenin adını ve bağlı olduğu kulenin adını saklayan.Format yöntemini kullanır.Text ad alanındaki StringBuilder sınıfı bu verimsizliği önlemek için tasarlanmıştır. değeri bir dize içinde değiştirdiğinizde. nameAndTower adında bir string değişkeni yaratır. . Yöntem. 7. methods liste kutusundaki Items koleksiyonu üzerinden yinelenir. Her onay kutusu incelenir ve kullanıcı tarafından seçilmişse. . String. nameAndTower dizesindeki metin. Üyenin ilk adı ve soyadını yazın. 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). bu liste kutusu. 10. System. ileti kutusunun gövdesindeki details dizesinin içeriğini görüntüler. onay kutusunun Content özelliğindeki metin details StringBuilder nesnesine eklenir. Show. Insert ve Remove yöntemlerini kullanarak StringBuilder nesnesine karakterler ekleyebilir ve çıkarabilirsiniz. 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. ç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 kule ve birkaç yöntem seçin. Son olarak. görüntüleyeceği bilginin dize gösterimini oluşturmak için bu StringBuilder nesnesini kullanır. Not StringBuilder nesnesi yerine sıradan dize birleştirme kullanabilirdiniz. Kodun. 8. Append. Başlık araç çubuğunda “Member Information” yazacaktır. başlangıç olarak details nesnesini yerleştirmek için kullanılır.WriteLine yöntemi ile aynı şekilde çalışır. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. ekranda iletişim kutularını görüntülemek için statik yöntemler sağlar. biçimlendirilmiş dizeyi ekranda görüntülemek yerine sonuç olarak döndürmesi dışında. Bir dizeyi tekrar tekrar değiştirmek.Format yöntemi. Kod daha sonra.446 Kısım IV Windows Uygulamaları ile Çalışmak Bu kod bloğu. MessageBox sınıfı. Formu kapatın ve Visual Studio 2008’e dönün. kod sonuçları sıfırlamak için statik String. Hatırlarsanız. Kod daha sonra details adında bir StringBuilder nesnesi yaratır. 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. Console. 9. onay kutusu denetimlerini içerir. Her seferinde yeni bir nesne yaratmak zorunda kalmadan. 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.

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

ikinci ifade. İşlevsel kullanıcı arabirimi oluşturmak için gerekli WPF özelliklerinin kullanımını gördünüz. WPF. 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. kullanıcıya uygulamayı kapatmak isteyip istemediğini soran bir ileti kutusu gösterir. burada gördüğümüz özelliklerden daha fazlasını. Bu defa. 6. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. Form kapanır ve uygulama sonlanır.No. 5. 7. 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. ileti kutusunda Yes’i tıklayın. Formu kapatmayı tekrar deneyin. Formu kapatmaya çalışın. kullanıcı Enter tuşuna basarsa varsayılan düğmeyi gösterir (kullanıcı yeni yazdığı verileri kazara kaybetmektense formu kapatmamayı ister). Kullanıcı No’yu tıklarsa. Save iletişim kutusu görünürse. formun kapanmasını engelleyen. İleti kutusu. Yes ve No düğmeleri ve bir soru işareti simgesi içerir. Kullanıcı her iki düğmeyi de tıkladığında. n . özellikle iki boyutlu ve üç boyutlu grafikler ve animasyon ile ilgili çok daha fazla özellik içerir. CancelEventArgs parametresinin (e) Cancel özelliğini true olarak atayacaktır.448 Kısım IV Windows Uygulamaları ile Çalışmak Bu ifadeler. Beliren ileti kutusunda No’yu tıklayın. Uygulamayı çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın. Son parametre olan MessageBoxResult. Form çalışmaya devam etmelidir. 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).

Clear(). Örneğin: novice. Aynı bölmedeki tüm seçenek düğmeleri birbirini dışlayandır. Örneğin: towerNames. Örneğin: towerNames. Listenin mevcut içeriğini saklı tutmak isteyip istemediğinize bağlı olarak. Design View penceresinde formu ya da denetimi tıklayın.xaml.IsChecked = true. n XAML bölmesinde. Denetimi Toolbox’dan forma sürükleyin. 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.xaml dosyasının klasörünü genişletin ve görünen .Add(“Upper Gumtree”). formun . Items özelliğinin Add yöntemini kullanın.Items. XAML bölmesinde. Solution Explorer’da. Code’u tıklayın.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. ilk önce Items özelliğini temizlemeniz gerekebilir. 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. 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.cs dosyasını çift tıklayın.Items. Bölmeye seçenek düğmeleri ekleyin. değiştirmek istediğiniz özelliği seçin ve yeni değeri girin. . <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. Daha sonra aşağıdakilerden birini yapın: n Properties penceresinde.

.

dosya ve yazıcılar gibi sık kullanılan öğeler için kullanıcının hızlı. Son olarak.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. 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. Kullanıcı bir menü komutunu tıkladığında işlemleri gerçekleştirmek için menü olaylarına tepki vermek. Bu bölümde. Menü Temel İlkeleri ve Stil Birçok Windows uygulamasına bakarsanız. Bu iletişim sınıfları. Bölüm 22’de yarattığınız Bell Ringers uygulamasında ise yeni bir üye olabilir. Menüleri kod üzerinden değiştirmek ve dinamik menüler yaratmak. 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. belgeyi yazdırmak ve uygulamadan çıkmak için komutlar bulunur. var olan bir belgeyi açmak. Microsoft Office Excel’de belge bir elektronik tablodur. Örneğin. 451 . Kullanıcı menüdeki bir komutu tıkladığında nasıl tepki verileceğini göreceksiniz. kolay ve tanıdık bir yolla bilgi girmesini sağlamanıza olanak verir. belgeyi kaydetmek. menü çubuğunda bazı bileşenlerin aynı yerde birçok kez yinelendiğini ve bu öğelerin içeriklerinin önceden kestirilebilir olduğunu fark edersiniz. 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. Menu ve MenuItem sınıflarını kullanarak menüler yaratmak ve düzenlemek. menülerin nasıl yaratıldıklarını ve menüleri Menu denetimini kullanarak formlara nasıl ekleyeceğinizi öğreneceksiniz. Kullanıcıların dosya adı girmesi için uygulamanızda Windows ortak iletişim kutularını kullanmak. Not document (Belge) terimi uygulamanın kullandığı veri anlamındadır. Etkin konuma göre içerikleri değişen açılan menüler yaratmayı öğreneceksiniz. File menüsü tipik olarak menü çubuğunun ilk öğesidir ve bu menüde genellikle bir belge yaratmak.

Kullanıcı bir menüdeki komutu tıkladığında. Sıklıkla menü çubuğunda uygulamaya özgü menüler de olur ama burada da genellikle son menünün hem yardıma. Bir menü düzenlemek hikayenin sadece yarısıdır. böylece hemen hemen her tür WPF denetimi içeren bir menü yapısı tanımlayabilirsiniz.microsoft.aspx adresinde sunmaktadır. sezgisel kullanıcı arabirimleri için menü tasarımı dahil menü temel ilkelerinin tümünü Microsoft Web sitesi olan http://msdn2. İpucu Microsoft. Paste.com/en-us/library/Aa286531. açılır kutular vb. File menüsünde uygulamaya özel komutlar da olabilir. düğmeler. Menüler ve Menü Olayları WPF. 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. Clear. Bir komutu gerçekleştirmek için tıklayabileceğiniz metin öğeleri içeren menülere aşina olabilirsiniz. Menu denetimi. Find vb. bir menü tanımlamak için basit bir kabuk sağlar. 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. menü öğeleri için bir taşıyıcı olarak Menu denetimini sağlar. 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. 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. İyi tasarlanmış bir uygulamada çoğu menüler tahmin edilebilir olup uygulamanın öğrenilmesini ve kullanılmasını kolaylaştırmaya yardımcı olur. 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. 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 uygulama genelde Cut. komutlar içeren bir Edit menüsüne de sahiptir. 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. Microsoft Visual Studio 2008’i başlatın. Menüleri. 2. Menu denetimi de oldukça esnektir. WPF menüleri ayrıca. örneğin. Exit komutu neredeyse şaşmaz biçimde File menüsünün son komutudur. Uygulama menüsü yaratın 1. öğeler içerir. Bu. metin kutuları.

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

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

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

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

. metin kutuları ve diğer denetim türlerinin birçoğunu ekleyebilirsiniz. tasarımınızı basit tutmalı ve çok fazla gösterişli yapmamalısınız. yuvalanmış MenuItem öğeleri kendi içinde daha fazla yuvalanmış MenuItem öğelerine sahip olabilir. Böyle bir menü çok sezgisel değildir! . 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.. Bununla birlikte.> <MenuItem Header=”Miscellaneous”> <Button>Add new member</Button> <ComboBox Text=”Towers”> <ComboBox. Teorik olarak. MenuItem öğesini kullanmakla sınırlı değilsiniz. Ayrıca. Ü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. Basamaklanmış menüler yaratmak istiyorsanız.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.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.Items> <ComboBoxItem> Great Shevington </ComboBoxItem> <ComboBoxItem> Little Mudford </ComboBoxItem> <ComboBoxItem> Upper Gumtree </ComboBoxItem> <ComboBoxItem> Downley Hatch </ComboBoxItem> </ComboBox. Örneğin. aşağıdaki menü yapısı düğme ve açılır kutu içerir: <Menu .

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

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

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

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

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.0” Name=”ok” HorizontalAlignment=”Left” Width=”78” Height=”23” VerticalAlignment=”Top”>OK</Button> </Grid> </Window> Tamamlanmış form şöyle görünmelidir: 6.0. Visual Studio. 7.50.cs dosyasını görüntüleyen Code and Text Editor penceresinde.85.xaml. XAML bölmesinde. Window1. aboutWindow. 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.cs dosyasına ok_Click yöntemini ekler. ok_Click yöntemine aşağıdaki ifadeyi ekleyin: private void ok_Click(object sender.xaml. Window1.cs dosyasını görüntüleyen Code and Text Editor penceresinde.462 Kısım IV Windows Uygulamaları ile Çalışmak <Label Margin=”80.ShowDialog(). 9. düğmenin Click olayı için bir olay yöntemi üretir ve About. About.0. .Close(). about_ Click yöntemine aşağıdaki ifadeleri ekleyin: private void about_Click(object sender. 8. About penceresi kapanana kadar (kullanıcı OK düğmesini tıkladığında) birşey döndürmez. } Bu kod.xaml.0” Name=”buildDate” Height=”30” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”160”>Build date: September 2007</Label> <Button Margin=”100. RoutedEventArgs e) { About aboutWindow = new About(). Design View penceresinde OK düğmesini çift tıklayın. RoutedEventArgs e) { this. ShowDialog yöntemi. } Kullanıcı OK düğmesini tıkladığında pencere kapanacaktır.xaml dosyasını görüntüleyen Design View penceresine dönün.

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

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

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

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

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

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

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

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

ShowDialog yöntemini kullanarak etkinleştirin ve kullanıcı Open düğmesini tıkladığı sonucunu döndürdüğünde FileName özelliğini alın. Dosyayı çift tıklayın ve dosyanın eklediğiniz üyenin bilgilerini içerdiğini doğrulayı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. 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. Visual Studio 2008 için MSDN Kütüphanesine başvurun. Header özelliği ile menü öğesi için metni belirleyin ve Name özelliğini belirleyerek de her menü öğesine bir ad verin. OpenFileDialog sınıfını kullanmak ile ilgili daha fazla ayrıntı için. Menu denetimine MenuItem öğeleri ekleyin. Simgeler ve alt menüler gibi özellikleri görüntüleyebilmek için isteğe bağlı özellikleri de belirleyebilirsiniz.txt dosyasının yaratıldığını doğrulayın. Menü öğesini seçin ve Click olayı için bir olay yöntemi belirleyin. Menüye Seperator öğesi ekleyin. Save iletişim kutusu görünürse. içeriğini okuyabilir ve ekranda alanları yerleştirebilirsiniz. Uygun harfi alt çizgi ile belirterek menü öğesine bir erişim anahtarı ekleyebilirsiniz. DockPanel denetimine Menu denetimi ekleyin. Windows Gezginini kullanarak Belgeler klasörünüze gidin. 11. Daha sonra Not Defteri uygulamasını kapatın. Pencere kaynaklarına bir ContextMenu ekleyin. Visual Studio 2008’den şimdi çıkmak istiyorsanız File menüsünde Exit’i tıklayın. TestMember. Kısayol menüsüne başvurmak için form ya da denetimin ContextMenu özelliğini ayarlayın. Bir dosyayı açmak için de aynı tekniği kullanabilirsiniz: bir OpenFileDialog nesnesi yaratı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. Olay yöntemine kodunuzu ekleyin.Bölüm 23 Menüler ve İletişim Kutularıyla Çalışmak 471 10. Daha sonra dosyayı açabilir. 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. Sıradan menüye öğeleri eklediğiniz biçimde kısayol menüsüne öğeleri ekleyin. Tasarım sırasında Properties penceresinde. 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 .

SaveFileDialog sınıfını kullanın. Bu nesnenin Items koleksiyonunu. kullanıcının seçtiği dosyanın adını içerir.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. SaveFileDialog örneğinin FileName özelliği. . menü öğelerini tanımlayan MenuItem nesneleri ile yerleştirin. İletişim kutusu kapandığında. ShowDialog yöntemini kullanarak iletişim kutusunu görüntüleyin. Bir ContextMenu nesnesi yaratın.

özellikle de doğrulama kullanıcının iki ya da daha çok denetime girdiği verilerin karşılıklı doğrulanmalarını gerektiriyorsa.Bölüm 24 Doğrulamayı Gerçekleştirmek Bu bölümü tamamladıktan sonra öğrenecekleriniz: n Kullanıcı tarafından girilen bilgileri. Bu strateji ile ilgili problem. Uygulamanın kullanımını kolaylaştırmak amacıyla menüler yarattınız. n n Önceki iki bölümde. Bu bölümde. etkili ama sıkıntı vermeyen biçimde gerçekleştirmek . formun kullanımını zorlaştırır ve sinirleri gerer. Microsoft . hiçbir uygulamayı ya da iş kuralını ihlal etmediğinden emin olmak için incelemek. 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. 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. LostFocus olayı. uygulamayı çalıştıran bir kullanıcı tarafından girilen verilerin. kullanıcı tarafından girilen bilgilerin anlamlı olmasına yardımcı olsa da genelde gerçekleştirmeniz gereken ek denetimler vardır. Kullanıcı tarafından girilen bilgiyi doğrulamak için veri bağlama doğrulama kurallarını kullanmak. kullanıcı bir denetimden uzaklaştığında ortaya çıkar. Verileri Doğrulamak Girdi doğrulama kavramı olabildiğince basittir ama uygulama içinde kullanımı her zaman kolay olmaz. denetimlerin LostFocus olayını işlemektir.NET Framework’un önceki sürümlerinden aşina olduğu yaygın teknik. Menüler. Bir formun dikkatli tasarlanması ve denetimlerin uygun kullanımları. uygulamanın gereklilikleri tarafından belirlenen iş kurallarına uyduğundan emin olmak için nasıl doğrulanacağını öğreneceksiniz. Birçok Microsoft Windows yazılım geliştiricisinin. Arka plandaki iş kuralı görece çok açık olabilir ama çoğu zaman yanlış zamanda gerçekleştirilen doğrulama. Doğrulamayı. 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. çoğu kez bir denetime girilen değer ile 473 . 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ı bir formdaki denetimler üzerinde hareket edebilir. ad ve cinsiyeti de içeren temel müşteri bilgilerinin girilmesini gerektirir. Uygulamanın bir bölümü. Bu strateji ile ilgili bir diğer önemli konu. Daha sonra. Bunun için. 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. kullanıcının bir denetimden diğerine geçiş sırası üzerinde bir güce sahip değilsiniz. Bir Örnek: Müşteri Yönetimi Örnek olarak basit bir senaryo düşünün.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. Ayrıca. . “Veriyi Yönetmek” başlıklı Kısım V’te veri bağlama hakkında daha fazla şey öğreneceksiniz. Bir Müşteri Yönetimi uygulaması geliştirmeniz istendi diyelim. doğrulama mantığını da değiştirmeniz gerekebilir ve kodun bakımı karmaşık bir iş haline gelebilir. Miss ya da Ms) seçili cinsiyetle (Male (Erkek) ya da Female (Kadın)) eşleşmelidir veya tam tersi. İş gereksinimleri değişirse. 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. veri bağlama ile ilişkilendirebileceğiniz doğrulama kuralları üzerinde yoğunlaşacağız. WPF bu sınıfların örneklerini yaratabilir. Mrs. WPF ile uygulamanız tarafından kullanılan iş modelinin parçası olarak doğrulama kuralları tanımlayabilirsiniz. bir uygulamanın sunum öğelerinin doğrulama mantığının iş mantığına oldukça yakından bağlı olmasıdır. hitap. Çalışma zamanında. kullanıcı arabiriminin Extensible Application Markup Language (XAML) tanımından bu kurallara başvurabilirsiniz. çoğu kez birkaç denetim için LostFocus olay işleyicisinde benzer mantığı tekrarlamayı bırakırsınız. Kullanıcı girdisinin tutarlı olduğundan emin olmanız gerekir. veri otomatik olarak. Bir denetimdeki veriyi değiştirdiğinizde. Bu bölümde. belirlenen ve doğrulanan uygun iş modeli sınıfı örneğine kopyalanabilir. hitap (Mr. Aşağıdaki resimdekine benzer bir form yaratmaya karar verdiniz.

Kaydederse. Microsoft Visual Studio 2008’i başlatın. 6. Belgeler klasörünüzdeki \Microsoft Press\Visual CSharp Step By Step\Chapter 24\ CustomerDetails klasöründe yer alan CustomerDetails projesini açın. CustomerDetails projesini farenin sağ düğmesiyle tıklayın. bir müşteri modelleyen bir sınıf yaratmaktır. Bir ad girişini sağlamak için doğrulama mantığıyla Customer sınıfını yaratın 1. 7. İdeal olarak. Uygulama gerçekte herhangi bir veri kaydetmez. private string lastName. 5. Form belirdiğinde. 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.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. uygulama herhangi bir denetim gerçekleştirmediğinden kaydedilen bilgi tutarsız olacaktır. Add’i işaret edin ve daha sonra Class’ı tıklayın. } . 3. Müşteri Yönetimi uygulamasını inceleyecek ve veri bağlamayı kullanarak doğrulama kuralları ekleyeceksiniz. Gender grup kutusunda. 2. Customer. Add New Item – CustomerDetails iletişim kutusunda Name metin kutusuna Customer. Title açılan kutusundaki aşağı okunu ve ardından Mr’ı tıklayın. Female seçenek düğmesini tıklayın. 2. OK’i tıklayın ve formu kapatarak Visual Studio 2008’e geri dönün. 4. Save’i tıklayın ve “Customer saved” (Müşteri kaydedildi) ileti kutusunun belirdiğini doğrulayın. Gerekli doğrulama mantığını eklemenin ilk adımı. 3. 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.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. File menüsünde. Uyarıcı bir aşama olarak. tüm müşteriler bir ada sahip olmalıdır ve Title ve Gender denetimleri için belirlenen veriler tutarlı olmalıdır. Solution Explorer’da. Uygulamayı oluşturmak ve çalıştırmak için Debug menüsünde Start Without Debugging’i tıklayın.

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

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

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

İleti kutusunda.HasError özelliğinin ne zaman true olarak ayarlandığını saptayan bir tetikleyici içerir. Bu problemi daha sonra ele alacaksınız. OK’i tıklayın ve sonra title açılan kutusunu tıklayın.Triggers> <Trigger Property=”Validation. 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. 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. 12.xaml dosyasını görüntüleyen Design View penceresinde.Resources> <cust:Customer x:Key=”customerData” /> <Style x:Key=”errorStyle” TargetType=”Control”> <Style. n Özel durum iletilerine bir stil ekleyin 1.Resources> Bu stil. Şimdi lastName metin kutusu etrafında kırmızı çerçeve belirir. doğrulamanın sadece metin kutusu odak noktasından çıktığında meydana gelmesidir. Tetikleyici.Self}.Triggers> </Style> </Window. XAML bölmesinde Window. CustomerForm. Aşağıdaki alıştırmada bunu nasıl yapacağınızı göreceksiniz. Ayrıca. denetimin Validation. 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.HasError” Value=”True”> <Setter Property=”ToolTip” Value=”{Binding RelativeSource={x:Static RelativeSource. 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.Resources öğesine aşağıdaki stili ekleyin: <Window.Bölüm 24 Doğrulamayı Gerçekleştirmek 479 11. özel durumun metnini görüntülemek için geçerli denetimin ToolTip özelliğini ayarlar. Burada gösterilen bağlama . Denetimin bağlama doğrulama kuralı bir özel durum oluşturursa bu meydana gelir. 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. Menüler gerçekte formun parçası olarak ele alınmaz (farklı olarak işlenirler). Bu da sadece kullanıcı form üzerindeki başka bir denetime odaklandığında olur. Sadece bir şeyler yazdığınızda ve sonra sildiğinizde doğrulama çalışır. Errors)[0].ErrorContent}” /> </Trigger> </Style. foreName ve lastName metin kutuları başlangıçta boştur. Formu kapatın ve Visual Studio 2008’e geri dönün.

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

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

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

İlk olarak. public override string ToString() { return this.Female olarak ayarlamalısınız. } } } } Bu özelliklerin set erişimcileri. 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. bunun gibi işlemleri gerçekleştirmek için bir çevirici sınıfı belirleyebilirsiniz.Gender. form tarafından yaratılan Customer nesnesinin Title özelliğine bağlamanız gerekir. Neyse ki. 6.Male olarak ayarlamalısınız. Her bir seçenek düğmesinin IsChecked özelliğini (bir boolean değerdir). 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. Neyse ki. Customer sınıfına ToString yöntemini ekleyin: class Customer { . female seçenek düğmesinin IsChecked özelliği true olarak ayarlanmışsa. biraz düşünürseniz. Bununla birlikte.Title.ToString(). . 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.LastName + “ . 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. Gender özelliğini Gender. male seçenek düğmesinin IsChecked özelliği true olarak ayarlanmışsa. Text özelliği string türündedir. title açılan kutusunun Text özelliğini. Aşağıda gösterildiği gibi.Bölüm 24 { Doğrulamayı Gerçekleştirmek 483 throw new ApplicationException( “The gender must match the title of the customer”). Customer nesnesinin Gender özelliğine (Gender türüne sahiptir) bağlamanız gerekir. Bağlamanın çalışması için string ve Title değerlerini birbirine çevirmeniz gerekir. Gender özelliğini Gender. çok sayıda küçük sorunlar olduğunu anlarsınız. Title özelliği de Title (bir numaralandırma) türündedir.. form üzerindeki male ve female seçenek düğmeleri ve title açılan kutusunu bu yeni özelliklere bağlamaktır. Bir sonraki aşama. } } 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. Yine.“ + this..ToString() + “ “ + this.ForeName + “ “ + this. İkinci problem de benzer bir problemdir. WPF tarafından gerçekleştirilen bağlama mekanizması ile.

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

object parameter. break. sınıf için uygun türe dönüştüreceğiniz değerdir.Globalization. public object ConvertBack(object value.Miss. 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. TitleConverter sınıfından sonra. bool retVal = false. aşağıda gösterilen GenderConverter sınıfını ekleyin: [ValueConversion(typeof(bool).Mrs. 6. System. Type targetType. GenderConverter sınıfına aşağıda gösterilen Convert yöntemini ekleyin: public class GenderConverter : IValueConverter { public object Convert(object value. 5.cs dosyasına.Ms.CultureInfo culture) { Title retVal = Title.Bölüm 24 Doğrulamayı Gerçekleştirmek 485 4.. Customer. . } } ConvertBack yönteminde. typeof(Gender))] public class GenderConverter : IValueConverter { } Bu defa.Miss. Aşağıda gösterilen ConvertBack yöntemini TitleConverter sınıfına ekleyin: public class TitleConverter : IValueConverter { .Mr. System. break.Globalization. Gender gender = (Gender)value. case “Ms” : retVal = Title. switch ((string)value) { case “Mr” : retVal = Title. } return retVal.CultureInfo culture) { string radioButtonId = (string)parameter. object parameter. Bu durumda. case “Mrs” : retVal = Title. case “Miss”: retVal = Title. break. Type targetType. 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.

yöntem parameter parametresini kullanacaktır. Anlaşılması gereken önemli nokta. 7.Equals(Gender. onu temizleyemez.486 Kısım IV Windows Uygulamaları ile Çalışmak if (String. Sonraki alıştırmada. Type targetType. bu yararlıdır. parameter parametresi “Male” ise.Female.Equals(Gender. Bir formdaki çeviriciye başvurduğunuzda. Bir seçenek düğmesi yalnızca aynı grupta başka bir seçenek düğmesi seçildiğinde temizlenir.Female)) retVal = true.Equals(r