Anonymous Types (Anonim/İsimsiz Tipler)

C# 3.0 ile gelen bir özellik olan anonim tipler adından da anlaşılacağı üzere bir değişkenin (objenin) tipini tanımlamadan objeler oluşturmamızı sağlayan bir yapıdır.

var” ifadesi ile tip adı belirtilmeden oluşturulan objeler compiler tarafından anonim tipte oluşturulmaktadır.
Örneğin

string MyString = “Merhaba”;

Yukarıdaki kod parçacığına bakıldığında sağ taraftaki ifadenin (string) olduğu ortadadır. Peki böyle bir tanımlamayı bizim yerimize compiler nasıl yapmaktadır?

var MyString = “Merhaba”;

“var” ifadesi ile değişkenimizi tanımlayıp yine string ifademizi değişkenimize atadığımızda, derleme zamanında “var” ifadesi yerine değişkene atanan verinin tipinin türü değişkene verilmektedir. Burada unutmamak gerekir ki C# halen type safety’dir. Yani aşağıdaki gibi bir işlem yapamazsınız.

var MyString2 = “Merhaba”;
MyString2 = 123; // Burada zekice bir deneme yapıyoruz,
// sonrasında compiler haşağıdaki gibi bir hata veriyor.
// String türünde oluşturulan nesneye int türünden değer atanamaz.
// "Error Cannot implicitly convert type 'int' to 'string'"


Anonim tiplerin integer, string gibi basit türler (types) için yukarıdaki gibi küçük faydalarının olmasının yanı sıra, daha karmaşık olarak tanımlayacağımız tipler üzerindede zeki davranışlar sergilemektedir.

int Age = 27;
var user1 = new { Name = "Bora", Age, Age.ToString().Length };

Örneğin yukarıdaki kod satırı ile aşağıdaki kod satırı tamamen aynıdır.

var user2= new { Name = "Bora", Age = Age, Length = Age.ToString().Length };

Bu yukarıdaki kodları derleyip disassemble edip compiler’ın user1 ve user2 için birebir aynı tipi kullandığını gözlemleyebiliriz. Aşağıda dissemble edilmiş halini incelediğimizde sadece tek bir anonip tip olduğunu görüyoruz. Compiler’ın burada zeki bir davranış sergilediğinide doğrulamış oluyoruz.

Disassemble

Aşağıdaki şekilde daha karmaşık bir tanım yaptığımızda da compiler burada tek tip obje kullanıldığını anlamakta ve tip çözümleme işlemini buna göre yapmaktadır.

var anonArray = new[] { new { SicilNo = 478, Personel = "Ahmet", Departman = "Üretim" },
                        new { SicilNo = 538, Personel = "Sibel", Departman = "Satış" }};

Yukarıda bahsettiğim üzere aynı yapıda tanımlanan anonim tipler çözümleme sırasında aynı türü kullanmaktadır bunu test edecek olursak. Aşağıda oluşturduğumuz a1 ve a2 değişkenlerinin aynı tipte olduklarını doğrulamak istediğimizde :

var a1 = new { X = 2, Y = 4 };
var a2 = new { X = 2, Y = 4 };
Console.WriteLine (a1.GetType() == a2.GetType());   // True

hatta buna ek olarak eşitlik kontrolü yapabileceğimiz Equals metodu anonim tipler için implement edilmiştir.

Console.WriteLine (a1 == a2);         // False
Console.WriteLine (a1.Equals (a2));   // True

Anonim tipler ile compile zamanı oluşan sınıflar internal’dır, yani tipin o an çalıştığı assembly dışarısından erişilemezler.

var anonymousObject =  new { SicilNo = 478, Personel = "Ahmet", Departman = "Üretim" };

Peki yukarıda oluşturduğumuz anonim tipteki bir objeyi parametre (argument) olarak bir metoda geçmek istersek ve özelliiklerindeki (property) değerleri kullanmak istesek?

public static void DoSomeThing(var anonymousObject)
{
//bir takım işlemler
}
// Yukarıdaki gibi bir kullanım aşağıdaki compile error'a sebep olacaktır.
//Error	1 The contextual keyword 'var' may only appear within a local variable declaration

Gerçekten böyle bir ihtiyaç olur ise aşağıdaki gibi Reflection kullanılarak gerekli özelliklere (property’lere) erişilip değerleri kullanılabir.

public static void DoSomeThing(object anonymousObject)
{
    Type t = anonymousObject.GetType();
    PropertyInfo[] pi = t.GetProperties();

    foreach (PropertyInfo p in pi)
    {
        Console.WriteLine(p.Name + " : " + p.GetValue(anonymousObject, null));
    }
}

Kaynak;

Anonymous Types (C# Programming Guide)

Martijn’s C# Programming Blog

0 thoughts on “Anonymous Types (Anonim/İsimsiz Tipler)”

Bir cevap yazın