Размышляя о собственности, чтобы получить атрибуты. Как это сделать, когда они определены в другом месте? - PullRequest
4 голосов
/ 20 июня 2009

У меня есть класс Bar такой:

class Foo : IFoo {
  [Range(0,255)]
  public int? FooProp {get; set}
}

class Bar : IFoo
{
  private Foo foo = new Foo();
  public int? FooProp { get { return foo.FooProp; }
                       set { foo.FooProp= value; } } 
}

Мне нужно найти атрибут [Range (0,255)], отражающий ТОЛЬКО свойство Bar.FooProp. Я имею в виду, реквизит оформлен в экземпляре класса (.. new Foo ()), а не в классе, когда я в данный момент выполняю синтаксический анализ. Infact Bar.FooProp не имеет атрибутов

EDIT

Я переместил атрибуты в определение интерфейса, поэтому мне нужно проанализировать унаследованные интерфейсы, чтобы найти их. Я могу сделать это, потому что класс Bar должен реализовывать IFoo. В этом конкретном случае мне повезло, но проблема остается, когда у меня нет интерфейсов ... Я приму к сведению в следующий раз

foreach(PropertyInfo property in properties)
{
  IList<Type> interfaces = property.ReflectedType.GetInterfaces();
  IList<CustomAttributeData> attrList;
  foreach(Type anInterface in interfaces)
  {
    IList<PropertyInfo> props = anInterface.GetProperties();
    foreach(PropertyInfo prop in props)
    {
      if(prop.Name.Equals(property.Name))
      { 
        attrList = CustomAttributeData.GetCustomAttributes(prop);
        attributes = new StringBuilder();
        foreach(CustomAttributeData attrData in attrList)
        {
            attributes.AppendFormat(ATTR_FORMAT,
                                        GetCustomAttributeFromType(prop));
        }
      }
    }
  }

Ответы [ 2 ]

2 голосов
/ 19 октября 2009

Некоторое время назад у меня была похожая ситуация, когда у меня был атрибут, объявленный для метода в интерфейсе, и я хотел получить атрибут от метода для типа, реализующего интерфейс. Например:

interface I {
  [MyAttribute]
  void Method( );
}

class C : I {
  void Method( ) { }
}

Приведенный ниже код используется для проверки всех интерфейсов, реализованных типом, просмотра того, какие элементы интерфейса реализует данный method (используя GetInterfaceMap), и возвращает любые атрибуты этих элементов. Прямо перед этим я также проверяю, присутствует ли атрибут в самом методе.

IEnumerable<MyAttribute> interfaceAttributes =
  from i in method.DeclaringType.GetInterfaces( )
  let map = method.DeclaringType.GetInterfaceMap( i )
  let index = GetMethodIndex( map.TargetMethods, method )
  where index >= 0
  let interfaceMethod = map.InterfaceMethods[index]
  from attribute in interfaceMethod.GetCustomAttributes<MyAttribute>( true )
  select attribute;

...

static int GetMethodIndex( MethodInfo[] targetMethods, MethodInfo method ) {
  return targetMethods.IndexOf( target =>
         target.Name == method.Name
      && target.DeclaringType == method.DeclaringType
      && target.ReturnType == method.ReturnType
      && target.GetParameters( ).SequenceEqual( method.GetParameters( ), PIC )
  );
}
1 голос
/ 20 июня 2009

Если посмотреть на FooProp, то ничто не может идентифицировать существование Foo (в любой точке). Возможно, вы могли бы добавить атрибут для идентификации поля foo и поразмышлять об этом (через FieldInfo.FieldType)?

...