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.