Pregunta

Puede que esté preguntando esto incorrectamente, pero puedo / cómo puedo encontrar campos en una clase dentro de sí misma ... por ejemplo ...

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();
}

O tal vez solo estoy haciendo esto incorrectamente ... ¿Cómo puedo llamar a un método y luego verificar los atributos aplicados a sí mismo?

También, por el bien de la pregunta . Tengo curiosidad por saber si fue posible encontrar información de atributos sin saber / acceder a la clase principal.

¿Fue útil?

Solución

Si entiendo su pregunta correctamente, creo que lo que está tratando de hacer no es posible ...

En el método Render , desea obtener un atributo posible aplicado al objeto. El atributo pertenece al campo _SecondPart que pertenece a la clase HtmlForm .

Para que funcione debería pasar el objeto que llama al método 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");
            }
        }
    }

Otros consejos

Este es un ejemplo de un solo objeto dado cómo encontrar si algún campo público o privado en ese objeto tiene una propiedad específica:

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);
    }

}

Para la segunda parte de su pregunta, puede verificar si un atributo está definido en el método actual usando:

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

Editar

Para responder a su edición sí, es posible sin saber el tipo real. La siguiente función toma un tipo de parámetro y devuelve todos los campos que tienen un atributo dado. Alguien en algún lugar sabrá el tipo que desea buscar o tendrá una instancia del tipo que desea buscar.

Sin eso, tendrías que hacer lo que dijo Jon Skeet, que consiste en enumerar todos los objetos en un ensamblaje.

   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;
    }

Puede encontrar campos dentro de una clase usando Type.GetFields , y puede encontrar atributos aplicados a un campo usando MemberInfo.GetCustomAttributes o IsDefined - pero si necesita encontrar todos los campos de un tipo en particular, tendrá que:

  • Iterar sobre todos los ensamblajes que desea buscar
  • Iterar sobre todos los tipos dentro de cada ensamblado
  • Iterar sobre todos los campos dentro de cada tipo
  • Verifique la presencia / ausencia del atributo para cada campo

Ahora, si realmente estás tratando de averiguar " es un atributo particular aplicado a un campo cuyo valor es una referencia a 'este' objeto " entonces eso es aún más difícil, porque tendría que saber todo sobre cada objeto en el sistema. También debe tener en cuenta que podría haber dos campos con el mismo valor, es decir, que hagan referencia al mismo objeto. ¿El objeto contaría como " opcional " En ese caso o no?

Básicamente, si el objeto debe tener una propiedad (por ejemplo, opcional o no), debe ser una propiedad del objeto en sí, no el campo que contiene la propiedad.

Podría ser que estoy malinterpretando lo que estás tratando de hacer, pero sospecho no es factible o al menos no es una buena idea. ¿Podría explicar el cuadro más grande aquí? ¿Qué estás realmente tratando de lograr con este atributo?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top