Menu
Coddy logo textTech

Attributes ve Reflection

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 44 / 70.

Öznitelikler (Attributes); sınıflar, metotlar veya özellikler gibi kod öğelerine eklediğiniz meta veri etiketleridir. Kodun doğrudan nasıl yürütüldüğünü değiştirmezler, ancak çalışma zamanında okunabilen bilgiler sağlarlar. Yansıma (Reflection), bu meta verileri okuyan mekanizmadır.

Bir özniteliği (attribute), hedef öğenin üzerine köşeli parantez içine yerleştirerek uygularsınız:

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Serializable]
public class Person
{
    public string Name { get; set; }
}

Attribute sınıfından miras alarak özel öznitelikler oluşturabilirsiniz:

public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}

[Author("John")]
public class Calculator { }

Yansıma (Reflection), System.Reflection ad alanını kullanarak çalışma zamanında türleri incelemenize ve öznitelikleri okumanıza olanak tanır:

Type type = typeof(Calculator);
var attr = type.GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(attr.Name);  // John

Ayrıca metotları, özellikleri keşfedebilir ve bunları dinamik olarak çağırabilirsiniz:

MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
    Console.WriteLine(method.Name);

Öznitelikler ve yansıma birçok framework'e güç verir - serileştirme kütüphaneleri bunları JSON çıktısını kontrol etmek için kullanır, test framework'leri bunları test metotlarını keşfetmek için kullanır ve bağımlılık enjeksiyonu konteynerleri bunları servisleri otomatik olarak bağlamak için kullanır.

challenge icon

Görev

Kolay

Özel öznitelikleri (custom attributes) ve yansımayı (reflection) kullanarak eklenti olarak işaretlenmiş sınıfları otomatik olarak bulan ve tanımlayan bir eklenti keşif sistemi oluşturalım. Bu, gerçek çerçevelerin (frameworks) çalışma zamanında bileşenleri, test yöntemlerini veya API uç noktalarını nasıl keşfettiğine benzer.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • PluginAttribute.cs: PluginSystem ad alanı (namespace) içinde PluginAttribute adında özel bir öznitelik oluşturun. Özniteliğiniz şunları yapmalıdır:
    • Attribute sınıfından miras almalı
    • İki salt okunur özelliğe sahip olmalı: Name (string) ve Version (string)
    • Her iki değeri de yapıcısı (constructor) aracılığıyla kabul etmeli
  • Plugins.cs: PluginSystem ad alanı içinde birkaç eklenti sınıfı oluşturun. Bazıları PluginAttribute ile süslenmeli, biri ise süslenmemelidir:
    • ImageProcessor - [Plugin("Image Processor", "1.0")] ile işaretlenmiş
    • DataExporter - [Plugin("Data Exporter", "2.5")] ile işaretlenmiş
    • HelperUtility - herhangi bir öznitelik ile işaretlenmemiş (bu sadece normal bir sınıftır)
    Her sınıf boş olabilir - biz sadece yansıma yoluyla onların meta verilerini keşfetmekle ilgileniyoruz.
  • Program.cs: Ana dosyanızda, PluginAttribute özniteliğine sahip tüm sınıfları keşfetmek için yansımayı kullanın. Keşfedilen her eklenti için bilgilerini yazdırın. Şunları yapmanız gerekecek:
    • Mevcut derlemedeki (assembly) tüm türleri alın
    • Her türü PluginAttribute için kontrol edin
    • Özniteliğin Name ve Version özelliklerini ayıklayın ve görüntüleyin

Türleri incelemek ve özel öznitelikleri almak için System.Reflection kullanın. GetCustomAttribute<T>() yöntemi, öznitelik mevcut değilse null döndürür, böylece hangi sınıfların gerçek eklenti olduğunu filtrelemek için bunu kullanabilirsiniz.

Keşfedilen her eklentiyi her satıra bir tane gelecek şekilde şu formatta yazdırın:

Plugin: {Name} (v{Version})

Eklentiler şu sırayla yazdırılmalıdır: önce ImageProcessor, ardından DataExporter. HelperUtility sınıfı, özniteliğe sahip olmadığı için çıktıda görünmemelidir.

Beklenen çıktı:

Plugin: Image Processor (v1.0)
Plugin: Data Exporter (v2.5)

Bu zorluk, çerçevelerin öznitelikleri işaretleyici olarak nasıl kullandığını ve bunları keşfetmek için yansımayı nasıl kullandığını gösterir - aynı teknik bağımlılık enjeksiyonu (dependency injection) konteynerlerini, serileştirme kütüphanelerini ve test çerçevelerini güçlendirir!

Kopya kağıdı

Öznitelikler (Attributes), kod öğelerinin üzerine köşeli parantez içinde yerleştirilen meta veri etiketleridir. Çalışma zamanında okunabilen bilgiler sağlarlar:

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Serializable]
public class Person
{
    public string Name { get; set; }
}

Attribute sınıfından miras alarak özel öznitelikler oluşturun:

public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}

[Author("John")]
public class Calculator { }

Yansıma (Reflection), System.Reflection ad alanını kullanarak çalışma zamanında türleri incelemenize ve öznitelikleri okumanıza olanak tanır:

Type type = typeof(Calculator);
var attr = type.GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(attr.Name);  // John

Metotları ve özellikleri dinamik olarak keşfedin:

MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
    Console.WriteLine(method.Name);

GetCustomAttribute<T>() metodu, öznitelik mevcut değilse null döndürerek türleri öznitelik varlığına göre filtrelemenize olanak tanır.

Kendin dene

using System;
using System.Reflection;
using PluginSystem;

class Program
{
    public static void Main(string[] args)
    {
        // TODO: Mevcut derlemedeki (assembly) tüm türleri al
        // İpucu: Assembly.GetExecutingAssembly().GetTypes() kullanın
        
        // TODO: Her bir türü döngüye alın ve PluginAttribute'a sahip olup olmadığını kontrol edin
        // İpucu: type.GetCustomAttribute<PluginAttribute>() kullanın
        
        // TODO: Eğer öznitelik (attribute) varsa, eklenti bilgisini şu formatta yazdırın:
        // Plugin: {Name} (v{Version})
        
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler