Öncelikle erişim belirleyicilerin (access modifiers) nerelere uygulandığını bilmemiz lazım; C# projesinde tanımlanmış tüm varlıklara uygulanabilir, buna class, struct, function, method, property ve class seviyesindeki tüm değişkenler dahildir.
Peki, neden erişim belirleyicilere ihtiyaç duyarız?
Çünkü, uygulamamızda kullandığımız varlıkların bulundukları kod bloğunun dışından erişilip/erişilemeyeceğini belirlemek isteriz.
C# dilinde tanımlı erişim belirleyiciler (access modifiers);
public : public olarak tanımlanan öğe, kod bloğunun içinde ve dışında tamamen erişilebilirdir. Yani, hiçbir kısıtlama yoktur.
protected : protected olarak tanımlanan öğe, sadece tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilirdir.
internal : internal olarak tanımlanan öğe, bulunduğu assembly’nin (Dll veya Exe dosyası) içinde erişilebilirdir. Dll veya Exe dosyasının içerisinde erişim için kısıtlama yoktur, ama dışarıdan erişilemez.
protected internal : protected internal erişim belirleyicisi, protected ve internal erişim belirleyicilerinin VEYA (OR) işlemiyle birleştirilmiş halidir. protected internal olarak tanımlanmış öğe, tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilir. Ayrıca, aynı assembly içinde olmasalar dahi, tanımlandığı class’tan türetilmiş diğer class’ların içinde de erişilebilirdir.
private : private olarak tanımlanan öğe, sadece tanımlandığı class’ın içerisinde erişilebilirdir. En katı erişim belirleyicidir.
Aslında CLR içinde tanımlı bir erişim belirleyici daha vardır. FamilyAndAssembly olarak bilinir. C# kelimeleri ile benzetmeye çalışırsak, protected VE (AND) internal erişim belirleyicisidir. C# dili bu erişim belirleyicisini desteklemez, eğer kullanmanız gerekiyorsa, C++ ve direk IL yazmanız gerekmektedir.
class veya struct‘lar ya public, ya da internal olabilir, varsayılan olarak internal erişim belirleyicisine sahiptirler.
Varsayılan olarak class içerisinde tanımlı öğeler private erişim belirleyicisine sahiptirler.
struct içerisinde tanımlı öğeler public, internal veya private olabilirler. struct‘lar türetmeyi desteklemediği için protected ve protected internal erişim belirleyicisine zaten ihtiyaçları yoktur.
Uygulamalarımızı geliştirirken birçok class veya struct yazmamız gerekir.
Bu class veya struct‘ların hemen hepsinde özelliklere (properties) ihtiyaç duyarız.
Çünkü, local değişkenlerin public değil, private olmasını isteriz. Bu durumda yapmamız gereken public olmasını istediğimiz local değişkenlere birer tane özellik (property) yazmaktır.
Örnek Personel Class‘ı aşağıdaki gibi olacaktır;
public class Personel { private int PersonelId; private string AdSoyad; }</pre>
public class Personel { private int _PersonelId; private string _AdSoyad; public int PersonelId { get { return _PersonelId; } set { _PersonelId = value; } } public string AdSoyad { get { return _AdSoyad; } set { _AdSoyad = value; } } }
Sadece okuma/yazma yapan iki özellik için ne faz kod yazdık, değil mi?
Eğer get/set blokları arasına özel iş yapan kod yazmamız gerekiyorsa, yukarıdaki gibi yapmaya devam etmeliyiz.
Fakat sadece okuma/yazma yapan özellikleri C# 3.0‘dan itibaren daha kısa yazabiliyoruz;
public class Personel { public int PersonelId { get; set; } public string AdSoyad { get; set; } }
Gördüğünüz gibi local değişkenlerin oluşturulması ve yönetilmesi işini yapmakla uğraşmıyoruz.
Eğer local değişkenlerin nasıl oluşturulduğunu merak ediyorsanız, projenizi compile ettikten sonra, ortaya çıkan exe/dll dosyasını ILDASM (Intermediate Language Disassembler) tool’u ile açıp bakabilirsiniz.
PersonelId özelliği için <>k__AutomaticallyGeneratedPropertyField0 isimli bir değişkenin oluşturulduğu ve tipininde int olduğunu göreceksiniz.
Otomatik oluşturulan değişken’in ismini herhangi bir kod parçasında kullanmaya çalışırsak, derleme (compile) zamanında yazım hatası (syntax error) alırız, yani local değişkenleri kullanamayız.
Eski stil kodlamada sadece okunabilir (readonly) veya sadece yazılabilir (writeonly) property tanımlayabiliyorduk. Bunu yeni stil kodlamada da yapabilir miyiz?
Cevap Evet, aşağıdaki kodu inceleyin;
public class Personel { public int PersonelId { get; private set; } public string AdSoyad { private get; set; } }
Uygulamanızda tarih göstereceğiniz ekranlarda, tarihin gününü de göstermek istersiniz. Hatta gün isimlerinin, kullanıcının dilinde olmasını istersiniz.
Öncelikle ilgili tarihin hangi güne geldiğini bulalım;
int gun1 = (int)DateTime.Now.DayOfWeek; int gun2 = (int)DateTime.Now.AddMonth(-5).DayOfWeek; int gun3 = (int)DateTime.Parse(“2009-01-05”).DayOfWeek;</pre> Dikkat etmemiz gereken şey; DayOfWeek ilgili tarihin hangi güne denk geldiğini bulurken, Pazar gününü baz alır.
Uygulamayı kullanan kullanıcının kendi dilinde gün ismini bulmak için;
string gun1 = DateTime.Now.ToString("dddd"); string gun2 = DateTime.Now.DayOfWeek; string gun3 = DateTime.Parse("2009-01-05").DayOfWeek; string gun4 = CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek];
İlgili tarihin hangi güne geldiğini başka bir dilde bulmak için;
string gun5 = CultureInfo.GetCultureInfo("tr-TR").DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek]; string gun6 = CultureInfo.GetCultureInfo("de-DE").DateTimeFormat.DayNames[(int)DateTime.Now.DayOfWeek];
Null Coalescing Operatörü (??) C# dilinin gözden kaçan, ama çok kullanışlı bir operatörüdür.
?? operatörü sayesinde bir değişkenin değerinin null olduğu durumda alternatif değer döndürebiliriz.
string mesaj = “merhaba dünya!”; string sonuc = mesaj ?? “mesaj yok”;</pre>
Eğer mesaj değişkeni null değer içeriyor olsaydı, sonuc değişkenine “mesaj yok” değeri atanacaktı.
string mesaj = null; string sonuc = mesaj ?? "mesaj yok";
int? yas = 30; int sonuc = yas ?? -1;
Eğer yas değişkeni null ise, sonuc değişkenine -1 değeri ata.
int? yas = null; int sonuc = yas ?? -1;
Sql Server 2008 ile hayatımıza yeni bir operatör geldi : MERGE.
MERGE Operatörü koşullu olarak INSERT ve UPDATE yerine geçen bir operatördür.
İşlem yapmak istediğiniz kaydın varlığına bağlı olarak INSERT veya UPDATE işlemlerinden birisini gerçekleştirir.
Eskiden bu işi gerçekleştirmek için, her satır için çalışan bir döngü içerisinde satırın varlığını kontrol ettirdiğimiz IF kontrolü olurdu, ya INSERT cümlesini ya da UPDATE cümlesini çalıştırırdık.
MERGE operatörünün ana kullanım alanı DataWarehouse‘lar olacaktır.
OLTP mimarisinde veritabanınız içinde bulunan verilerinizin, OLAP mimarisinde veritabanınıza işlemek istediğinizde, varolan satırları UPDATE etmek, varolmayan satırları INSERT etmek istersiniz.
MERGE operatörü, bu karmaşık yapının oldukça basitleşmesini sağlıyor.
Kullanım şablonu;
MERGE INTO Tablo USING (SELECT Cümlesi) WHEN MATCHED THEN UPDATE Cümlesi WHEN NOT MATCHED THEN INSERT Cümlesi</pre>
AdventureWorks 2008 veritabanında bulunan Production.UnitMeasure tablosunda bu özelliği nasıl kullanabileceğimizi bir örnek ile inceleyelim;
MERGE Production.UnitMeasure AS T USING (SELECT 'KG', 'Kilogram') AS S (UnitMeasureCode, Name) ON (T.UnitMeasureCode = S.UnitMeasureCode) WHEN MATCHED THEN UPDATE SET Name = S.Name WHEN NOT MATCHED THEN INSERT (UnitMeasureCode, Name) VALUES (S.UnitMeasureCode, S.Name)
Senior Software Engineer, @Microsoft
Ada ve Ege'nin babası ;)
Makale Adedi: 484