C#'ta var ve açık tip bildirimi arasındaki fark, türün koda nerede yazıldığıdır: açık tip bildiriminde tür satırda görünür, var kullanıldığında ise derleyici türü sağ taraftaki ifadeden kendisi çıkarır. İki yazım da değişkene kesin ve sabit bir tür verir. Hangisini seçeceğin çoğunlukla okunabilirlik meselesidir.
var ve açık tip bildirimi arasındaki temel fark
var bir değişkeni türsüz bırakmaz. Derleyici, atamanın sağ tarafına bakar, türü belirler ve değişkeni o türle derler. Bu yüzden şu cümle işin özünü verir: var, dinamik tür değil, derleme zamanında belirlenen tür çıkarımıdır.
Aşağıdaki iki satır, derlenmiş sonuçta aynı türü üretir:
int sayi = 5; // tür açıkça yazılmış
var sayi = 5; // tür sağ taraftan çıkarılır (yine int)
İkinci satırda sayi değişkeni int olur. Sonradan ona bir metin atamaya çalışırsan derleyici hata verir. Yani fark değişkenin davranışında değil, kodu okuyan kişinin türü nereden göreceğindedir. İlk satırda tür doğrudan yazılıdır; ikincisinde sağ taraftaki değeri okuyarak türü sen çıkarırsın.
string, int ve List<int> ile var nasıl çalışır?

Çıkarılan türü görmenin en kolay yolu, değişkenin türünü çalışma sırasında yazdırmaktır. Aşağıdaki küçük konsol programı üç farklı değer için var kullanır:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var ad = "Ayşe";
var yas = 16;
var notlar = new List<int> { 70, 85, 90 };
Console.WriteLine(ad.GetType());
Console.WriteLine(yas.GetType());
Console.WriteLine(notlar.GetType());
}
}
Beklenen çıktı üç satırdır:
System.String
System.Int32
System.Collections.Generic.List`1[System.Int32]
Derleyici "Ayşe" için string, 16 için int, new List<int> ifadesi için List<int> türünü çıkarmıştır. Çıktıdaki System.String ve System.Int32, C#'taki string ve int anahtar sözcüklerinin .NET tarafındaki adlarıdır. Aynı satırları string ad = "Ayşe";, int yas = 16; ve List<int> notlar = new List<int> { 70, 85, 90 }; biçiminde açık tiple yazsan da çıktı birebir aynı olur.
Bu örnekte List<int> satırı dikkat çekicidir: açık tipte türü iki kez yazarsın, var ile bir kez. Kendi bilgi düzeyini görmek istersen ücretsiz C# bilgi testi tür, değişken ve temel sözdizimi konularında seviyeni ölçmene yardımcı olabilir. Test yalnızca seviye ölçümüdür.
var ile dynamic aynı şey mi? Derleme zamanı ve çalışma zamanı farkı
Hayır, aynı şey değildir. var kullandığında derleyici tür çıkarımını derleme sırasında yapar ve değişkenin türü o noktada sabitlenir. dynamic ise tür denetimini çalışma zamanına erteler.
var sayi = 10; // derleyici türü int olarak sabitler
sayi = "on"; // derleme hatası: string, int'e örtük dönüştürülemez
dynamic esnek = 10;
esnek = "on"; // derlenir, tür çalışma zamanında belirlenir
Console.WriteLine(esnek);
İlk blokta ikinci satır program çalışmadan önce hata verir. Derleyici sayi değişkenini int olarak kaydettiği için bir string atamasını kabul etmez. Microsoft dokümantasyonunda bu durum CS0029 koduyla, bir türün diğerine örtük olarak dönüştürülemeyeceğini söyleyen hata biçiminde yer alır. Hatanın düzeltilmesi için ya değer int olmalı ya da değişkenin türü baştan string olmalıdır.
İkinci blokta ise esnek önce bir tamsayı, sonra bir metin tutar. Bu kod derlenir ve çalıştırınca ekrana on yazar. Aynı değişkene farklı türler atayabilmenin karşılığı, olası tür uyumsuzluklarının derleme aşamasında yakalanmamasıdır; hata ancak kod o satıra geldiğinde ortaya çıkar.
Kısacası var yazım kolaylığıdır, tür güvenliğinden vazgeçmez. dynamic ise türü bilinçli olarak çalışma zamanına bırakan ayrı bir mekanizmadır.
var'ın kullanılamadığı durumlar

Derleyici türü, sağ taraftaki ifadeye bakarak çıkarır. Sağ taraf yoksa ya da türü belli etmiyorsa çıkarım yapılamaz. Bunu iki örnekte adım adım görebilirsin.
1. Başlangıç değeri olmayan bildirim
var x; satırında derleyicinin bakacağı bir ifade yoktur. Değişkene ileride ne atanacağını tahmin etmek derleyicinin işi değildir, bu yüzden bildirim hata verir. Çözüm, ya bir başlangıç değeri vermek ya da türü açıkça yazmaktır.
2. null ile başlatma
var y = null; satırında sağ tarafta bir ifade vardır ama null tek başına belirli bir türü göstermez. string, List<int> ya da başka bir başvuru türü olabilir. Çıkarılacak tür bulunmadığı için derleyici burada da türü belirleyemez.
// Hatalı: sağ taraf yok, tür çıkarılamaz
// var x;
// Hatalı: null hangi türe ait olduğunu söylemiyor
// var y = null;
// Düzeltme 1: türü açıkça yaz
int x;
x = 5;
// Düzeltme 2: null için türü belirt
string y = null;
// Alternatif: değeri baştan ver, var kullanabilirsin
var z = 5; // int olarak çıkarılır
Her iki durumda da kural aynıdır: var kullanabilmek için bildirim satırında türü belirleyen bir ifade bulunmalıdır. Bu ifade yoksa açık tip bildirimi zorunlu hâle gelir.
Hangi satırda var, hangisinde açık tip? Karar çerçevesi
Her satır için kendine şu dört ölçütle soru sorabilirsin: Okunabilirlik, türün satırda görünür olması, sayısal dönüşüm ihtiyacı ve ifadenin karmaşıklığı.
Sayısal dönüşüm ölçütü en kolay gözden kaçan ölçüttür, çünkü türü sayısal literal belirler. var fiyat = 10; yazdığında fiyat bir int olur. decimal fiyat = 10; yazdığında ise değişken decimal olur ve 10 bu türe dönüştürülür. var fiyat = 10m; yazarsan sağdaki m soneki literali decimal yapar, derleyici de değişkeni decimal olarak çıkarır. İki yolla da aynı türe ulaşabilirsin, fark niyetin nerede görünür olduğudur.
| Ölçüt | var'ın uygun olduğu durum | Açık tipin uygun olduğu durum |
|---|---|---|
| Okunabilirlik | Tür satırda zaten okunuyor, tekrarı gürültü yaratıyor | Tür satırdan anlaşılmıyor |
| Türün görünür olması | Sağ tarafta new ya da açık bir literal var | Okurun türü başka bir yere bakarak bulması gerekiyor |
| Dönüşüm ihtiyacı | Literalin türü zaten istediğin tür (10m, 2.5) | İstediğin tür ile ifadenin doğal türü farklı olabilir (int, double, decimal) |
| Karmaşık ifadeler | Tür adı çok uzun ya da anonim tür söz konusu | Metot dönüşü veya LINQ sonucu türü okurdan saklıyor |
Bu tablo bir kural listesi değil, düşünme çerçevesidir. var her durumda önerilmez, açık tip de her satırda dayatılmaz. Ekibinin yazım stili ve projenin kod kuralları da başlı başına bir ölçüttür: Ortak bir kural varsa ona uymak, tek tek satır zevkinden daha değerlidir.
Açık tip bildiriminin daha anlaşılır olduğu satırlar
Bazı satırlarda var, okura küçük bir bilmece bırakır. Şu örneğe bak:
using System;
using System.Collections.Generic;
var oran = 7 / 2;
double oranNet = 7 / 2.0;
var liste = new List<int>();
Console.WriteLine(oran);
Console.WriteLine(oranNet);
Console.WriteLine(liste.Count);
Beklenen çıktı:
3
3.5
0
var oran = 7 / 2; satırında iki tam sayı bölündüğü için tür int olur ve sonuç 3'tür. Okur bunu bilmiyorsa 3,5 bekleyebilir. double oranNet = 7 / 2.0; satırı ise ondalıklı sonuç istediğini açıkça gösterir. Aynı durum para hesaplarında double ile decimal arasındaki seçim için de geçerlidir: türü satırda yazmak, niyeti de yazmaktır.
Metot dönüşlerinde de benzer bir durum vardır. var sonuc = Hesapla(); satırını okuyan kişi, sonuc'un int, decimal ya da bir koleksiyon olduğunu görmek için metodun tanımına gitmek zorunda kalır. decimal sonuc = Hesapla(); bu yolculuğu kısaltır. LINQ sonuçlarında da aynı soruyu sorabilirsin.
Karşı örnek de ortadadır: var liste = new List<int>(); satırında tür sağ tarafta açıkça yazıyor. Aynı bilgiyi soldan tekrar etmek okumaya bir şey katmaz, bu yüzden var burada rahat bir tercihtir. Veri türü seçimini satır satır tartmak, C#'a özgü bir ayrıntı değil, dilden bağımsız bir beceridir. Bu becerinin ne durumda olduğunu görmek istersen dilden bağımsız Algoritmik Düşünme Testi'ni çözebilirsin.
Bir değişkeni yazarken şu kontrol sorusunu kullan: Bu satırı ilk kez okuyan biri türü saniyeler içinde anlıyor mu?