Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C# 10 – CallerArgumentExpression Attribute’u

Merhaba,

Bu içeriğimizde, C#’ın gelişim yolunda geçmişteki tartışmaları nihayete erdiren ve C# 8.0’da duyurulup, ertelenen, C# 9.0’da beklenirken sonunda C# 10 ile gelen CallerArgumentExpression attribute’u üzerine incelemede bulunuyor olacağız.

Caller? Attribute’u Tanıdık mı Geliyor?

Evet, C# 5’ten bu yana .NET’te kullanılan ve adı Caller ile başlayan üç adet attribute mevcuttur. Bunlar; System.Runtime.CompilerServices namespace’i altındaki CallerMemberName, CallerFilePath ve CallerLineNumber attribute’larıdır. Bu attribute’lar metot parametrelerinde kullanılarak, özelliklerine göre ilgili metodun nereden, hangi metot tarafından çağrıldığı, dosya yolu ve koddaki satır numarası bilgilerini döndüren sihirli niteliklerdir.

    public static class LogService
    {
        public static void Log(string logMessage,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string filePath = "",
            [CallerLineNumber] int lineNumber = 0)
        {
            //...
            Console.WriteLine(memberName);
            Console.WriteLine(filePath);
            Console.WriteLine(lineNumber);
        }
    }

Yukarıda görüldüğü üzere Caller attribute’larının hedeflenen metoda dair bilgiler edinebilmeleri için işaretledikleri parametrelerin opsiyonel olmaları gerekmektedir. Yani ilgili parametrelere default değerlerin atanmış olması gerekiyor. Haliyle ilgili metodun tetiklendiği noktada bu opsiyonel parametrelere herhangi bir değer iletmeksizin mahiyetlerine uygun verilerle doldurulduklarını göreceksiniz. Misal olarak;

using services;

class Program
{
    public static void Main()
    {
        LogService.Log("Merhaba");
    }
}

Yukarıdaki kod bloğunu derleyip, çalıştırdığımız zaman aşağıdaki gibi çıktı verecektir.
C# 10 - CallerArgumentExpression Attribute'uEn nihayetinde compiler’ın, derleme sürecinde bu metodu aşağıdaki misali tekrar inşa ettiğini söyleyebilmekteyiz.

using services;

class Program
{
    public static void Main()
    {
        LogService.Log("Merhaba",
            "Main",
            @"C:\Users\Gencay\source\repos\functions\functions\Program.cs",
            7);
    }
}

Bu attribute’lara dair daha teferruatlı bilgi için yıllar önce klavyeye aldığımız ve yukarıdaki paragraflarda referans ettiğimiz C# 5.0 Caller Information başlıklı makaleye(her ne kadar eski olsa da hala güncelliğini korumaktadır) sizleri buyur ediyorum…

Şimdi bizler günün astolistine odaklanacak ve C# 10 ile Caller attribute’ları arasına katılan CallerArgumentExpression niteliğini incelemeye başlayacağız…

CallerArgumentExpression Attribute’u Nedir?

CallerArgumentExpression, C# 10 ile gelen ve bir metodun herhangi bir parametresinin değerini metinsel olarak yakalayabilmemizi sağlayan attribute’dur. Evet, bu açıklamanın pek aydınlatıcı olmadığını biliyorum. En doğrusu ilgili attribute’u basit bir örnek üzerinde kullanarak incelemekte fayda var.

    public static class Data
    {
        public static void Control(bool value,
            [CallerArgumentExpression("value")] string expression = "")
        {
            Console.WriteLine($"value : {value} \t| expression : {expression}");
        }
    }

Yukarıda görüldüğü üzere diğer Caller* attribute’larında olduğu gibi CallerArgumentExpression‘da yine opsiyonel bir parametreye uygulanmaktadır. Burada ilgili attribute belirtilen değere karşılık gelen parametrenin(value) değerini metinsel olarak alır ve ‘expression’ parametresine atar. Dolayısıyla;

        Data.Control(3 > 5);
        Data.Control(true || ((true && false) || false && true));

şeklinde kullanım durumlarında buradaki condition ifadelerinin metinsel olarak aşağıdaki gibi elde edilmesini sağlamaktadır.
C# 10 - CallerArgumentExpression Attribute'uİşte bu davranış, compiler tarafından hedef parametreye verilen ifadenin kendisi(gerçek ifadenin kendisi, ifadenin sonucu değil!) metinsel değere dönüştürülerek CallerArgumentExpression uygulanan parametreye iletilmesi sonucunda ortaya çıkmaktadır.

Burada, ifadesi yakalanmak istenen parametrenin adını CallerArgumentExpression attribute’una vermek mecburiyetinde olduğumuz aşikar. Burada ne yazık ki, parametre adlarına attribute kapsamından erişemediğimizden dolayı nameof keyword’ünü kullanamamaktayız. Üzgünüm ama bu durumda kod geliştiricinin metinsel değer yazabilme becerisini konuşturması gerekmektedir 🙂

Artık C# 10 ile hayatımıza giren bu attribute sayesinde uygulamaların loglama yahut doğrulama gibi operasyon süreçlerinde daha zengin işlemler gerçekleştirilebileceği kanaatindeyim… Hayırlı olsun 🙂

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.