Question

Je pose peut-être cette question de manière incorrecte, mais je peux / comment trouver des champs dans une classe en elle-même ... par exemple ...

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

Ou peut-être que je fais juste cela de manière incorrecte ... Comment puis-je appeler une méthode et ensuite vérifier les attributs qui lui sont appliqués?

Par ailleurs, dans l'intérêt de la question , je suis simplement curieux de savoir s'il était possible de trouver des informations d'attribut sans savoir / accéder à la classe parente!

Était-ce utile?

La solution

Si je comprends bien votre question, je pense que ce que vous essayez de faire n'est pas possible ...

Dans la méthode Render , vous souhaitez obtenir un attribut possible appliqué à l'objet. L'attribut appartient au champ _SecondPart qui appartient à la classe HtmlForm .

Pour que cela fonctionne, vous devez passer l'objet appelant à la méthode 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");
            }
        }
    }

Autres conseils

Voici un exemple d'objet donné à un seul objet, pour savoir si des champs publics ou privés de cet objet ont une propriété spécifique:

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

}

Pour la deuxième partie de votre question, vous pouvez vérifier si un attribut est défini sur la méthode actuelle à l'aide de:

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

Modifier

Pour répondre à votre modification, oui, il est possible de ne pas connaître le type réel. La fonction suivante prend un type Parameter et renvoie tous les champs ayant un attribut donné. Quelqu'un quelque part va soit connaître le type que vous souhaitez rechercher, soit disposer d'une instance du type que vous souhaitez rechercher.

Sans cela, vous devrez faire ce que Jon Skeet a dit, qui consiste à énumérer tous les objets d'un assemblage.

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

Vous pouvez rechercher des champs dans une classe à l'aide de Type.GetFields , ainsi que des attributs appliqués à un champ à l'aide de MemberInfo.GetCustomAttributes ou IsDefined - mais si vous avez besoin de trouver tous les champs d'un type particulier, vous devrez:

  • Parcourez tous les assemblys que vous souhaitez rechercher
  • Itérer sur tous les types de chaque assemblage
  • Itérer sur tous les champs de chaque type
  • Vérifier la présence / absence de l'attribut pour chaque champ

Maintenant, si vous essayez vraiment de savoir "est un attribut particulier appliqué à un champ dont la valeur est une référence à" cet "objet" alors c'est encore plus difficile - car il faudrait tout savoir sur chaque objet du système. Vous devez également garder à l’esprit que deux champs peuvent avoir la même valeur, c’est-à-dire référencer le même objet. L'objet compterait-il comme "facultatif"? dans ce cas ou pas?

Fondamentalement, si l'objet doit avoir une propriété (par exemple, facultative ou non), il doit s'agir d'une propriété de l'objet lui-même, et non du champ contenant la propriété.

Il se peut que j'interprète mal ce que vous essayez de faire, mais je soupçonne que ce n'est pas réalisable ou du moins que ce n'est pas une bonne idée. Pourriez-vous expliquer la plus grande image ici? Qu'est-ce que vous essayez vraiment de faire avec cet attribut?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top