Published on

C# Attribute Nedir ? Nasıl Kullanılır ?

Authors
  • avatar
    Name
    Alperen Önal
    Twitter

C# Attribute Nedir ?

attribute-metadata-c#

Bizlere Run Time’da metot,property,class,field vs. hakkında bilgi vermesi amaçlı kullanılır.(Etiket benzetmesi yapabiliriz.)

En yaygın olarak ; yazdığımız kodlara ‘run time’da bir işlev vermek veya derleme öncesi verdiğimiz işlevi değiştirmek için kullanılmaktadır.

Yukarıdaki resimde de göründüğü gibi kodlarımıza karşılık gelen assembly’nin içerisinde Attribute ile etiketlediğimiz yapılara(metot,property,class vs.) ekstra anlam katarız.

Bu etiketlediğimiz yapıları run time’da Reflection yardımıyla değerlendirebiliriz.

Değerlendirmekten kastın ne ? Neden değerlendiriyoruz diye soracak olursanız. Yanıt vereyim , şöyleki bir kod bloğumuz var ve ben bu kod bloğunun run time’da işlevini değiştirdim veya bir işlev kazandırdım işte tam olarak aksiyona değerlendirme diyoruz.

Mesela ileride entity framework göreceğiz bir kod satırının veri tabanı kısmında primary key olarak görünmesini istiyorsam o kod satının hemen üstüne [KEY] attribute’sini koyarım çünkü run ‘time’da yazdığım kodlar veritabanına entegre edilirken o kodun primary key olacağını hedef veritabanına söylerim.

Alttaki örnekler işin mantığını anlamak için verilmiş klasik örneklerdir.Attributeler bu örneklerden ibaret değildir.Bu konudan sonra yapışık konu olan reflection’a geçerek mantığını tam olarak kavrayabilirsin.

Kendi Attribute’mizi tanımlamak için Attribute sınıfından kalıtım almalıyız.


class MyAttribute : Attribute
{

}

Belirlediğimiz yapıların hemen üstüne ‘[ilgili-attribute-ismi]’ yazılarak uygulanır.

Aşağıda da göründüğü gibi [My] ile [MyAttribute] arasında fark yoktur ikisi de aynı şeyi uygular yani MyAttribute’yi [My] olarak kullansak da değişen bir şey olmayacaktır.


[My]
class Test
{
    [My]
    public int number;

    [MyAttribute]
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

Şimdi gelelim anlamdırmaya.Anlamdırmak için yarattığım MyAttribute sınıfımda authorName ve version isminde iki adet field oluşturuyorum.

class MyAttribute : Attribute
{
    public string Authorname;
    public string version;





}

Artık metadata’ya bu ifadeler ile ilgili ekstra bilgiler eklemiş olduk. Ardından istediğim ifadelere(Test class’ı,name field’ı ve goster metot’una) uyguluyorum.

[My(Authorname ="Alperen", version = "1.1")]
class Test
{
    [My(Authorname ="Alperen", version ="1.1")]
    int number;


    [My(Authorname = "Alperen", version = "1.1")]
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

Peki Yarattığım MyAttribute Class’ının Sadece Benim Önceden Belirlediğim İfadelere Eklenebileceğini Belirtmek İstiyorsam ?

Bunun için AttributeUsage Class’ını kullanıyoruz.MyAttribute Class’ın hemen üstüne [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field)] ekliyorum.Bu , MyAttribute’nin sadece class ve field ifadelerine uygulanabileceği anlamını taşıyor. Eğer bunu tanımlamazsak az önceki örnekte de göründüğü gibi default olarak tüm ifadelere açık hale gelecektir.Şimdi Örneğe geçelim.


[AttributeUsage(AttributeTargets.Class|AttributeTargets.Field)]
class MyAttribute : Attribute
{
    public string Authorname;
    public string version;





}
[My(Authorname ="Alperen", version = "1.1")] //burada sıkıntı yok.
class Test
{
    [My(Authorname ="Alperen", version ="1.1")] //Burada sıkıntı yok.
    int number;
    [My(Authorname = "Alperen", version = "1.1")] //hata verecektir.
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

Olarak kullanılacaktır.[AttibuteUsage(AttributeTargets.Class|AttributeTargets.Field)] yapısında iki target’i ayırmak için ‘,’ değil ‘|’ kullanıyoruz unutmayalım.

MyAttribute’yi bir ifadeye birden fazla kez uygulamak için : ” [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field,AllowMultiple =true)] ” bu koddaki AllowMultiple’yi true şeklinde yazarak , 1’den fazla kullanmaya izin vermeliyiz.

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Field,AllowMultiple =true)]
class MyAttribute : Attribute
{
    public string Authorname;
    public string version;





}
[My(Authorname ="Alperen", version = "1.1")]
class Test
{
    [My(Authorname ="Alperen", version ="1.1")]
    [My(Authorname = "Mehmet", version = "1.2")] //AllowMultiple true olmasaydı buradan hata alacaktık.
    int number;

    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

Hazır Attribute’ler :

1-) [Obsolete] : Artık kullanılmayan üyeleri etiketlemek ve kullanmaya çalışan kişiye mesaj ulaştırmak için kullanılır.

class Program
{
    static void Main()
    {

      Test test = new Test();
        Test.Goster(); //çalışacak ama mesaj gösterecektir

    }

}

class Test
{
    int number;

    [Obsolete("Bunu kullanamazsın")]
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

Artık bu metot’un kullanılmadığını ve bizim mesajımızı ilgili kişiye gösteriyor.

Eğer etiketlediğimiz üyenin kullanılmasını istemiyorsak , [Obsolete(“Bunu kullanamazsın”,true)]’yi kullanmalıyız.Bu şekilde error vermesini onayladık.

class Program
{
    static void Main()
    {

      Test test = new Test();
        Test.Goster(); //artık burasının altı çizik ve çalışmıyor hata alıyoruz.

    }

}

class Test
{
    int number;

    [Obsolete("Bunu kullanamazsın",true)]
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }




}

2-) [Conditional] : İçerisinde string bir ifade tanımlanır ve eğer bu içerisindeki string ifade #define ile tanımlanmış ise [Conditional] ile etiketlenmiş ifade çalışacaktır tanımlanmamış ise çalışmayacaktır.Yani ilgili ifadenin çalışması bir şarta bağlanmıştır.Not : eğer bu etiketi kullanacaksak “using System.Diagnostics;”i dahil etmeliyiz.

#define A
using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {

      Test test = new Test();
        Test.Goster(); //Çalışacak
        Test.BaskaGoster(); //Çalışmayacak ve Hata vermeyecek.
    }

}

class Test
{
    int number;


    [Conditional("A")]
    public static void Goster()
    {

        Console.WriteLine("Gosterdim");

    }

    [Conditional("B")]
    public static void BaskaGoster()
    {

        Console.WriteLine("Başka Gosterdim");

    }


}

Attribute’ler konumuz bitmiştir.Okuduğunuz için teşekkürler.