Отражение в C # :Поиск атрибутов в поле элемента

StackOverflow https://stackoverflow.com/questions/803221

Вопрос

Возможно, я задаю это неправильно, но можете ли вы / как вы можете найти поля в классе внутри него самого...например...

public class HtmlPart {
  public void Render() {
    //this.GetType().GetCustomAttributes(typeof(OptionalAttribute), false);
  }
}

public class HtmlForm {
  private HtmlPart _FirstPart = new HtmlPart();      
  [Optional] //<-- how do I find that?
  private HtmlPart _SecondPart = new HtmlPart();
}

Или, может быть, я просто делаю это неправильно...Как я могу вызвать метод, а затем проверить наличие атрибутов, примененных к нему самому?

Кроме того, ради самого вопроса - Мне просто интересно, удалось ли найти атрибутивную информацию не зная / не получая доступа к родительскому классу!

Это было полезно?

Решение

Если я правильно понимаю ваш вопрос, я думаю, что то, что вы пытаетесь сделать, невозможно...

В Render метод, в котором вы хотите получить возможный атрибут, примененный к объекту.Атрибут принадлежит полю _SecondPart ведьма принадлежит к этому классу HtmlForm.

Чтобы это сработало, вам нужно было бы передать вызывающий объект в Render способ:

    public class HtmlPart {
        public void Render(object obj) {
            FieldInfo[] infos = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            foreach (var fi in infos)
            {
                if (fi.GetValue(obj) == this && fi.IsDefined(typeof(OptionalAttribute), true))
                    Console.WriteLine("Optional is Defined");
            }
        }
    }

Другие советы

Вот пример того, как для данного отдельного объекта определить, обладают ли какие-либо открытые или закрытые поля этого объекта определенным свойством:

var type = typeof(MyObject);
foreach (var field in type.GetFields(BindingFlags.Public |
             BindingFlags.NonPublic | BindingFlags.Instance))
{
    if (field.IsDefined(typeof(ObsoleteAttribute), true))
    {
        Console.WriteLine(field.Name);
    }

}

Что касается второй части вашего вопроса, вы можете проверить, определен ли атрибут в текущем методе, используя:

MethodInfo.GetCurrentMethod().IsDefined(typeof(ObsoleteAttribute));

Редактировать

Чтобы ответить на вашу правку утвердительно, это возможно без знания фактического типа.Следующая функция принимает параметр типа и возвращает все поля, которые имеют данный атрибут.Кто-то где-то либо будет знать тип, который вы хотите найти, либо у него будет экземпляр типа, который вы хотите найти.

Без этого вам пришлось бы делать так, как сказал Джон Скит, то есть перечислять все объекты в сборке.

   public List<FieldInfo> FindFields(Type type, Type attribute)
    {
        var fields = new List<FieldInfo>();
        foreach (var field in type.GetFields(BindingFlags.Public |
                           BindingFlags.NonPublic |
                           BindingFlags.Instance))
        {
            if (field.IsDefined(attribute, true))
            {
                fields.Add(field);
            }

        }
        return fields;
    }

Вы можете найти поля внутри класса, используя Type.GetFields, и вы можете найти атрибуты , примененные к полю , используя MemberInfo.GetCustomAttributes или IsDefined - но если вам нужно найти все поля определенного типа, вам придется:

  • Выполните итерацию по всем сборкам, которые вы хотите найти
  • Выполните итерацию по всем типам в каждой сборке
  • Выполните итерацию по всем полям внутри каждого типа
  • Проверьте наличие / отсутствие атрибута для каждого поля

Теперь, если вы действительно пытаетесь выяснить, "применяется ли определенный атрибут к полю, значение которого является ссылкой на "этот" объект", то это еще сложнее - потому что вам нужно было бы знать все о каждом объекте в системе.Вы также должны иметь в виду, что могут быть два оба поля имеют одинаковое значение, т.е.ссылается на один и тот же объект.Будет ли объект считаться "необязательным" в этом случае или нет?

В принципе, если объект должен обладать свойством (напримернеобязательно или нет), то это должно быть свойство самого объекта, а не поля, содержащего это свойство.

Возможно, я неправильно истолковываю то, что вы пытаетесь сделать, но я подозреваемый это либо неосуществимо, либо, по крайней мере, не очень хорошая идея.Не могли бы вы объяснить здесь общую картину?Чего вы на самом деле пытаетесь достичь с помощью этого атрибута?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top