3 Nisan 2009 Cuma

C#'ta ?? operatörü

C#'ta daha önce hiç karşılaşmadığım bir operatörle karşılaştım: "??" Daha da ilginci, bu operatörün ne olduğunu araştırınca bir de "?" operatörü ile karşılaştım. "?:" operatörünü biliyordum ama bu ikisini ilk defa görüyorum.


"??" operatörü, bir "binary operator", yani toplama, çıkarma operatörleri gibi sağına ve soluna operand olan bir operatör. Sol taraftaki operand null değilse onu döndürüyor, null ise sağdakini döndürüyor.

Mesela:

string s = null;
string y = s ?? "Undefined";

Bu örnekte s'nin değeri null olduğundan, y'nin değeri "Undefined" olacak. s, null olmayan bir string olsaydı, x'in değeri y'ye kopyalanacaktı.

Gelelim "?" olayına... Normalde bir string değişken null değeri alabilir ama bir int değişkenin değeri null olamaz. Ama siz değeri null olan bir int değişkeni tanımlamak istiyorsanız bu değişkeni int tipinde değil de int? tipinde tanımlayabiliyorsunuz.

Mesela:

int x = null;

yazdığınızda derleyici hata verir; çünkü int değişkene null değeri atanamaz. Ama,

int? x = null;

yazarsanız derleyici hata vermez. Bu tür null değeri alabilen tiplere "Nullable Types" deniyormuş.

"??" operatörü C# 2.0 versiyonundan itibaren kullanılabiliyormuş.

Peki böyle bir operatöre neden ihtiyaç duyulmuş?

Veritabanlarında alanların tipini belirleyebiliyoruz ama bu alanlara değer girilmezse oradaki değer null olarak tutuluyor. Veritabanından gelen değeri, null olamayan bir değişkene atamaya çalışırsanız çalışma zamanı hatası meydana geliyor. Bu yüzden veritabanından gelen verilerin null olup olmadığını kontrol etmek gerekiyor.

Bu problemin üstesinden gelmek için ben kodlarımı şöyle kullanıyordum:

string duyuru = (dbRow["Duyuru"].GetType() != typeof(DBNull)) ? (string)dbRow["Duyuru"] : string.Empty;

Buradaki dbRow, veritabanından gelen bir kaydı gösteriyor. Bu kayıttaki "Duyuru" alanını çekmek için dbRow["Duyuru"] kullanılıyor. Fakat bu ifade, geriye bir "object" sınıfından bir nesne döndürüyor. Dolayısıyla o satırdaki duyuru null ise, dbRow["Duyuru"] ifadesi geriye bir DBNull nesnesi döndürüyor. Bunu string'e çevirmeye çalıştığınızda da hata meydana geliyor. Bundan dolayı ifadenin tipinin DBNull olup olmadığı kontrol edilmeli. Eğer DBNull ise, duyuru string'ine boş bir string atanmalı.

?? operatörünü öğrendikten sonra yukarıdaki satırı şu şekilde yazmak mümkün olacak diye tahmin ediyorum (ama denemem lazım):

string duyuru = (string)dbRow["Duyuru"] ?? string.Empty;