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); // JohnAyrı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.
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:PluginSystemad alanı (namespace) içindePluginAttributeadında özel bir öznitelik oluşturun. Özniteliğiniz şunları yapmalıdır:Attributesınıfından miras almalı- İki salt okunur özelliğe sahip olmalı:
Name(string) veVersion(string) - Her iki değeri de yapıcısı (constructor) aracılığıyla kabul etmeli
Plugins.cs:PluginSystemad alanı içinde birkaç eklenti sınıfı oluşturun. BazılarıPluginAttributeile 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)
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ü
PluginAttributeiçin kontrol edin - Özniteliğin
NameveVersionö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); // JohnMetotları 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})
}
}
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
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları