C# 4.0 – Yeni Özellikler


Bilgisayarı meslek haline getirmiş bir insan sürekli değişime açık olmalıdır. Bizim mesleğin en önemli özelliklerinden biridir, yeniliklere açık olmak. Bilgisayarcı, yeni bir teknolojiyi, yöntemi hemen pratikte kullanabilmelidir. Bunu yapamazsa; belki parasını yine alır ama bence o artık bilgisayarcılıktan uzaklaşmaya başlamıştır.

36 gün önce Visual Studio 2010 resmi olarak piyasaya çıktı. Birlikte .NET Framework 4 ile birlikte C# 4.0 da yenilikleriyle birlikte geldi. Hazır finaller arasında bir gün bulmuşken bu makale ile size bu yeniliklerden bahsetmeye çalışacağım.

Öncelikle metodları tanımlarken artık parametrelere varsayılan değer verebiliyoruz ve metodu çağırırken parametreleri istediğimiz sırada kullanabiliyoruz. Örneğin metod tanımlarken;

private void Metod1(int param1, int param2, string param3 = “def”, DateTime param4 = DateTime.Now)
{
     // Metod1 içeriği
}

param3 ve param4 parametrelerinde; eğer özellikle kullanılmazlarsa alacağı değerleri belirtilmiştir. Bu PHP, JS gibi dillerde zaten varolan birşeydi, C#’ a eklenmesi de isabet olmuş. Buna aslında metodları aşırı yüklemenin değişik versiyonu diyebiliriz. Eskiden olsaydı bunu şu şekilde yapmamız gerekirdi:

private void Metod1(int param1, int param2)
{
    string param3 = “def”;
    DateTime param4 = DateTime.Now;
    // Metod1  içeriği
}
private void Metod1(int param1, int param2, string  param3)
{
    DateTime param4 = DateTime.Now;
    // Metod1  içeriği
}
private void Metod1(int param1, int param2, string  param3,  DateTime param4)
{
    // Metod1  içeriği
}

Metodların kullanımında ise şöyle bir yenilik göze çarpıyor;

Metod1( param2:1500, param1:3, param4:new DateTime(1989, 11, 18));

Gördüğünüz gibi parametrelerin sırası önemli değil. Çünkü, parametrelere direkt isimlerini göstererek değer veriyoruz. Bu özellik çok fazla opsiyonel parametre barındıran metodlarda gerçekten çok yardımcı olabiliyor.
DLR
İkinci yenilik ise DLR‘ nin gelmesiyle birlikte kullanabildiğimiz dinamik nesneler. Bu nesneler dynamic kelimesi ile belirtilen değişkenlerde tutuluyorlar. Bu değişkenlerin özelliği, çalışma zamanında denetlenmesi. Örnek olarak aşağıdaki kod parçasına bakabiliriz.

// string s = “deneme”;
// dynamic s = “deneme”;
s.HedeHode();

“s” değişkenini string olarak tanımlayıp 3. satırı öyle çalıştırmaya çalışırsak derleme anında hata alırız. Bunun yerine dynamic olarak tanımlayıp çalıştırsak çalışma zamanında exception alırız. Derleme zamanında hata almak yerine çalışma zamanında exception almak bizim ne işimize yarar. Bu soruyu kendime sordum, aşağıdaki gibi bir cevap çıktı.

Daha önce burada değindiğim Reflections konusunda bu işlev bize çok yardımcı olabilir. Şöyle ki;

// DLL içerisindeki sınıfımız aşıdaki gibi olsun
// ——————————————–
// public class MyClass
// {
//      private int i = 0;
//      public MyClass()
//     {
//           Random rnd = new Random();
//           i = rnd.Next();
//     }
//
//      public int Fonk()
//      {
//           return i;
//      }
//}
// ——————————————–
Assembly asm = Assembly.LoadFrom(“sinifim.dll”);
Type MyClass = asm.GetType(“MyClass”);
dynamic obj = MyClass.GetConstructors()[0].Invoke(null);
/*
// Önceden “Fonk” metodunu çağırıp geri döndürdüğü değeri yazdırmak
// için aşağıdaki 3 satırı kullanmamız gerekiyordu
MethodInfo mi = MyClass.GetMethod(“Fonk”);
int sayi = (double) mi.Invoke(obj, null);
Console.WriteLine(sayi);
*/
// Bunun yerine aşağıdaki tek satır (yani bildiğimiz metod çağırma yöntemi)
// bize daha az karmaşık kod imkanı veriyor.
Console.WriteLine(obj.Fonk());

Çünkü, yukarıda çalışma zamanı tip yüklemesi ve tanımlaması gerkçekleştiriyoruz. Bu yüzden, bir metodun derleme anında var mı yok mu diye kontrol edilmesi işimize engel oluyor.

Kendime soru sormayı bırakıp MSDN’ e bu soruyu sorduğumda ise, MSDN bana iki güzide System.Dynamic öğesinden bahsetti. DynamicObject ve ExpandoObject. Aslında ExpandoObject, DynamicObject’ in değiştirilmiş hali. Bu sınıflar kullanılarak nesnelere satır-içi üye atanabiliyor.

Örneğin;

dynamic nesne = new System.Dynamic.ExpandoObject();
nesne.Sinan = “Bir string”;
nesne.Sayi = 2010;
nesne.Kayit = new DateTime(2010, 5, 19);
Console.WriteLine(nesne.Sinan);
Console.WriteLine(nesne.Kayit);

“nesne” nesnesinin “Sinan”, “Sayi”, “Kayit” gibi üyeleri yok iken sadece atama yaparak üyeleri dinamik olarak oluşturduk ve daha sonra da kullandık. Yani genişleyebilen bir nesnemiz oldu. Yalnız birşeye değinmek istiyorum, bu genişleme işlemi eğer öyle bir üyeye sahip değilse geçerlidir. ExpandoObject sınıfı ayrıca “Count” isimli bir özelliğe sahiptir. Eğer

nesne.Count = 5

gibi bir atama yapmaya kalkışırsak hata ile karşılaşırız, çünkü Count isimli özellik daha önceden vardır ve set metodu tanımlı değildir. Bu ayrımı DynamicObject’ i anlattığım zaman daha iyi anlayacaksınız. Bunların yanında; ExpandoObject, IDictionary arayüzünden türediği için foreach içerisinde kullanılabilir. Yani yukarıda örnekteki “nesne” yi şu şekilde kullanabiliriz:

foreach (dynamic item in nesne)
{
    Console.WriteLine(item);
}

Çıktısı da şu şekilde olacaktır.Çıktı

DynamicObject ise geliştirilebilir, kendimize özel bir dinamik nesne oluşturmamızı sağlar. Bu sınıf ile aslında dinamik nesnelerin tam olarak yapısını anlayabiliriz. Bu nesneler (ExpandoObject de dahil) birer Dictionary gibi çalışırlar. Yani Key-Value ilişkisi vardır. Aşağıdaki örnekte basit bir dinamik nesne sınıfı tanımlıyoruz.

public class SampleObject : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = binder.Name;
        return true;
    }
}

DynamicObject tarafında virtual olarak tanımlanan TryGetMember metodu biz varolmayan bir üyeye erişmek istediğimizde çağırılır. Aşağıdaki gibi …

dynamic obj = new SampleObject();
Console.WriteLine(obj.DenemeOzelligi);

Yukarıdaki kod parçası “DenemeOzelligi” çıktısını verir. Çünkü; DenemeOzelligi adında varolmayan bir üye çağrılmak istenir, böyle bir üye bulunmadığı için de TryGetMember metodu devreye girer. “binder” parametresinin “Name” özelliği istenen üyenin adını (buradaki “DenemeOzelligi”) taşır. İstenin üyenin ismi result parametresine aktarılır ve true döndürerek başarıldığı bildirilir. (Eğer false döndürürse Exception oluşur). Kısacası, geriye dönen değer erişilmek istenen üyenin adına eş olur.

Bunun yerin sınıfımız içerisinde bir liste tutabilir, istenen öğeyi bu liste içerisinden döndürebilirdik ya da daha gelişmiş bir sınıf yardımıyla XML belgelerimizi böyle bir sınıf yardımıyla okuyup, yönetebilirdik. Yapabileceklerimiz bize kalmış.

Yazarken arada mola verdiğim için bazı yerlerde kopukluklar olabilir. Mantık hatası varsa bildirebilirsiniz.

Popularity: 39%

, , , , ,

  1. #1 by halit on 19 Mayıs 2010 - 23:19

    Bu güzel çalışma için teşekkürler.Yazılarının devamını bekliyor olacağım kolay gelsin.

  2. #2 by Zalım on 21 Mayıs 2010 - 00:41

    C# ‘ı severiz.. Ama yaşasın JAVA..
    Ayrıca PHP ye de tanımlayamadığım bir sempati besliyorum. Hadi hayırlısı..

(yayınlanmayacak)