Web & Yazılım Geliştirme Serisi · Modül 11
C# ve .NET ile tipli, yapılı kod yaz
Statik tipler, değişkenler, koşullar, döngüler, diziler ve metotlar; sınıflar, özellikler, kalıtım, arayüzler ve çok biçimlilik; tip güvenliği, koleksiyonlar, LINQ, hata yönetimi ve async; .NET, web, veritabanı ve güvenlik. Her bölümde "kod → konsol çıktısı" diyagramlarıyla.
C#'a Giriş
Temeller: C# ve .NET nedir, ilk program, değişkenler ve statik tipler, operatörler, koşullar, döngüler, diziler ve koleksiyonlar, metotlar.
Bölüm 01
C# ve .NET Nedir?
C#, Microsoft tarafından geliştirilen, modern, güçlü ve nesne yönelimli bir programlama dilidir. .NET platformu üzerinde çalışır; web, masaüstü, oyun (Unity) ve kurumsal uygulamalarda yaygındır. PHP ve Python'dan en büyük farkı: C# derlenen ve statik tipli bir dildir.
C#'ı farklı kılan ne?
- Derlenir: kod, çalışmadan önce derleyiciden geçer (hatalar erken yakalanır).
- Statik tipli: her değişkenin sabit, belli bir tipi vardır.
- .NET üzerinde çalışır: zengin, olgun bir platform ve kütüphane.
- Çok yönlü: web (ASP.NET), masaüstü, oyun (Unity), bulut.
PHP ve Python'da kodu doğrudan çalıştırıyordun (yorumlanan diller); C#'ta arada bir derleme adımı vardır. Bu fazladan adım bir avantajdır: derleyici, kod çalışmadan önce birçok hatayı (yanlış tip, yazım hatası, eksik tanım) yakalar — "çalıştırınca patlamak" yerine "derlerken uyarı almak". Statik tipleme de aynı felsefenin parçasıdır: bir değişkeni int tanımladıysan ona metin atayamazsın; bu, büyük projelerde hata oranını ciddi biçimde düşürür. C#, "güvenlik ve yapı" tarafında duran bir dildir.
Konsola ne yazar?
ÇıktıC# kodu önce derlenir (denetlenir ve .NET'in anlayacağı ara koda çevrilir), sonra .NET çalışma zamanı tarafından çalıştırılır. Bir konsol uygulamasında sonuç terminalde görünür; bir web uygulamasında tarayıcıya, bir masaüstü uygulamasında pencereye gider. Derleme adımı, programın daha güvenli ve hızlı çalışmasını sağlar.
Alıştırma
8 dkC#'ı konumla:
- C#'ın "derlenen" ve "statik tipli" olmasının ne demek olduğunu yaz.
- Derleme adımının sağladığı bir avantajı belirt.
- C# ile Python'ın ortak yanı ve temel farkı nedir, kısaca yaz.
Bölüm 02
İlk Program: Console.WriteLine
C#'ta ekrana yazı yazdırmanın yolu Console.WriteLine'dır. Modern C#'ta basit programlar çok sadeleşmiştir; tek satırla bir program yazabilirsin. Geleneksel yapıda ise kod bir Main metodunun içinde yer alır.
Console.WriteLine ile çıktı
Console.WriteLine("metin")— satır yazdırır.Console.Write(...)— satır atlamadan yazar.- Her ifade noktalı virgülle (;) biter.
İlk C# programın
// Modern (üst düzey) — tek satır yeterli
Console.WriteLine("Merhaba, dünya!");
// Geleneksel yapı
class Program {
static void Main() {
Console.WriteLine("Merhaba!");
}
}C#'ta her ifade noktalı virgülle biter (Python'dan farklı, PHP'ye benzer) ve kod blokları süslü parantezle { } tanımlanır (Python'ın girintisinden farklı). Geleneksel olarak her program bir Main metoduyla başlar — programın giriş noktasıdır. Modern C# (.NET 6+) bu kalıbı basitleştirdi: küçük programlarda doğrudan üst düzeyde kod yazabilirsin. WriteLine satır sonuna geçer, Write ise aynı satırda devam eder.
Konsola ne yazar?
ÇıktıConsole.WriteLine("Merhaba, dünya!"); kodu derlenip çalıştırıldığında konsola "Merhaba, dünya!" satırını yazar. Geleneksel yapıda aynı satır Main metodunun içinde yer alır; modern C#'ta tek başına da çalışır. Sonuç aynıdır: konsolda bir satır metin.
Alıştırma
10 dkİlk programı yaz:
- Kendini tanıtan üç satırlık bir C# kodu yaz (WriteLine ile).
- WriteLine ile Write arasındaki farkı bir örnekle göster.
- Main metodunun görevini kendi cümlenle açıkla.
Bölüm 03
Değişkenler ve Tipler
C#'ın kalbinde statik tipleme vardır: her değişken tanımlanırken bir tip alır ve o tipte kalır. Bu, C#'ı PHP ve Python'dan ayıran en temel özelliktir. Tipi açıkça yazabilir veya var ile derleyiciye çıkarttırabilirsin.
Statik tipli değişkenler
- Tip + ad + değer:
int sayi = 42;. - Temel tipler:
int,double,string,bool. var— tipi değerden çıkarır (yine de statiktir).- Bir kez tip belirlendi mi, değişmez:
int'e metin atayamazsın.
Değişkenler ve tipler
int sayi = 42;
string ad = "Ayşe";
double fiyat = 9.99;
bool aktif = true;
var sehir = "Ankara"; // var: tip "string" olarak çıkarılır
// sayi = "metin"; // HATA: int'e metin atanamazStatik tipleme ilk başta "fazladan yazı" gibi görünebilir, ama büyük bir güvenlik sağlar: bir değişkene yanlış türde değer atamaya çalışırsan, program çalışmadan derleyici seni uyarır. Python/PHP'de bu hata ancak çalışma anında (belki kullanıcının önünde) ortaya çıkardı. var anahtar kelimesi yazımı kısaltır ama tipi ortadan kaldırmaz — derleyici tipi değerden çıkarır ve yine sabittir. C# isimlendirme geleneği: yerel değişkenler camelCase, tipler ve metotlar PascalCase.
Konsola ne yazar?
Çıktıint sayi = 42; "sayi" adında, tipi kalıcı olarak int olan bir değişken oluşturur. Ona daha sonra "metin" atamaya çalışırsan kod derlenmez — hata alırsın. var sehir = "Ankara" ise tipi (string) otomatik çıkarır. Tablodaki her satır, bir tip–ad–değer üçlüsüdür.
Alıştırma
12 dkTipli değişken kullan:
- int, string, double ve bool tipinde birer değişken tanımla ve yazdır.
- var ile bir değişken tanımla; tipinin ne olacağını söyle.
- Statik tiplemenin sağladığı bir avantajı kendi cümlenle açıkla.
Bölüm 04
Operatörler ve İfadeler
Operatörler değerler üzerinde işlem yapar. C#'ta metinleri birleştirmenin en şık yolu, Python'daki f-string'e çok benzeyen string interpolation'dır: $"..." içinde değişkenleri süslü parantezle gömersin.
Operatörler ve string interpolation
- Aritmetik:
+ - * / %. - Karşılaştırma:
== != > < >= <=. - Mantıksal:
&&(ve),||(veya),!(değil). - String interpolation:
$"Merhaba {ad}".
Operatörler ve interpolation
int a = 10, b = 3;
Console.WriteLine(a + b); // 13
Console.WriteLine(a % b); // 1 (kalan)
Console.WriteLine(a / b); // 3 (tam sayı bölme!)
Console.WriteLine(a / 3.0); // 3.33 (ondalık)
string ad = "Ayşe";
Console.WriteLine($"Ad: {ad}");String interpolation ($"...{degisken}..."), C#'ta metin oluşturmanın en okunur yoludur — Python'ın f-string'inin neredeyse aynısıdır. Tip konusunda bir tuzağa dikkat: iki int'i bölersen sonuç da int olur ve ondalık kısım atılır (10 / 3 → 3, 3.33 değil!). Ondalık sonuç istiyorsan en az bir tarafı double yap (10 / 3.0). Bu, statik tipli dillerde sık karşılaşılan ve dikkat gerektiren bir davranıştır.
Konsola ne yazar?
Çıktı$"{ad}, {yas}" ifadesi, {ad} ve {yas} yerine değişkenlerin değerlerini koyarak "Ayşe, 30" üretir. Aritmetikte tipe dikkat: int / int tam sayı bölme yapar (kalanı atar), ondalık için bir tarafı double olmalıdır.
Alıştırma
10 dkOperatör kullan:
- İki tam sayının bölümünü hem int hem double olarak hesapla, farkı gör.
- String interpolation ile ad ve şehri tek cümlede yazdır.
- 10 / 3'ün neden 3 verdiğini açıkla.
Bölüm 05
Koşullar: if / else / switch
Koşullar programa karar verdirir. C#'ta if/else if/else yapısının yanında, çok sayıda durumu düzenli ele almak için switch deyimi de vardır. Bloklar süslü parantezle tanımlanır.
if / else if / else ve switch
if (koşul) { ... }— koşul doğruysa çalışır.else if/else— ek dallar.switch— bir değeri birçok olası duruma karşı sınar.
if / else if / else ve switch
int not = 75;
if (not >= 85) {
Console.WriteLine("Pekiyi");
} else if (not >= 60) {
Console.WriteLine("Geçer");
} else {
Console.WriteLine("Kaldı");
}
switch (gun) {
case "Pzt": Console.WriteLine("Hafta başı"); break;
default: Console.WriteLine("Diğer"); break;
}C#'ta koşullar süslü parantezle yazılır ve mantıksal operatörler PHP'deki gibidir (&&, ||, !) — Python'ın and/or/not'undan farklı. switch, bir değeri çok sayıda olası değere karşı sınarken if/else if zincirinden daha okunurdur; her case sonunda break unutma (yoksa derleyici uyarır). C#'ın koşulları "tip güvenli"dir: koşul mutlaka bool olmalıdır — bazı dillerdeki gibi sayıyı doğrudan koşul yapamazsın, bu da kazara hataları önler.
Konsola ne yazar?
Çıktınot = 75 için kod sırayla bakar: 85'ten büyük mü (hayır), 60'tan büyük mü (evet) → "Geçer" yazdırılır. switch ise bir değeri (örn. günü) tek tek durumlara karşı sınar ve eşleşen case'i çalıştırır. İkisi de programın koşula göre farklı yol izlemesini sağlar.
Alıştırma
12 dkKoşul yaz:
- Bir notu harf karşılığına çeviren if/else if/else yaz.
- Bir switch ile haftanın gününe göre mesaj yazdır.
- Koşulun neden bool olması gerektiğini açıkla.
Bölüm 06
Döngüler: for / while / foreach
Döngüler bir işi tekrar ettirir. C#'ta üç temel döngü vardır: sayaçlı for, koşullu while ve bir koleksiyonun her elemanını gezen foreach. Üçü de süslü parantezli bloklarla çalışır.
for / while / foreach
for (int i = 0; i < 5; i++)— sayaçlı tekrar.while (koşul)— koşul doğru oldukça.foreach (var x in koleksiyon)— her eleman için.
for, while ve foreach
// for
for (int i = 1; i <= 3; i++) {
Console.WriteLine(i);
}
// foreach: koleksiyonun her elemanı
string[] renkler = { "kırmızı", "yeşil" };
foreach (var renk in renkler) {
Console.WriteLine(renk);
}foreach, bir dizi veya listenin elemanlarını dolaşmanın en temiz yoludur (Python'ın for x in'ine, PHP'nin foreach'ine benzer). Klasik for ise sayaç üzerinde tam kontrol gerektiğinde kullanılır. Döngü değişkenini foreach (var renk in ...) derken var ile tanımlamak yaygındır — derleyici tipi koleksiyondan çıkarır. En sık for hatası, koşulu yanlış kurup sonsuz döngüye girmek veya dizi sınırını aşmaktır (C# bunu çalışma anında yakalayıp hata fırlatır).
Konsola ne yazar?
Çıktıfor (int i = 1; i <= 3; i++) döngüsü i'yi 1, 2, 3 yaparak gövdeyi üç kez çalıştırır ve "Satir 1/2/3" yazdırır. foreach ise bir koleksiyonun her elemanını sırayla alıp işler. İkisi de tekrar eden işi tek bir blokla ifade eder.
Alıştırma
12 dkDöngü yaz:
- 1'den 10'a sayıları yazdıran bir for döngüsü yaz.
- Bir string dizisini foreach ile dolaşıp yazdır.
- for ile foreach'i hangi durumda tercih edersin, açıkla.
Bölüm 07
Diziler ve Koleksiyonlar
Birden çok değeri bir arada tutmak için C# diziler ve koleksiyonlar sunar. Dizi (array) sabit boyutludur; List ise dinamik olarak büyüyüp küçülebilir. C#'ın tip güvenliği burada da geçerlidir: bir List bir tek tipte eleman tutar.
Dizi ve List
- Dizi:
int[] sayilar = {1, 2, 3};— sabit boyut. - List:
List<string> adlar = new();— dinamik. .Add(...)ile listeye eleman eklenir.- Erişim indeksle:
sayilar[0].
Dizi ve List
// Dizi: sabit boyut
int[] sayilar = { 10, 20, 30 };
Console.WriteLine(sayilar[0]); // 10
// List: dinamik, tip güvenli
List<string> adlar = new();
adlar.Add("Ayşe");
adlar.Add("Veli");
Console.WriteLine(adlar.Count); // 2List<T> yazımındaki <string>, "bu liste yalnızca string tutar" demektir — buna generics (genel tipler) denir ve C#'ın tip güvenliğinin güçlü bir parçasıdır. Listeye yanlış tipte eleman eklemeye çalışırsan derleyici engeller. Sabit, boyutu belli veriler için dizi; sürekli değişen (eklenen/çıkarılan) veriler için List kullan. List, PHP'nin dizilerine ve Python'ın listelerine benzer ama tip güvenlidir. İndeksler 0'dan başlar; sınır dışı erişim çalışma anında hata verir.
Konsola ne yazar?
Çıktıint[] sayilar = {10, 20, 30} sabit boyutlu bir dizidir; sayilar[0] ilk elemanı (10) verir. List<string> ise boş başlar, .Add(...) ile büyür ve .Count eleman sayısını verir. Dizi sabit, List dinamiktir; ikisi de yalnızca belirtilen tipte eleman tutar.
Alıştırma
12 dkKoleksiyon kullan:
- Üç sayıdan oluşan bir dizi oluştur ve ikincisini yazdır.
- Bir List<string> oluştur, iki eleman ekle ve sayısını yazdır.
- Dizi ile List arasındaki farkı kendi cümlenle açıkla.
Bölüm 08
Metotlar
Metot, bir işi yapan, isimlendirilmiş ve tekrar kullanılabilir bir kod bloğudur (diğer dillerdeki "fonksiyon"). C#'ta metotlar tip güvenlidir: hem parametrelerin hem de döndürdüğü değerin tipi bellidir.
Tipli metotlar
dönüş_tipi Ad(tip parametre) { ... }.returnile belirtilen tipte değer döndürür.void— değer döndürmeyen metot.
Metot tanımı
// int alır, int döndürür
int Topla(int a, int b) {
return a + b;
}
// değer döndürmez (void)
void Selamla(string ad) {
Console.WriteLine($"Merhaba, {ad}");
}
Console.WriteLine(Topla(10, 20)); // 30
Selamla("Ayşe");C# metotlarında her şeyin tipi bellidir: int Topla(int a, int b) ifadesi "iki int alır, bir int döndürür" der. Bu, metodu yanlış kullanmanı (örn. metin verip sayı beklemeni) derleyici aşamasında engeller — Python/PHP'de bu hata çalışma anında ortaya çıkardı. Değer döndürmeyen metotlar void ile işaretlenir. Metot ve sınıf isimleri C#'ta PascalCase (büyük harfle başlar) yazılır. Metotlar, Modül 6'daki "problemi parçalara bölme" ilkesinin C#'taki karşılığıdır.
Konsola ne yazar?
ÇıktıTopla(3, 5) çağrısı metodu çalıştırır, 3 + 5 hesaplar ve return ile 8 döndürür; Console.WriteLine bunu yazdırır. Selamla(...) ise bir şey döndürmez (void), doğrudan ekrana yazar. Metodun parametre ve dönüş tipleri sabittir; yanlış tip verirsen kod derlenmez.
Alıştırma
12 dkMetot yaz:
- İki sayının çarpımını döndüren (int) bir metot yaz ve çağır.
- Bir ismi alıp selam yazan bir void metot yaz.
- void ile değer döndüren metot arasındaki farkı açıkla.
Nesne Yönelimli C#
C#'ın kalbi OOP: sınıflar ve nesneler, özellikler (properties), kurucular, kalıtım, arayüzler ve çok biçimlilik.
Bölüm 09
Sınıflar ve Nesneler
Nesne yönelimli programlama (OOP) C#'ın merkezindedir. Bir sınıf (class), ilgili veriyi (alanlar/özellikler) ve davranışları (metotlar) tek bir kalıpta birleştirir. Nesne (object) ise bu kalıptan üretilen somut bir örnektir.
Sınıf ve nesne
- Sınıf: bir kalıp — özellikler + metotlar.
- Nesne: sınıftan
newile üretilen örnek. nesne.Ozellikvenesne.Metot()ile erişilir.
Sınıf ve nesne
class Kisi {
public string Ad;
public int Yas;
public void Selamla() {
Console.WriteLine($"Merhaba, {Ad}");
}
}
Kisi k = new Kisi();
k.Ad = "Ayşe";
k.Selamla(); // Merhaba, AyşeOOP, Modül 6'daki soyutlama ve "ilgili şeyleri bir arada tutma" ilkelerinin C#'taki güçlü hâlidir. PHP ve Python'da da sınıflar gördün; C#'ın farkı, OOP'nin dilin her yerine işlemiş olmasıdır — neredeyse her şey bir nesnedir. Bir sınıf bir kez tanımlanır, ondan new ile istediğin kadar nesne üretirsin; her nesne kendi verisini taşır. C# geleneğinde sınıf adları ve genel üyeler PascalCase yazılır. Sonraki bölümlerde alanları doğrudan açmak yerine özellikler (properties) kullanmanın neden daha iyi olduğunu göreceksin.
Konsola ne yazar?
Çıktınew Kisi(), sınıf kalıbından somut bir nesne üretir; k.Ad = "Ayşe" ile verisini ayarlar, k.Selamla() ile davranışını çağırırsın — konsola "Merhaba, Ayşe" yazar. Aynı sınıftan farklı nesneler (farklı kişiler) üretebilir, her birine kendi verisini verebilirsin.
Alıştırma
14 dkSınıf yaz:
- Bir "Urun" sınıfı tasarla: alanları (Ad, Fiyat) ve bir metodu.
- Sınıftan iki nesne üret ve metodunu çağır.
- Sınıf ile nesne arasındaki farkı kendi cümlenle açıkla.
Bölüm 10
Özellikler (Properties)
C#'a özgü ve çok kullanılan bir özellik: properties. Bir alanı doğrudan dışarı açmak yerine, ona kontrollü erişim sağlayan get/set bloklarıyla sararsın. Böylece veriyi okurken/yazarken araya kural koyabilirsin.
get ve set
public string Ad { get; set; }— otomatik özellik.- get: değeri okur. set: değeri yazar.
- set içinde doğrulama yapabilirsin (örn. negatif yaşı engelle).
Özellikler (properties)
class Kisi {
// Otomatik özellik
public string Ad { get; set; }
// Kurallı özellik
private int _yas;
public int Yas {
get => _yas;
set => _yas = (value < 0) ? 0 : value;
}
}Özellikler, OOP'nin kapsülleme (encapsulation) ilkesinin C#'taki şık aracıdır: verinin nasıl okunup yazıldığını sınıf kontrol eder. Basit durumlarda { get; set; } (otomatik özellik) yeterlidir; kural gerektiğinde set bloğuna doğrulama eklersin (örn. negatif yaşı sıfıra çekmek). value, set içinde "atanmak istenen değer" anlamına gelen özel bir kelimedir. Yalnızca okunabilir özellik için { get; }, dışarıdan değiştirilemeyen ama içeride ayarlanabilen için { get; private set; } kullanılır. Bu, alanları doğrudan public yapmaktan çok daha güvenlidir.
Konsola ne yazar?
Çıktık.Ad = "Ayşe" aslında özelliğin set bloğunu, Console.WriteLine(k.Ad) ise get bloğunu çalıştırır — dışarıdan basit bir değişken gibi görünse de araya kural koyabilirsin. Yas özelliğine negatif bir değer atanırsa, set bloğu onu sıfıra çevirir; veri her zaman geçerli kalır.
Alıştırma
12 dkÖzellik yaz:
- Bir sınıfa otomatik özellik (Ad) ekle.
- Fiyat için, negatif değeri engelleyen kurallı bir set yaz.
- Özelliğin alanı doğrudan public yapmaya göre avantajını açıkla.
Bölüm 11
Kurucular ve this
Bir nesne oluşturulurken başlangıç değerlerini ayarlamak için kurucu (constructor) kullanılır. Kurucu, sınıfla aynı adı taşıyan özel bir metottur ve nesne new ile üretilirken otomatik çalışır.
Kurucu ve this
- Kurucu, sınıfla aynı adı taşır;
newile çalışır. - Başlangıç değerlerini parametre olarak alır.
this— nesnenin kendisine işaret eder.
Kurucu (constructor)
class Kisi {
public string Ad { get; set; }
public int Yas { get; set; }
// Kurucu: sınıfla aynı ad
public Kisi(string ad, int yas) {
this.Ad = ad;
this.Yas = yas;
}
}
var k = new Kisi("Ayşe", 30);Kurucu, bir nesnenin geçerli bir başlangıç durumuyla doğmasını sağlar: new Kisi("Ayşe", 30) dediğinde, Ad ve Yas daha en baştan ayarlanmış olur — "yarım kurulmuş" nesne riski azalır. this, parametre adıyla özellik adı aynı olduğunda hangisinin hangisi olduğunu netleştirir (this.Ad = ad): "bu nesnenin Ad'ı, parametredeki ad olsun". PHP'deki $this ve Python'daki self ile aynı fikirdir. Bir sınıfta birden çok kurucu olabilir (farklı parametrelerle) — buna aşırı yükleme (overloading) denir.
Konsola ne yazar?
Çıktınew Kisi("Ayşe", 30) kurucuyu çağırır; kurucu, gelen "Ayşe" ve 30 değerlerini this.Ad ve this.Yas'a atar. Böylece nesne, oluşturulduğu anda geçerli verilerle hazır olur. k.Ad okunduğunda "Ayşe" döner.
Alıştırma
12 dkKurucu yaz:
- Bir "Araba" sınıfına marka ve hız alan bir kurucu yaz.
- Kurucu içinde this kullanarak değerleri ata.
- Kurucunun nesneyi "geçerli başlangıç durumu" ile kurmasının faydasını açıkla.
Bölüm 12
Kalıtım (Inheritance)
Kalıtım, bir sınıfın başka bir sınıfın özelliklerini ve davranışlarını devralmasıdır. Ortak olanı bir üst sınıfta toplar, özel olanı alt sınıflarda eklersin — kod tekrarını önlersin. C#'ta bir sınıf : ile üst sınıfını belirtir.
Üst ve alt sınıf
class Kopek : Hayvan— Hayvan'dan miras alır.- Alt sınıf, üstün üyelerini otomatik kullanır.
baseile üst sınıfa erişilir.
Kalıtım
class Hayvan {
public string Ad { get; set; }
public void Bilgi() =>
Console.WriteLine($"Ben {Ad}");
}
class Kopek : Hayvan { // miras alır
public void Havla() =>
Console.WriteLine("Hav!");
}
var k = new Kopek { Ad = "Karabaş" };
k.Bilgi(); // Ben Karabaş (devralındı)Kalıtım, "bir X bir Y türüdür" ilişkisini ifade eder: bir köpek bir hayvandır, bu yüzden class Kopek : Hayvan doğaldır. Üst sınıftaki kod alt sınıflarda tekrar yazılmadan kullanılır. C#'ta bir sınıf yalnızca tek bir sınıftan miras alabilir (çoklu kalıtım yoktur) — bu kısıtın yarattığı boşluğu bir sonraki bölümdeki arayüzler doldurur. Çok derin kalıtım zincirlerinden kaçın; gereğinden fazla kalıtım kodu kırılgan yapar. Modern tasarımda çoğu zaman arayüzler ve kompozisyon tercih edilir.
Konsola ne yazar?
ÇıktıKopek sınıfı Hayvan'dan miras aldığı için Bilgi() metodunu yeniden yazmadan kullanır: k.Bilgi() "Ben Karabaş" yazar. Havla() ise yalnızca Kopek'e özeldir. Ortak davranış üstte tanımlanır, özel davranış altta eklenir — tekrar önlenir.
Alıştırma
14 dkKalıtım kur:
- Bir "Hayvan" üst sınıfı ve ondan türeyen bir alt sınıf yaz.
- Üst sınıftaki bir metodun alt sınıfta kullanıldığını göster.
- C#'ta neden tek kalıtım olduğunu ve bunu neyin tamamladığını yaz.
Bölüm 13
Arayüzler (Interfaces)
Arayüz (interface), bir sınıfın "ne yapabileceğini" tanımlayan bir sözleşmedir — ama nasıl yapacağını söylemez. Bir sınıf bir arayüzü uyguladığında, o arayüzdeki tüm metotları sağlamayı taahhüt eder. Arayüzler, C#'ta esnek ve gevşek bağlı tasarımın anahtarıdır.
Sözleşme olarak arayüz
interface IYazdirilabilir { void Yazdir(); }— sözleşme.class Fatura : IYazdirilabilir— sözleşmeyi uygular.- Bir sınıf birden çok arayüz uygulayabilir.
Arayüz (interface)
interface IYazdirilabilir {
void Yazdir(); // gövdesiz: sözleşme
}
class Fatura : IYazdirilabilir {
public void Yazdir() =>
Console.WriteLine("Fatura yazdırıldı");
}
IYazdirilabilir nesne = new Fatura();
nesne.Yazdir(); // Fatura yazdırıldıArayüzleri bir sözleşme olarak düşün: "Beni uygulayan her sınıf şu metotları sağlamalı." Bu, kodun gevşek bağlı olmasını sağlar — bir metot, somut bir sınıf yerine bir arayüz isteyebilir (void Yazdir(IYazdirilabilir x)) ve o arayüzü uygulayan herhangi bir sınıfla çalışır. Bu esneklik, test edilebilir ve değiştirilebilir kodun temelidir. Arayüz adları C#'ta geleneksel olarak I ile başlar (IYazdirilabilir, IComparable). Kalıtımdan farkı: bir sınıf tek bir sınıftan miras alır ama birçok arayüz uygulayabilir.
Konsola ne yazar?
ÇıktıIYazdirilabilir arayüzü yalnızca "bir Yazdir() metodu olmalı" der; nasıl yazdırılacağını Fatura ve Rapor sınıfları kendi içinde belirler. IYazdirilabilir nesne = new Fatura() ile bir nesneyi arayüz tipi üzerinden tutup Yazdir() çağırırsın — hangi sınıf olursa olsun sözleşmeyi yerine getirir.
Alıştırma
14 dkArayüz yaz:
- Bir ISekil arayüzü tanımla (örn. Alan() metodu).
- Bu arayüzü uygulayan iki sınıf yaz (Daire, Kare).
- Arayüz ile kalıtım arasındaki farkı kendi cümlenle açıkla.
Bölüm 14
Çok Biçimlilik (Polymorphism)
Çok biçimlilik, aynı çağrının farklı nesnelerde farklı davranmasıdır. Bir üst sınıf metodunu alt sınıflar kendilerine göre yeniden tanımlar (override); sen tek bir çağrı yaparsın, doğru davranış nesnenin gerçek tipine göre seçilir. OOP'nin en güçlü fikirlerinden biridir.
virtual ve override
- Üst sınıf:
virtualile metodu "geçersiz kılınabilir" yapar. - Alt sınıf:
overrideile kendi davranışını verir. - Aynı çağrı, nesneye göre farklı sonuç üretir.
virtual / override
class Hayvan {
public virtual void SesCikar() =>
Console.WriteLine("...");
}
class Kopek : Hayvan {
public override void SesCikar() =>
Console.WriteLine("Hav!");
}
Hayvan h = new Kopek();
h.SesCikar(); // Hav! (Kopek'in davranışı)Çok biçimliliğin gücü şudur: bir List<Hayvan> içinde farklı türden hayvanlar (Kopek, Kedi, Kus) tutabilir, hepsini tek bir foreach ile dolaşıp SesCikar() çağırabilirsin — her biri kendi sesini çıkarır. Sen "nasıl"ı bilmek zorunda değilsin; doğru davranış çalışma anında seçilir. Üst sınıfta metot virtual olmalı, alt sınıfta override ile değiştirilir. Bu, if/else zincirleriyle tip kontrol etmekten çok daha temiz ve genişletilebilir bir tasarımdır — yeni bir hayvan türü eklemek, var olan kodu değiştirmeden mümkün olur.
Konsola ne yazar?
ÇıktıHayvan h = new Kopek() ile değişkenin tipi Hayvan ama gerçek nesne bir Kopek'tir. h.SesCikar() çağrıldığında C#, nesnenin gerçek tipine (Kopek) bakar ve onun override ettiği davranışı ("Hav!") çalıştırır. Aynı çağrı, Kedi nesnesinde "Miyav!" üretirdi — davranış nesneye göre değişir.
Alıştırma
14 dkÇok biçimlilik kur:
- Bir üst sınıfta virtual bir metot, iki alt sınıfta override yaz.
- Üst tip bir değişkenle farklı nesneleri tutup metodu çağır.
- Bu yaklaşımın if/else tip kontrolüne göre avantajını açıkla.
Güçlü Araçlar
C#'ı güçlü kılan araçlar: tip güvenliği ve dönüşümler, koleksiyonlar, LINQ ile veri sorgulama, hata yönetimi, dosyalar ve asenkron programlama.
Bölüm 15
Tip Güvenliği ve Dönüşümler
Statik tipleme güçlüdür ama bazen tipler arası geçiş gerekir: kullanıcıdan gelen metni sayıya çevirmek, bir tipi diğerine dönüştürmek gibi. C# bunu güvenli ve açık yollarla yapar; "olmayabilir" değerler için de nullable tipler sunar.
Dönüşüm ve null
int.Parse("42")— metni sayıya çevir (hata olabilir).int.TryParse(...)— güvenli çevir (başarı/başarısız).int?— null olabilen tip (değer yoksa).
Tip dönüşümleri
// Riskli: hatalı metinde çöker
int n = int.Parse("42"); // 42
// Güvenli: başarıyı bildirir
if (int.TryParse(girdi, out int sayi)) {
Console.WriteLine(sayi);
} else {
Console.WriteLine("Geçerli sayı girin.");
}
int? yas = null; // null olabilen intKullanıcıdan veya dosyadan gelen veri her zaman metindir; onu sayıya çevirirken TryParse tercih et: Parse hatalı bir metinde programı çökertir, TryParse ise sessizce "başarısız" döner ve sen nazikçe baş edersin. out anahtar kelimesi, dönüşen değeri geri almanı sağlar. Nullable tipler (int?, string?) "bu değer olmayabilir" demenin tip-güvenli yoludur — modern C#, null kaynaklı hataları derleyici aşamasında uyararak azaltır. Tip güvenliği, "boş/yanlış değer" hatalarını kullanıcının önünde değil, kodu yazarken yakalamana yardım eder.
Konsola ne yazar?
Çıktıint.TryParse(girdi, out int sayi), girdi geçerli bir sayıysa true döner ve sayıyı sayi'ya yazar; değilse false döner ve program çökmez. Böylece "12" girilince 12 yazdırılır, "abc" girilince "Geçerli sayı girin." mesajı gösterilir. Dönüşümü her zaman güvenli yoldan yaparsın.
Alıştırma
12 dkDönüşüm yap:
- Bir metni TryParse ile sayıya çeviren, hatayı ele alan kod yaz.
- Parse ile TryParse arasındaki farkı açıkla.
- int? (nullable) ne işe yarar, bir örnekle yaz.
Bölüm 16
Koleksiyonlar Derinlemesine
Diziler ve List'in ötesinde, C# zengin bir koleksiyon ailesi sunar. En çok kullanılanı, anahtar–değer çiftlerini tutan Dictionary'dir. Hepsi generics ile tip güvenlidir: ne tür anahtar ve değer tutacaklarını baştan belirtirsin.
List ve Dictionary
List<T>— sıralı, dinamik liste.Dictionary<K, V>— anahtar–değer (PHP/Python sözlüğü gibi).- Generics
<...>tip güvenliğini sağlar.
Dictionary kullanımı
var stok = new Dictionary<string, int>();
stok["kalem"] = 100;
stok["defter"] = 50;
Console.WriteLine(stok["kalem"]); // 100
foreach (var cift in stok) {
Console.WriteLine($"{cift.Key}: {cift.Value}");
}Dictionary<string, int>, "anahtarları string, değerleri int olan bir sözlük" demektir — PHP'nin ilişkisel dizilerinin ve Python'ın sözlüklerinin tip-güvenli karşılığıdır. Bir anahtara hızlıca erişmek (örn. ürün koduyla stok bulmak) için listeyi baştan sona aramaktan çok daha verimlidir. Var olmayan bir anahtara erişmek hata verir; stok.TryGetValue(...) veya stok.ContainsKey(...) ile güvenle kontrol edersin. Generics (<...>) sayesinde yanlış tipte anahtar/değer eklemeye çalışırsan derleyici engeller — koleksiyonların içeriği her zaman beklediğin tiptedir.
Konsola ne yazar?
ÇıktıDictionary<string, int> ürün adını stok sayısına eşler; stok["kalem"] ile 100 değerine doğrudan erişirsin. foreach ile her çiftin .Key (anahtar) ve .Value (değer) bilgisini dolaşıp yazarsın. Dictionary, anlamlı anahtarlarla hızlı erişim gereken her yerde idealdir.
Alıştırma
12 dkKoleksiyon kullan:
- Bir Dictionary<string, int> oluştur ve üç çift ekle.
- Bir anahtarın değerini yazdır.
- foreach ile tüm anahtar–değer çiftlerini yazdır.
Bölüm 17
LINQ ile Veri Sorgulama
LINQ (Language Integrated Query), C#'ın en sevilen ve güçlü özelliklerinden biridir: koleksiyonları, neredeyse SQL gibi, doğrudan kod içinde sorgulamanı sağlar. Süzme, sıralama, dönüştürme — hepsi okunur tek satırlarla.
Where, Select, OrderBy
.Where(x => koşul)— süz (filtrele)..Select(x => ifade)— dönüştür..OrderBy(x => ...)— sırala.
LINQ sorgusu
int[] sayilar = { 5, 30, 8, 25, 12 };
var buyukler = sayilar
.Where(x => x > 10) // süz
.OrderBy(x => x) // sırala
.ToList();
foreach (var s in buyukler)
Console.WriteLine(s); // 12, 25, 30LINQ, Modül 8'deki SQL'in mantığını (süz, sırala, seç) C# koleksiyonlarına taşır — ama veritabanı yerine bellekteki listeler üzerinde çalışır. x => x > 10 yazımı bir lambda'dır: "bir x al, x'in 10'dan büyük olup olmadığını döndür" demenin kısa yoludur. LINQ ifadeleri zincirlenebilir (.Where(...).OrderBy(...).Select(...)) ve her adım okunur kalır. Select ile dönüştürür (örn. her kişiden yalnızca adını al), Sum/Count/Average ile özetlersin. LINQ, döngülerle yazılacak çok şeyi kısa ve net hâle getirir — ama karmaşıklaşınca okunabilirliği koru.
Konsola ne yazar?
Çıktısayilar.Where(x => x > 10) yalnızca 10'dan büyük sayıları seçer; .OrderBy(x => x) onları küçükten büyüğe sıralar. Sonuç 12, 25, 30 olur ve foreach ile yazdırılır. LINQ, "şu koşula uyanları, şöyle sıralı getir" demenin kod içindeki en temiz yoludur.
Alıştırma
14 dkLINQ yaz:
- Bir sayı dizisinden çiftleri Where ile süz.
- Sonucu OrderBy ile sırala ve yazdır.
- LINQ ile SQL arasındaki benzerliği kendi cümlenle açıkla.
Bölüm 18
Hata Yönetimi
Statik tipleme birçok hatayı önler ama hepsini değil: dosya bulunamaz, ağ kesilir, kullanıcı beklenmedik veri girer. Bu çalışma-anı hatalarını C#'ta try/catch/finally ile yakalar, programın çökmesini önlersin.
try / catch / finally
try { ... }— riskli kodu dene.catch (Exception e) { ... }— hatayı yakala.finally { ... }— her hâlükârda çalışır (temizlik).
Hata yakalama
try {
int n = int.Parse(girdi);
Console.WriteLine(100 / n);
} catch (FormatException) {
Console.WriteLine("Geçerli sayı girin.");
} catch (DivideByZeroException) {
Console.WriteLine("Sıfıra bölünemez.");
} finally {
Console.WriteLine("İşlem tamam.");
}Belirli hata tiplerini yakala (FormatException, DivideByZeroException) — her şeyi tek bir genel catch (Exception) ile yutmak, gerçek sorunu gizleyip hata ayıklamayı zorlaştırır. Birden çok catch bloğu farklı hatalara farklı yanıt verir. finally bloğu, hata olsa da olmasa da her zaman çalışır — dosya kapatmak, bağlantı serbest bırakmak gibi temizlik işleri için idealdir (ya da using deyimini kullan, bir sonraki bölümde göreceksin). Backend ve PHP modüllerindeki ilkeyle aynı: hata ayrıntısını kullanıcıya gösterme, logla ve nazik bir mesaj ver.
Konsola ne yazar?
ÇıktıKullanıcı "abc" girerse int.Parse bir FormatException fırlatır; ilgili catch "Geçerli sayı girin." yazar. Sıfır girilirse bölme hatası yakalanır. Ne olursa olsun finally bloğu "İşlem tamam." yazarak çalışır. Program hiçbir durumda çökmez; her senaryoya uygun bir yanıt verir.
Alıştırma
12 dkHata yönet:
- Bir dönüşümü ve bölmeyi try/catch ile saran kod yaz.
- İki farklı hata tipini ayrı catch bloklarıyla ele al.
- finally bloğunun ne işe yaradığını açıkla.
Bölüm 19
Dosyalar ve Veri
Programlar çoğu zaman kalıcı veriyle çalışır. C#, System.IO ad alanıyla dosya okuma/yazmayı sade hâle getirir. Küçük işler için tek satırlık yardımcılar, büyük dosyalar için akış (stream) tabanlı yöntemler vardır.
Dosya okuma ve yazma
File.WriteAllText(yol, metin)— metni dosyaya yaz.File.ReadAllText(yol)— dosyayı oku.File.ReadAllLines(yol)— satır dizisi olarak oku.
Dosya okuma/yazma
using System.IO;
// Yaz
File.WriteAllText("notlar.txt", "İlk notum");
// Oku
string icerik = File.ReadAllText("notlar.txt");
Console.WriteLine(icerik); // İlk notum
// Satır satır
string[] satirlar = File.ReadAllLines("notlar.txt");Küçük dosyalar için File.WriteAllText / ReadAllText en pratik yoldur — tek satırda işi bitirir. Büyük dosyalarda (tümünü belleğe almak istemediğinde) akış tabanlı yöntemler ve using deyimi kullanılır: using var sr = new StreamReader(...), blok bitince dosyayı otomatik kapatır (Python'ın with'i gibi). Dosya işlemleri sık hata kaynağıdır (dosya yok, izin yok) — bu yüzden bir önceki bölümdeki try/catch ile sarmak iyi olur. Türkçe karakterler için kodlamayı (UTF-8) belirtmek güvenlidir.
Konsola ne yazar?
ÇıktıFile.WriteAllText("notlar.txt", "İlk notum") metni dosyaya yazar (yoksa oluşturur, varsa üzerine yazar); File.ReadAllText(...) aynı dosyayı geri okur ve konsola "İlk notum" yazdırılır. ReadAllLines ise dosyayı bir satır dizisine çevirir — her satıra ayrı erişebilirsin.
Alıştırma
12 dkDosya kullan:
- Bir dosyaya metin yazan ve geri okuyan kod yaz.
- ReadAllText ile ReadAllLines arasındaki farkı açıkla.
- Dosya işlemlerini neden try/catch ile sarmak iyi olur, yaz.
Bölüm 20
Asenkron Programlama (async/await)
Bir program, yavaş bir işi (dosya okuma, ağ isteği, veritabanı sorgusu) beklerken donmamalıdır. Asenkron programlama, bu bekleme sırasında programın başka işler yapabilmesini sağlar. C#'ta bunun aracı async ve await'tir.
async ve await
async— metodun asenkron olduğunu belirtir.await— yavaş işin sonucunu, bloklamadan bekler.- Bekleme sırasında program tepkisiz kalmaz.
async / await
async Task<string> VeriGetir() {
// ağ isteği — yavaş olabilir
string sonuc = await httpClient
.GetStringAsync("https://api.ornek.com");
return sonuc;
}
string veri = await VeriGetir();
Console.WriteLine(veri);Asenkron programlamayı bir restorandaki garson gibi düşün: bir masanın yemeğini beklerken (mutfakta hazırlanıyor) öylece durmaz, diğer masalara bakar. await, "bu yavaş işin sonucunu bekle ama bu sırada programı kilitleme" der. Bu, özellikle web sunucularında (aynı anda binlerce isteği karşılarken) ve arayüzlerde (kullanıcı beklerken donmaması için) kritiktir. async metotlar genelde Task veya Task<T> döndürür. Modern C# ve .NET'te ağ, dosya ve veritabanı işlemlerinin çoğu asenkron sürümleriyle (...Async) kullanılır. Başlangıçta soyut gelebilir; bol pratikle yerleşir.
Konsola ne yazar?
Çıktıawait httpClient.GetStringAsync(...), bir ağ isteğini başlatır ve sonucu beklerken programın bloklanmasını önler — bu sürede başka işler yürüyebilir. İstek tamamlanınca kod kaldığı yerden devam eder, dönen veri veri'ye atanır ve yazdırılır. Kullanıcı veya sunucu, bekleme boyunca tepkisiz kalmaz.
Alıştırma
12 dkAsenkronu kavra:
- async/await'in çözdüğü problemi kendi cümlenle açıkla.
- Hangi tür işler (örnekler) asenkron yapılmaya uygundur, yaz.
- await'in "beklerken bloklamaması"nın neden önemli olduğunu belirt.
C# ile Üretim
Gerçek uygulamalar: .NET ekosistemi ve NuGet, ASP.NET ile web, veritabanı, güvenlik, yayınlama ve küçük bir C# uygulaması.
Bölüm 21
.NET Ekosistemi ve NuGet
C# tek başına değil, .NET platformuyla birlikte gelir: zengin standart kütüphane, proje yapısı ve NuGet paket yöneticisi. Bu ekosistem, C#'ı web'den buluta, masaüstünden oyuna geniş bir alanda güçlü kılar.
Proje yapısı ve paketler
- .csproj: proje dosyası (ayarlar, bağımlılıklar).
- NuGet: .NET'in paket yöneticisi (pip/Composer gibi).
dotnet add package ...ile paket eklenir.
NuGet, .NET dünyasının paket yöneticisidir (Python'daki pip, PHP'deki Composer gibi): dotnet add package Newtonsoft.Json gibi bir komutla hazır kütüphaneleri projene eklersin ve bağımlılıklar .csproj dosyasına kaydedilir. bin/ ve obj/ klasörleri derleme çıktısıdır ve Git'e konmaz (başka makinede dotnet build ile yeniden üretilir) — diğer dillerdeki vendor/ ve venv/ mantığının aynısı. .NET, tek bir komut satırı aracıyla (dotnet) proje oluşturma, derleme, çalıştırma ve paket yönetimini birleştirir; bu tutarlılık, büyük projelerde işi kolaylaştırır.
Konsola ne yazar?
ÇıktıBir .NET projesinde Program.cs giriş noktasıdır, .csproj projenin ayar ve bağımlılıklarını tutar, bin/ ve obj/ ise derleme sırasında üretilir. NuGet ile eklediğin paketler .csproj'ye işlenir; böylece proje başka bir yerde tek komutla aynı bağımlılıklarla kurulur. Düzen, projeyi büyümeye ve ekip çalışmasına hazır kılar.
Alıştırma
10 dkEkosistemi tanı:
- Bir .NET projesinin temel dosyalarını ve görevlerini yaz.
- NuGet'in ne işe yaradığını kendi cümlenle açıkla.
- bin/ ve obj/ klasörlerinin neden Git'e konmadığını belirt.
Bölüm 22
C# ile Web: ASP.NET'e Bakış
C#, web uygulamaları ve API'ler geliştirmek için ASP.NET çatısını kullanır. Backend ve API modüllerinde öğrendiğin kavramlar (istek, yanıt, rota, JSON) burada C#'ın tip güvenli dünyasında hayat bulur.
İstekten yanıta
- Tarayıcı/istemci bir istek gönderir (Modül 7).
- ASP.NET, isteği doğru rotaya yönlendirir.
- Kod, veriyi işler ve bir yanıt (HTML/JSON) döner.
Basit bir API uç noktası (minimal API)
var app = WebApplication.Create();
app.MapGet("/urunler", () => {
var urunler = new[] { "Kalem", "Defter" };
return Results.Json(urunler); // JSON döner
});
app.Run();ASP.NET, Modül 7'deki (Backend) ve Modül 9'daki (PHP web) kavramların C#'taki olgun karşılığıdır: rotalar, istek/yanıt, durum kodları, JSON. Modern "minimal API" yaklaşımı, küçük servisleri çok az kodla yazmanı sağlar; büyük uygulamalar için MVC (Model-View-Controller) deseni vardır. C#'ın tip güvenliği web'de de avantaj sağlar: gelen/giden veriyi sınıflarla (modellerle) temsil edersin ve derleyici birçok hatayı yakalar. Güvenlik ilkeleri burada da değişmez — bir sonraki bölümlerde göreceğin gibi girdiyi doğrula, parametreli sorgu kullan, sırları gizle.
Konsola ne yazar?
Çıktıapp.MapGet("/urunler", ...), "/urunler adresine gelen GET isteğini şu kod karşılasın" der; kod bir ürün listesini Results.Json(...) ile JSON olarak döner. Bir tarayıcı veya başka bir uygulama bu adrese istek atınca, ASP.NET isteği bu koda yönlendirir ve dönen JSON'u istemciye iletir — tam da Modül 7'deki API mantığı.
Alıştırma
10 dkWeb'i kavra:
- ASP.NET'te bir isteğin yanıta dönüşme akışını adım adım yaz.
- Minimal API ile bir uç noktanın ne yaptığını açıkla.
- C#'ın tip güvenliğinin web'de sağladığı bir avantajı belirt.
Bölüm 23
Veritabanı ve C#
C# uygulamaları veritabanıyla konuşur: veri okur, yazar, sorgular. Modül 8'deki SQL bilgisi burada doğrudan işe yarar. Ve oradaki en kritik güvenlik kuralı C#'ta da aynen geçerlidir: kullanıcı verisini asla doğrudan sorguya gömme — parametreli sorgu kullan.
Güvenli sorgu
Parametreli sorgu
// Parametre (@ad) ile — güvenli
var cmd = new SqlCommand(
"SELECT * FROM Kisiler WHERE Ad = @ad", baglanti);
cmd.Parameters.AddWithValue("@ad", girdi);
var okuyucu = cmd.ExecuteReader();
// ... sonuçları okuBu, tüm seri boyunca tekrarlanan en kritik güvenlik kuralıdır ve C#'ta da değişmez: kullanıcıdan gelen değeri içeren her sorgu, parametreli yazılmalıdır (@ad gibi yer tutucular + ayrı verilen değerler). Böylece kullanıcı girdiye SQL yazsa bile o yalnızca aranan bir metin olur, sorgunun yapısını değiştiremez — Modül 8'deki SQL enjeksiyonu ve Modül 9'daki hazırlanmış ifadelerle aynı ilke. Pratikte çoğu C# projesi, veritabanıyla daha yüksek seviyede konuşmak için bir ORM (örneğin Entity Framework) kullanır; o da arka planda parametreli sorgular üretir. Hangi yöntemi kullanırsan kullan: girdiyi asla ham olarak sorguya katma.
Konsola ne yazar?
ÇıktıWHERE Ad = @ad sorgunun iskeletini tanımlar; cmd.Parameters.AddWithValue("@ad", girdi) ise kullanıcı verisini ayrı olarak yerleştirir. Kullanıcı ada zararlı bir SQL parçası yazsa bile, o değer yalnızca aranan bir metin olarak ele alınır — sorgunun mantığını bozamaz. Sonuç hem doğru hem güvenlidir.
Alıştırma
12 dkGüvenli sorgula:
- Kullanıcı verisini birleştiren tehlikeli bir sorguyu parametreli hâle getir.
- Parametrenin (@ad) enjeksiyonu nasıl önlediğini açıkla.
- Bu kuralın Modül 8 ve 9 ile bağını kendi cümlenle yaz.
Bölüm 24
Güvenlik İlkeleri
Statik tipleme ve derleyici, birçok hatayı önler — ama güvenlik açıklarını değil. C# uygulamalarında da, tüm seri boyunca öğrendiğin temel güvenlik ilkeleri geçerlidir. Güvenlik, dilin değil, geliştiricinin sorumluluğudur.
Olmazsa olmaz önlemler
- Girdiyi doğrula: kullanıcı/dış veriye güvenme.
- Parametreli sorgu: SQL enjeksiyonunu önle (Bölüm 23).
- Sırları gizle: bağlantı bilgisi/anahtar koda değil, yapılandırmaya.
- Şifreleri hash'le: asla düz metin sakla.
Bu ilkeler dilden bağımsızdır; C#'ta da aynen geçerlidir: kullanıcı/dış veriyi doğrula (Modül 9), veritabanı sorgularında parametre kullan (Modül 8), bağlantı bilgisi ve API anahtarı gibi sırları koda gömme — .NET'in yapılandırma sistemini (appsettings + ortam değişkenleri) kullan (Modül 7). Şifreleri güçlü bir algoritmayla hash'le, düz metin saklama. ASP.NET, kimlik doğrulama ve yetkilendirme için olgun, hazır bileşenler sunar — bunları kendin sıfırdan yazmak yerine kullan. Statik tipleme sana güvenlik vermez; o yalnızca tip hatalarını önler. Güvenlik, bilinçli bir alışkanlıktır.
Konsola ne yazar?
ÇıktıGüvenli bir C# uygulaması: dış veriyi doğrular, veritabanı sorgularını parametreli yazar, sırları koddan ayrı (yapılandırmada) tutar ve şifreleri hash'ler. Bu dört önlem, gerçek dünya saldırılarının büyük çoğunluğunu durdurur ve tüm seri boyunca tekrarlanan ortak ilkelerdir — dil değişse de güvenlik kuralları değişmez.
Alıştırma
12 dkGüvenliği uygula:
- Dört temel güvenlik önlemini ve neye karşı koruduğunu yaz.
- Sırların C#'ta nasıl saklanması gerektiğini açıkla.
- "Statik tipleme güvenlik sağlamaz" ifadesini kendi cümlenle yorumla.
Bölüm 25
Yayınlama ve Dağıtım
Uygulaman hazır olduğunda, onu çalıştırılabilir bir hâle getirip dağıtırsın. .NET, tek bir komut satırı aracıyla derleme, yayınlama ve dağıtımı kolaylaştırır; uygulaman birçok platformda (Windows, Linux, macOS) çalışabilir.
Derle, yayınla, dağıt
dotnet build— projeyi derle.dotnet publish— dağıtıma hazır çıktı üret.- Çıktıyı sunucuya/buluta taşı ve çalıştır.
dotnet publish, uygulamanı çalıştırılabilir bir pakete dönüştürür; .NET'in çapraz platform desteği sayesinde aynı kod Windows, Linux ve macOS'ta çalışır. Modern dağıtımda uygulamalar genelde kapsayıcılarda (Docker) paketlenip buluta taşınır — bu, "benim makinemde çalışıyordu" sorununu ortadan kaldırır. Üretime almadan önce kontrol listesi diğer modüllerdekiyle aynıdır: sırlar koda gömülü değil, HTTPS aktif, hata ayrıntısı kullanıcıya gösterilmiyor (loglanıyor), bağımlılıklar güncel, veritabanı yedekleniyor (Modül 8). Yayınlama, "çalışıyor" ile "güvenle üretimde" arasındaki köprüdür.
Konsola ne yazar?
Çıktıdotnet build projeyi derleyip hataları yakalar; dotnet publish ise dağıtıma hazır, çalıştırılabilir bir paket üretir. Bu paketi bir sunucuya veya bulut ortamına taşıyıp çalıştırırsın — .NET'in çapraz platform desteğiyle çoğu işletim sisteminde sorunsuz koşar. Son adım, üretimde uygulamayı izlemek ve sağlıklı tutmaktır.
Alıştırma
10 dkDağıtıma hazırlan:
- build, publish ve deploy adımlarının ne yaptığını yaz.
- Üretime almadan önce kontrol edeceğin dört maddeyi listele.
- Kapsayıcıların (Docker) sağladığı bir faydayı belirt.
Bölüm 26
Bitirme: Küçük Bir C# Uygulaması
Öğrendiklerini birleştirip baştan sona küçük bir C# uygulaması tasarlıyorsun: tipli veriyi al, sınıflarla modelle, işle, sakla ve sun. Bu, gerçek bir C# uygulamasının çekirdeğidir ve seriyi diller açısından tamamlar.
Bir "görev yöneticisi" akışı
Uygulama kontrol listesi
// 1. Girdiyi al ve DOĞRULA (TryParse)
// 2. Veriyi SINIFLARLA modelle (class Gorev)
// 3. List<Gorev> + LINQ ile süz/sırala
// 4. try/catch ile hataları ele al
// 5. Dosya veya parametreli sorgu ile SAKLA
// 6. Sırlar yapılandırmada + okunur kodGerçek bir C# uygulaması yazarken bu sırayı izle: girdiyi doğrula (TryParse), veriyi sınıflarla modelle, koleksiyonlar ve LINQ ile işle, hataları try/catch ile yakala, sonucu dosya veya parametreli sorgu ile sakla, sırları yapılandırmada tut. Bu modülle birlikte üç dili (PHP, Python, C#) tamamladın ve önemli bir şeyi gördün: kavramlar ortaktır, sözdizimi değişir. Değişkenler, koşullar, döngüler, fonksiyonlar/metotlar, OOP, güvenlik — hepsi her dilde var. C# sana tip güvenliğini ve yapıyı; Python sadeliği; PHP web'in pratikliğini öğretti. Artık yeni bir dile geçmek çok daha kolay; çünkü öğrenilen şey dil değil, programlama düşüncesidir.
Konsola ne yazar?
ÇıktıTasarladığın görev yöneticisi: kullanıcıdan görevleri alır (doğrulayarak), her görevi bir Gorev sınıfıyla modeller, List<Gorev> içinde tutup LINQ ile süzer/sıralar, hataları yakalar ve sonucu dosyaya veya veritabanına güvenle saklar. Tipli modeller, koleksiyonlar, LINQ ve güvenlik bir araya gelince — çalışan, sağlam, gerçek bir C# uygulaması ortaya çıkar.
Alıştırma
20 dkUygulamanı tasarla:
- Küçük bir uygulama seç (görev listesi, kişi rehberi, basit envanter).
- Veriyi hangi sınıf(lar)la modelleyeceğini yaz.
- Al → modelle → işle (LINQ) → sakla akışını fonksiyonlara böl.
- Hangi güvenlik ve hata yönetimi önlemlerini ekleyeceğini belirt.
Ek
C# Terimleri ve Komutları Sözlüğü
En sık kullanılan C# yapıları ve komutları. Bir başvuru kaynağı olarak saklayabilirsin.
C#'ın özeti
ÇıktıC# derlenen, statik tipli ve güçlü nesne yönelimli bir dildir. Console.WriteLine ile yazdırır, tipli değişkenlerle (int, string...) veri taşır, if/switch ve döngülerle akışı yönetir. Diziler ve List<T> koleksiyonları tip güvenlidir; metotlar, sınıflar, özellikler, arayüzler ve kalıtım OOP'nin temelidir. LINQ ile veriyi sorgular, async/await ile asenkron çalışır, .NET platformunun zengin kütüphanesinden yararlanırsın. Derleyici ve statik tipler birçok hatayı çalışmadan önce yakalar — ama güvenlik yine senin sorumluluğun: girdiyi doğrula, parametreli sorgu kullan, sırları gizle.