Yinelenen izin verilen öznitelikler nasıl oluşturulur?


96

Bir öznitelik sınıfından miras alınan özel bir öznitelik kullanıyorum. Bunu şu şekilde kullanıyorum:

[MyCustomAttribute("CONTROL")]
[MyCustomAttribute("ALT")]
[MyCustomAttribute("SHIFT")]
[MyCustomAttribute("D")]
public void setColor()
{

}

Ancak "Yinelenen" MyCustomAttribute "özniteliği" hatası gösteriliyor.
Yinelenen izin verilen bir özniteliği nasıl oluşturabilirim?

Yanıtlar:


185

Bir sopa AttributeUsagesenin Özellik (lokma evet,) sınıf ve set üzerine niteliğini AllowMultipleiçin true:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class MyCustomAttribute: Attribute

6
Sadece merak - neden "mühürlü" bir sınıf?
— Tomas Aschan

18
Microsoft, mümkün olduğunda öznitelik sınıflarının mühürlenmesini önerir: msdn.microsoft.com/en-us/library/2ab31zeh.aspx
— Anton Gogolev

3
Neden mühürlendi? Kısaca: Öznitelik aramasını hızlandırır ve başka bir etkisi yoktur.
— Noel Widmer

Başka birinin kodunuzu yeniden kullanmasını durdurması dışında. Worth DataAnnotations doğrulama nitelikleri dikkat çekerek değil bunun mümkün bunlardan uzmanlık oluşturmak için yapmak son derece yararlı olduğu mühürlü.
— Neutrino

@ Neutrino, sınıflarınızın miras alınmasını beklemediğiniz veya tasarlamadığınız zamanlarda kullanılmalıdır. Ayrıca, kalıtım hataların kaynağı olduğunda, örn: İş parçacığı güvenli uygulamalar.
— Francisco Neto

20

AttributeUsageAttribute ;-p

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyAttribute : Attribute
{}

Bununla birlikte, ComponentModel ( TypeDescriptor) kullanıyorsanız , üye başına yalnızca bir öznitelik örneğini (öznitelik türü başına) desteklediğini unutmayın; ham yansıma herhangi bir sayıyı destekler ...


13

Anton'un çözümü doğru, ancak başka bir sorun var .

Kısacası, özel özelliğiniz TypeId'yi geçersiz kılmadıkça, ona erişim PropertyDescriptor.GetCustomAttributes(), özelliğinizin yalnızca tek bir örneğini döndürür.


Ancak şu yolla çalışır: var customAtt = propertyInfo.GetCustomAttributes <MyCustomAttribute> ();
— oo_dev

9

Varsayılan olarak, Attributetek bir alana / özelliğe / vb. Yalnızca bir kez uygulanmakla sınırlıdır. Bunu, MSDN'deki sınıfın tanımındanAttribute görebilirsiniz :

[AttributeUsageAttribute(..., AllowMultiple = false)]
public abstract class Attribute : _Attribute

Bu nedenle, diğerlerinin de belirttiği gibi, tüm alt sınıflar aynı şekilde sınırlıdır ve aynı özniteliğin birden çok örneğine ihtiyaç duyarsanız, aşağıdakileri açıkça ayarlamanız AllowMultiplegerekir true:

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute

Birden çok kullanıma izin veren özniteliklerde, gibi özelliklerin beklendiği gibi çalışmasını sağlamak için TypeIdözelliği de geçersizPropertyDescriptor.Attributes kılmalısınız. Bunu yapmanın en kolay yolu, öznitelik örneğini döndürmek için bu özelliği uygulamaktır:

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
    public override object TypeId
    {
        get
        {
            return this;
        }
    }
}

(Bu cevabı diğerleri yanlış olduğu için değil, daha kapsamlı / kanonik bir cevap olduğu için göndermek.)


3

Alternatif olarak, bir diziye izin vermek için niteliğinizi yeniden tasarlamayı düşünün.

[MyCustomAttribute(Sequence="CONTROL,ALT,SHIFT,D")]

veya

[MyCustomAttribute("CONTROL-ALT-SHIFT-D")]

ardından özniteliğinizi yapılandırmak için değerleri ayrıştırın.

Bunun bir örneği için, www.codeplex.com/aspnet adresindeki ASP.NET MVC kaynak kodundaki AuthorizeAttribute'a bakın .


3
Yapıcının, değiştiricili veya değiştiricisiz MyCustomAttributebir dizi dizisi alması bile mümkündür . Daha sonra sözdizimi (with ) ile uygulanabilir . string[]params[MyCustom("CONTROL", "ALT", "SHIFT", "D")]params
— Jeppe Stig Nielsen

2

AttributeUsage'ı ekledikten sonra, bu özelliği Attribute sınıfınıza eklediğinizden emin olun.

public override object TypeId
{
  get
  {
    return this;
  }
}
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.