Menguasai Atribut C#: Tingkatkan Kode dengan Metadata
Sebuah atribut adalah tag deklaratif yang digunakan untuk menyampaikan informasi ke runtime tentang perilaku berbagai elemen seperti kelas, metode, struktur, enumerasi, assembly, dll. dalam program Anda. Anda dapat menambahkan informasi deklaratif ke program dengan menggunakan atribut. Tag deklaratif digambarkan oleh kurung siku ([ ]) yang ditempatkan di atas elemen yang digunakan.
Atribut digunakan untuk menambahkan metadata, seperti instruksi compiler dan informasi lainnya seperti komentar, deskripsi, metode dan kelas ke program. Kerangka .Net menyediakan dua jenis atribut: atribut yang telah ditentukan dan atribut yang dibuat khusus.
Menentukan Atribut
Sintaks untuk menentukan atribut adalah sebagai berikut:
[attribute(positional_parameters, name_parameter = value, ...)] element
Nama atribut dan nilainya ditentukan dalam kurung siku, sebelum elemen yang diterapkan atributnya. Parameter posisi menentukan informasi penting dan parameter nama menentukan informasi opsional.
Atribut yang Telah Ditentukan
Kerangka .Net menyediakan tiga atribut yang telah ditentukan:
- AttributeUsage
- Conditional
- Obsolete
AttributeUsage
Atribut yang telah ditentukan AttributeUsage menggambarkan bagaimana kelas atribut khusus dapat digunakan. Ini menentukan jenis item yang dapat diterapkan atribut tersebut.
Sintaks untuk menentukan atribut ini adalah sebagai berikut:
[AttributeUsage ( validon, AllowMultiple = allowmultiple, Inherited = inherited )]
Dimana:
Parameter validon menentukan elemen bahasa di mana atribut dapat ditempatkan. Ini adalah kombinasi dari nilai enumerator AttributeTargets. Nilai default adalah AttributeTargets.All.
Parameter allowmultiple (opsional) memberikan nilai untuk properti AllowMultiple dari atribut ini, nilai Boolean. Jika ini true, atribut dapat digunakan berkali-kali. Nilai default adalah false (single-use).
Parameter inherited (opsional) memberikan nilai untuk properti Inherited dari atribut ini, nilai Boolean. Jika true, atribut diwarisi oleh kelas turunan. Nilai default adalah false (tidak diwarisi).
Contohnya:
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
Conditional
Atribut yang telah ditentukan ini menandai metode kondisional yang eksekusinya tergantung pada pengidentifikasi preprocessing yang ditentukan.
Ini menyebabkan kompilasi bersyarat dari panggilan metode, tergantung pada nilai yang ditentukan seperti Debug atau Trace. Contohnya, menampilkan nilai variabel saat men-debug kode.
Sintaks untuk menentukan atribut ini adalah sebagai berikut:
[Conditional( conditionalSymbol )]
Contohnya:
[Conditional("DEBUG")] Contoh berikut menunjukkan atribut ini:
Live Demo
#define DEBUG using System; using System.Diagnostics; public class Myclass { [Conditional("DEBUG")] public static void Message(string msg) { Console.WriteLine(msg); } } class Test { static void function1() { Myclass.Message("In Function 1."); function2(); } static void function2() { Myclass.Message("In Function 2."); } public static void Main() { Myclass.Message("In Main function."); function1(); Console.ReadKey(); } } Ketika kode di atas dikompilasi dan dieksekusi, hasilnya adalah:
In Main function In Function 1 In Function 2
Obsolete
Atribut yang telah ditentukan ini menandai entitas program yang tidak boleh digunakan. Ini memungkinkan Anda untuk memberi tahu compiler untuk membuang elemen target tertentu. Contohnya, ketika metode baru digunakan dalam kelas dan jika Anda masih ingin mempertahankan metode lama dalam kelas, Anda dapat menandainya sebagai usang dengan menampilkan pesan bahwa metode baru harus digunakan, bukan metode lama.
Sintaks untuk menentukan atribut ini adalah sebagai berikut:
[Obsolete ( message )] [Obsolete ( message, iserror )]
Dimana:
Parameter message, adalah string yang menggambarkan alasan mengapa item tersebut usang dan apa yang harus digunakan sebagai gantinya.
Parameter iserror, adalah nilai Boolean. Jika nilainya true, compiler harus memperlakukan penggunaan item sebagai kesalahan. Nilai default adalah false (compiler menghasilkan peringatan).
Program berikut menunjukkan hal ini:
using System; public class MyClass { [Obsolete("Don't use OldMethod, use NewMethod instead", true)] static void OldMethod() { Console.WriteLine("It is the old method"); } static void NewMethod() { Console.WriteLine("It is the new method"); } public static void Main() { OldMethod(); } } Saat Anda mencoba mengkompilasi program, compiler memberikan pesan kesalahan yang menyatakan:
Don't use OldMethod, use NewMethod instead
Membuat Atribut Khusus
Kerangka .Net memungkinkan pembuatan atribut khusus yang dapat digunakan untuk menyimpan informasi deklaratif dan dapat diambil pada waktu eksekusi. Informasi ini dapat terkait dengan elemen target apa saja tergantung pada kriteria desain dan kebutuhan aplikasi.
Membuat dan menggunakan atribut khusus melibatkan empat langkah:
- Mendeklarasikan atribut khusus
- Membangun atribut khusus
- Menerapkan atribut khusus pada elemen program target
- Mengakses Atribut Melalui Refleksi
Langkah terakhir melibatkan penulisan program sederhana untuk membaca melalui metadata untuk menemukan berbagai notasi. Metadata adalah data tentang data atau informasi yang digunakan untuk menggambarkan data lain. Program ini harus menggunakan refleksi untuk mengakses atribut pada waktu eksekusi. Kita akan membahas ini di bab berikutnya.
Mendeklarasikan Atribut Khusus
Sebuah atribut khusus baru diturunkan dari kelas System.Attribute. Contohnya:
//a custom attribute BugFix to be assigned to a class and its members [AttributeUsage( AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute
Dalam kode sebelumnya, kami telah mendeklarasikan atribut khusus bernama DeBugInfo.
Membangun Atribut Khusus
Mari kita buat atribut khusus bernama DeBugInfo, yang menyimpan informasi yang diperoleh dengan men-debug program apa pun. Biarkan menyimpan informasi berikut:
- Nomor kode untuk bug
- Nama pengembang yang mengidentifikasi bug
- Tinjauan terakhir dari kode
- Pesan string untuk menyimpan catatan pengembang
Kelas DeBugInfo memiliki tiga properti private untuk menyimpan tiga informasi pertama dan satu properti publik untuk menyimpan pesan. Oleh karena itu, nomor bug, nama pengembang, dan tanggal tinjauan adalah parameter posisi dari kelas DeBugInfo dan pesan adalah parameter opsional atau bernama.
Setiap atribut harus memiliki setidaknya satu konstruktor. Parameter posisi harus dilewatkan melalui konstruktor. Kode berikut menunjukkan kelas DeBugInfo:
//a custom attribute BugFix to be assigned to a class and its members [AttributeUsage( AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute { private int bugNo; private string developer; private string lastReview; public string message; public DeBugInfo(int bg, string dev, string d) { this.bugNo = bg; this.developer = dev; this.lastReview = d; } public int BugNo { get { return bugNo; } } public string Developer { get { return developer; } } public string LastReview { get { return lastReview; } } public string Message { get { return message; } set { message = value; } } } Menerapkan Atribut Khusus
Atribut diterapkan dengan menempatkannya segera sebelum targetnya:
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")] [DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")] class Rectangle { //member variables protected double length; protected double width; public Rectangle(double l, double w) { length = l; width = w; } [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")] public double GetArea() { return length * width; } [DeBugInfo(56, "Zara Ali", "19/10/2012")] public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea()); } } Di bab berikutnya, kami mengambil informasi atribut menggunakan objek kelas Refleksi.