.NET'te öznitelikler nelerdir?


Yanıtlar:


146

Meta veri. Nesneleriniz / yöntemleriniz / özellikleriniz hakkındaki veriler.

Örneğin, kullanıcı arabiriminde hangi sipariş özelliklerinin görünmesi gerektiğini kolayca kontrol edebilmem için: DisplayOrder adlı bir Nitelik bildirebilirim. Sonra bir sınıfa eklemek ve öznitelikleri ayıklamak ve UI öğeleri uygun şekilde sipariş bazı GUI bileşenleri yazmak olabilir.

public class DisplayWrapper
{
    private UnderlyingClass underlyingObject;

    public DisplayWrapper(UnderlyingClass u)
    {
        underlyingObject = u;
    }

    [DisplayOrder(1)]
    public int SomeInt
    {
        get
        {
            return underlyingObject .SomeInt;
        }
    }

    [DisplayOrder(2)]
    public DateTime SomeDate
    {
        get
        {
            return underlyingObject .SomeDate;
        }
    }
}

Böylece, özel GUI bileşenlerimle çalışırken SomeInt'ın SomeDate'ten önce her zaman görüntülenmesini sağlar.

Ancak, bunların doğrudan kodlama ortamının dışında en yaygın şekilde kullanıldığını göreceksiniz. Örneğin, Windows Tasarımcısı bunları yoğun bir şekilde kullanır, bu nedenle özel yapım nesnelerle nasıl başa çıkılacağını bilir. BrowsableAttribute'ı şu şekilde kullanma:

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

Tasarımcıya bunu örneğin tasarım zamanında Özellikler penceresindeki kullanılabilir özelliklerde listelememesini söyler.

Sen olabilir ayrıca Reflection.Emit olarak veya çalışma zamanı işlemleri (örneğin Sonrası Sharp gibi) önceden derleme işlemleri, kod-nesil için bunları kullanın. Örneğin, profilleme için, kodunuzun yaptığı her çağrıyı şeffaf bir şekilde saran ve kodlama yapan bir miktar kod yazabilirsiniz. Belirli yöntemlere yerleştirdiğiniz bir özellik aracılığıyla zamanlamanın "kapsamı dışında kalmayı" seçebilirsiniz.

public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
    bool time = true;
    foreach (Attribute a in target.GetCustomAttributes())
    {
        if (a.GetType() is NoTimingAttribute)
        {
            time = false;
            break;
        }
    }
    if (time)
    {
        StopWatch stopWatch = new StopWatch();
        stopWatch.Start();
        targetMethod.Invoke(target, args);
        stopWatch.Stop();
        HandleTimingOutput(targetMethod, stopWatch.Duration);
    }
    else
    {
        targetMethod.Invoke(target, args);
    }
}

Onları bildirmek kolaydır, sadece Nitelik'ten miras alan bir sınıf yapın.

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

Ve özniteliği kullandığınızda "öznitelik" sonekini atlayabileceğinizi unutmayın, derleyici bunu sizin için ekleyecektir.

NOT: Öznitelikler kendi başlarına hiçbir şey yapmazlar - bunları kullanan başka bir kod olması gerekir. Bazen bu kod sizin için yazılmıştır, ancak bazen kendiniz yazmanız gerekir. Örneğin, C # derleyicisi bazı ve belirli çerçeve çerçevelerinin bazılarını kullanır (örn. NUnit bir sınıfta [TestFixture] ve bir montajı yüklerken bir test yönteminde [Test] arar).
Dolayısıyla, kendi özel özniteliğinizi oluştururken kodunuzun davranışını hiç etkilemeyeceğini unutmayın. Nitelikleri kontrol eden (yansımayla) diğer kısmı yazmanız ve bunlara göre hareket etmeniz gerekir.


32
Değer için, bu tüm (yerleşik) .NET özniteliklerinin bir listesidir: msdn.microsoft.com/en-us/library/aa311259(VS.71).aspx
wprl

1
"SomeProfilingMethod" öğenizi öznitelik olarak nasıl kullanırsınız?
RayLoveless

@RayLoveless bir özniteliği değil, SomeProfilingMethod profil oluşturma özniteliklerini arayan enstrümantasyon kodudur. Özellikle örnekte ben bir "opt-in" biri yerine "opt-out" özniteliği (NoTimingAttribute) aramaya verdi. Fikir, her şeyi zamanlamasıdır.
16:48

@Quibblesome, "Nitelikler kendi başlarına hiçbir şey yapmazlar - bunları kullanmak için başka bir kod olması gerekir (derleyici çiftle ilgilenir, farklı çerçeveler biraz kullanır). öznitelikleri (yansıma yoluyla) kontrol eden ve bunlara göre hareket eden diğer kısmı yazmanız gerekir ". (ya da iyiysen bunu yapabilirim). Birçok kişi, özelliklerin sihirli bir şekilde çalışmasını bekler ve buradaki cevapların hiçbiri bunu açıklığa kavuşturmaz. (veya bunu kapsayan stackoverflow.com/questions/4879521/… adresine bağlantı verin )
Alexei Levenkov

yalnızca Bing'i kullanmayı bırakırsanız. Hayır. j / k Ben esas olarak Bing iirc kullanan birincil olarak DuckDuckGo kullanın. :)
26'da Quibblesome

36

Birçok insan cevap verdi ama şimdiye kadar kimse bundan bahsetmedi ...

Nitelikler yoğun bir şekilde yansıma ile kullanılır. Yansıma zaten oldukça yavaş.

Çalışma zamanı performansını artırmak için özel niteliklerinizi sınıf olarak işaretlemek çok faydalıdırsealed .

Böyle bir niteliğin nerede kullanılmasının uygun olacağını düşünmek ve bunu () ile belirtmek için özelliğinizi (!) İlişkilendirmek de iyi bir fikirdir AttributeUsage. Kullanılabilir özellik kullanımlarının listesi sizi şaşırtabilir:

  • montaj
  • modül
  • Sınıf
  • struct
  • Sıralama
  • inşaatçı
  • Yöntem
  • Emlak
  • Alan
  • Etkinlik
  • Arayüz
  • Parametre
  • Temsilci
  • Geri dönüş değeri
  • GenericParameter
  • Herşey

AttributeUsage özniteliğinin AttributeUsage özniteliğinin imzasının bir parçası olması da iyidir. Dairesel bağımlılıklar için whoa!

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute

13

Nitelikler sınıfları etiketlemek için kullanılan bir tür meta veridir. Bu, WinForms'da örneğin denetimleri araç çubuğundan gizlemek için kullanılır, ancak farklı sınıfların örneklerinin belirli şekillerde davranmasını sağlamak için kendi uygulamanızda uygulanabilir.

Bir özellik oluşturarak başlayın:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
    public int SortOrder { get; set; }

    public SortOrderAttribute(int sortOrder)
    {
        this.SortOrder = sortOrder;
    }
}

Tüm öznitelik sınıflarının geçerli olması için "Öznitelik" sonekine sahip olması gerekir.
Bu yapıldıktan sonra, özniteliği kullanan bir sınıf oluşturun.

[SortOrder(23)]
public class MyClass
{
    public MyClass()
    {
    }
}

Şimdi SortOrderAttributeaşağıdakileri yaparak belirli bir sınıfı kontrol edebilirsiniz ' (eğer varsa):

public class MyInvestigatorClass
{
    public void InvestigateTheAttribute()
    {
        // Get the type object for the class that is using
        // the attribute.
        Type type = typeof(MyClass);

        // Get all custom attributes for the type.
        object[] attributes = type.GetCustomAttributes(
            typeof(SortOrderAttribute), true);

        // Now let's make sure that we got at least one attribute.
        if (attributes != null && attributes.Length > 0)
        {
            // Get the first attribute in the list of custom attributes
            // that is of the type "SortOrderAttribute". This should only
            // be one since we said "AllowMultiple=false".
            SortOrderAttribute attribute = 
                attributes[0] as SortOrderAttribute;

            // Now we can get the sort order for the class "MyClass".
            int sortOrder = attribute.SortOrder;
        }
    }
}

Bu konuda daha fazla okumak isterseniz, her zaman oldukça iyi bir açıklamaya sahip olan MSDN'ye göz atabilirsiniz .
Umarım bu sana yardımcı olmuştur!


5

Öznitelik, kodunuzdaki nesnelere uygulayabileceğiniz bazı işlevler içeren bir sınıftır. Bir tane oluşturmak için, System.Attribute öğesinden devralan bir sınıf oluşturun.

Ne için iyi olduklarına gelince ... onlar için neredeyse sınırsız kullanım var.

http://www.codeproject.com/KB/cs/dotnetattributes.aspx


1
"işlevsellik" burada yanlış kelime; bunlar meta veri, işlevsellik değil
Marc Gravell

5

Nitelikler, sınıflara, yöntemlere veya derlemelere uygulanan meta veriler gibidir.

Çok sayıda şey için iyidirler (hata ayıklayıcı görselleştirme, şeyleri eski olarak işaretleme, şeyleri serileştirilebilir olarak işaretleme, liste sonsuzdur).

Kendi özel olanlarınızı oluşturmak pasta gibi kolaydır. Buradan başlayın:

http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx


5

Şu anda üzerinde çalıştığım projede, çeşitli tatlardan oluşan bir dizi UI nesnesi ve DevStudio'daki form tasarımcısı gibi ana uygulamada kullanılmak üzere sayfalar oluşturmak için bu nesneleri birleştirmek için bir düzenleyici var. Bu nesneler kendi derlemelerinde bulunur ve her nesne UserControlözel bir öznitelikten türetilmiş bir sınıftır . Bu özellik şu şekilde tanımlanır:

[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
  ControlDescriptionAttribute (String ^name, String ^description) :
    _name (name),
    _description (description)
  {
  }

  property String ^Name
  {
    String ^get () { return _name; }
  }

  property String ^Description
  {
    String ^get () { return _description; }
  }

private:
  String
    ^ _name,
    ^ _description;
};

ve ben böyle bir sınıfa uyguluyorum:

[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
  // stuff
};

önceki posterlerin söylediği şey bu.

Özniteliği kullanmak için düzenleyicide Generic::List <Type>kontrol türlerini içeren bir öğe bulunur. Kullanıcının denetimin bir örneğini oluşturmak için sayfaya sürükleyip bırakabileceği bir liste kutusu vardır. Liste kutusunu ControlDescriptionAttributedoldurmak için, denetim için olsun ve listede bir girişi doldurun:

// done for each control type
array <Object ^>
  // get all the custom attributes
  ^attributes = controltype->GetCustomAttributes (true);

Type
  // this is the one we're interested in
  ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;

// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
  if (attributetype->IsInstanceOfType (attribute))
  {
    ECMMainPageDisplay::ControlDescriptionAttribute
      ^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);

    // get the name and description and create an entry in the list
    ListViewItem
      ^item = gcnew ListViewItem (description->Name);

    item->Tag = controltype->Name;
    item->SubItems->Add (description->Description);

    mcontrols->Items->Add (item);
    break;
  }
}

Not: yukarıdaki C ++ / CLI ama C # 'e dönüştürmek zor değil (evet, biliyorum, C ++ / CLI bir iğrenç ama bununla çalışmak zorundayım :-()

Nitelikleri çoğu şeye koyabilirsiniz ve önceden tanımlanmış tüm özellikler vardır. Yukarıda belirtilen editör ayrıca özelliği ve mülkün nasıl düzenleneceğini açıklayan özelliklerde özel özellikler arar.

Tüm fikri anladıktan sonra, onlarsız nasıl yaşadığınızı merak edeceksiniz.


4

Söylendiği gibi, Nitelikler oluşturmak nispeten kolaydır. İşin diğer kısmı, onu kullanan kod oluşturmaktır. Çoğu durumda, bir özniteliğin veya özelliklerinin varlığına bağlı olarak davranışı değiştirmek için çalışma zamanında yansımayı kullanırsınız. Ayrıca, bir tür statik analiz yapmak için derlenmiş koddaki öznitelikleri inceleyeceğiniz senaryolar da vardır. Örneğin, parametreler null olmayan olarak işaretlenebilir ve analiz aracı bunu bir ipucu olarak kullanabilir.

Öznitelikleri kullanmak ve kullanımları için uygun senaryoları bilmek işin büyük kısmıdır.


3

Nitelikler, temel olarak, türlerinize eklemek istediğiniz veri parçalarıdır (sınıflar, yöntemler, etkinlikler, numaralandırmalar, vb.)

Fikir, çalışma zamanında başka bir tür / çerçeve / aracın öznitelikteki bilgiler için türünüzü sorgulayacağı ve buna göre hareket edeceği yönündedir .

Bu nedenle, örneğin, Visual Studio tasarım zamanında Özellikler bölmesinde denetimin hangi özelliklerinin görünmesi gerektiğini anlamak için 3. taraf denetimindeki öznitelikleri sorgulayabilir.

Nitelikler, Unsur Odaklı Programlama'da, nesneleri süsleyen niteliklere dayalı olarak çalışma zamanında nesneleri enjekte etmek / değiştirmek ve nesnenin iş mantığını etkilemeden nesnelere doğrulama, günlük kaydı vb. Eklemek için de kullanılabilir.



2

Bir öznitelik oluşturmaya başlamak için bir C # kaynak dosyası açın attributeve [SEKME] tuşuna basın. Yeni bir özellik için bir şablona genişleyecektir.


6
Bu soruya nasıl cevap veriyor? bu bir yorum olmalı, cevap değil.
gdoron Monica'yı

1

Nitelikler, Unsur Odaklı Programlama için yaygın olarak kullanılır. Bunun bir örneği için PostSharp projesine göz atın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.