2009-02-16 30 views
69

Öznitelik sınıfından miras alınan bir özel özniteliğim kullanıyorum.Yinelenen izin verilen öznitelikler nasıl oluşturulur

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

} 

Ama "Yinelenen 'MyCustomAttribute' özelliği" hata gösterilmiştir: Böyle kullanıyorum.
Yinelenen izin verilen bir özelliği nasıl oluşturabilirim?

cevap

132

Çubuk sizin Özellik sınıfının üzerine AttributeUsage özniteliği (evet, o lokma) ve set AllowMultipletrue için: ancak

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

Sadece meraklı - neden bir "mühürlü" sınıf? –

+15

Microsoft, mümkün olduğunda sızdırmazlık özellik sınıflarını önerir: http://msdn.microsoft.com/en-us/library/2ab31zeh.aspx –

+1

Neden mühürlenmiş? Kısaca: Nitelik aramasını daha hızlı yapar ve başka hiçbir etkisi yoktur. –

16

AttributeUsageAttribute ;-p

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

Not, bu kadar eğer ComponentModel (TypeDescriptor) kullanarak, yalnızca üye başına bir öznitelik örneğini (öznitelik türü başına) destekler; raw yansıma herhangi bir sayıyı destekler ...

3

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

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

veya

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

ardından niteliğini yapılandırmak için değerleri ayrıştırmak.

Bunun bir örneği için, www.codeplex.com/aspnet numaralı telefondan ASP.NET MVC kaynak kodundaki AuthorizeAttribute öğesini inceleyin.

+1

'MyCustomAttribute' yapıcısına 'params' değiştiricisine sahip olan veya olmayan bir dizgenin * dizi * dizgesini * almak bile mümkündür. Daha sonra sözdizimi '' MyCustom ('' CONTROL '', 'ALT', 'SHIFT' ',' D ')] '' ('params' ile) ile uygulanabilir. –

11

Anton's solution doğru, ancak another gotcha var.

Kısaca, özel durumunuz TypeId'yi geçersiz kılmadıkça, PropertyDescriptor.GetCustomAttributes() aracılığıyla erişme, özniteliğinizin yalnızca bir örneğini döndürür. Eğer AttributeUsage ekledikten sonra

1

, kendi Özellik sınıfının Varsayılan olarak

public override object TypeId 
{ 
    get 
    { 
    return this; 
    } 
} 
2

için bu özelliği eklemek emin olun Attribute s vb tek bir alan/mülk/yalnızca bir kez uygulanan sınırlıdır. , Açıkça true için AllowMultiple ayarlamanız gerekir diğerleri de belirtildiği gibi

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

nedenle, tüm alt sınıflar aynı şekilde sınırlıdır ve aynı özelliğin birden fazla örneğini gerektirir olmalıdır: Sen definition of the Attribute class on MSDN bu anlaşılıyor :

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

birden kullanımlarını izin nitelikler üzerinde you should also override the TypeId property özellikleri böyle PropertyDescriptor.Attributes iş olarak beklendiği gibi olmasını sağlamak için. Bunu yapmanın en kolay yolu nitelik örneğini kendisi dönmek için bu özelliği uygulamaktır:

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

(bu yanıtı yayınlama diğerlerini yanlış, ama bu daha kapsamlı/kanonik cevaptır çünkü çünkü.)

İlgili konular