2010-02-17 12 views
162

Bir türüm var, t ve MyAttribute özniteliğine sahip olan ortak özelliklerin listesini almak istiyorum. özelliği, bu gibi AllowMultiple = false ile işaretlenmiştir:Belirli bir özniteliğe sahip özelliklerin listesi nasıl alınır?

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 

Şu anda ne var bu, ama daha iyi bir yolu yoktur düşünüyorum:

foreach (PropertyInfo prop in t.GetProperties()) 
{ 
    object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true); 
    if (attributes.Length == 1) 
    { 
     //Property with my custom attribute 
    } 
} 

Bunu nasıl geliştirebilirim? Özür dilerim, eğer bu bir kopyasıysa, orada bir ton yansıma ipliği var ... oldukça sıcak bir konu gibi görünüyor.

+0

Nope. Mülkün bir özelliğinin olup olmadığını öğrenebilmeniz için bir PropertyInfo'ya ihtiyacınız var. –

cevap

303
var props = t.GetProperties().Where(
       prop => Attribute.IsDefined(prop, typeof(MyAttribute))); 

Bu yani o GetCustomAttribute[s]() daha ucuzdur (herhangi bir özellik örneklerini hayata zorunluluğunu ortadan kaldırdığı

+0

İyi öneri. Bununla birlikte, öznitelik örneğine ihtiyacım var, ama hoşuma gidiyor. – wsanville

+1

Sadece mülkün çağrıldığı yan etki olmadan bir özelliğin varlığını kontrol etmenin bir yolunu arıyordum. Teşekkürler Marc, işe yarıyor! –

+1

@ ÖrjanJämte 'GetCustomAttributes' kullanırken bile' get' özelliği çağrılmaz; bununla birlikte, öznitelik * ücretsiz olan * örneklenmiştir *. Özniteliğin belirli değerlerini kontrol etmeniz gerekmiyorsa, 'IsDefined' daha ucuzdur. Ve 4.5'de, gerçekleme verilerini kontrol etmenin * gerçekte herhangi bir öznitelik örneği oluşturmadan * kontrol edilmesi için yollar vardır (bu sadece * çok özel senaryolar için * amaçlanmıştır) –

-3

iyi bir yol:

//if (attributes.Length == 1) 
if (attributes.Length != 0) 
+0

Söz konusu öznitelik AllowMultiple = false değerine sahiptir, yani 0 veya 1 vardır. Sorgumda belirtmeliydim. – wsanville

+0

downvote? Neden? + (15 karakter) – Behrooz

+1

Dunno, ben değildim. – wsanville

31

olarak bildiğim kadarıyla, daha akıllı bir şekilde Yansıma kütüphanesi ile çalışan açısından daha iyi bir yolu yoktur. Ancak, kod biraz daha hoş hale getirmek için LINQ kullanabilirsiniz:

var props = from p in t.GetProperties() 
      let attrs = p.GetCustomAttributes(typeof(MyAttribute), true) 
      where attrs.Length != 0 select p; 

// Do something with the properties in 'props' 

Bunun bir daha okunabilir şekilde kod yapılandırmaya yardımcı olur inanıyoruz.

12

hep LINQ vardır:

t.GetProperties().Where(
    p=>p.GetCustomAttributes(typeof(MyAttribute), true).Length != 0) 
5

Eğer Yansıma içinde Öznitelikler'in düzenli başa varsa, bazı uzatma yöntemlerini tanımlamak için çok pratiktir. Orada birçok projede göreceksiniz. Buradaki tek biridir Sık sık var:

public static bool HasAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute 
{ 
    var atts = provider.GetCustomAttributes(typeof(T), true); 
    return atts.Length > 0; 
} 

Eğer kimlik örneğin bir ince sözdizimi olması typeof(Foo).HasAttribute<BarAttribute>();

Diğer projelerde (örn StructureMap) İfade ağaçları kullanmak tam teşekküllü ReflectionHelper sınıfları gibi kullanabileceğiniz PropertyInfos. Kullanımı daha sonra bu gibi görünür:

ReflectionHelper.GetProperty<Foo>(x => x.MyProperty).HasAttribute<BarAttribute>() 
34

Ben en çok Tomas Petriček cevabı off dayanır kullanarak sona çözüm. . genellikle hem nitelik ve mal ile bir şeyler yapmak istiyorum. Ayrıca

var props = from p in this.GetType().GetProperties() 
      let attr = p.GetCustomAttributes(typeof(MyAttribute), true) 
      where attr.Length == 1 
      select new { Property = p, Attribute = attr.First() as MyAttribute}; 
+0

+1 - "Genelde hem özellik hem de mülk ile bir şeyler yapmak istiyorum", aradığım şey - cevabınızı gönderdiğiniz için çok teşekkürler! –

0

öncesi Yazık cevaplar: Koleksiyonun kontrol uzunluğu yerine Any() yöntemini kullanmak daha iyidir:

propertiesWithMyAttribute = type.GetProperties() 
    .Where(x => x.GetCustomAttributes(typeof(MyAttribute), true).Any()); 
İlgili konular