Domanda

Potrei chiederlo in modo errato, ma posso / come puoi trovare campi su una classe al suo interno ... per esempio ...

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 forse sto solo facendo questo in modo errato ... Come posso chiamare un metodo e quindi verificare la presenza di attributi applicati a se stesso?

Inoltre, per il bene della domanda - Sono solo curioso di sapere se era possibile trovare informazioni sugli attributi senza conoscere / accedere alla classe genitore!

È stato utile?

Soluzione

Se capisco correttamente la tua domanda, penso che ciò che stai cercando di fare non sia possibile ...

Nel metodo Render , si desidera ottenere un possibile attributo applicato all'oggetto. L'attributo appartiene al campo _SecondPart witch appartiene alla classe HtmlForm .

Affinché funzioni, dovresti passare l'oggetto chiamante al metodo 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");
            }
        }
    }

Altri suggerimenti

Ecco un esempio di come dare a un singolo oggetto come scoprire se qualche campo pubblico o privato su quell'oggetto ha una proprietà specifica:

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

}

Per la seconda parte della tua domanda puoi verificare se un attributo è defiend sul metodo corrente usando:

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

Modifica

Per rispondere alla modifica sì, è possibile senza conoscere il tipo effettivo. La seguente funzione accetta un tipo di parametro e restituisce tutti i campi con un determinato attributo. Qualcuno da qualche parte conoscerà il Tipo che si desidera cercare o avrà un'istanza del tipo che si desidera cercare.

Senza quello dovresti fare come diceva Jon Skeet, che è quello di enumerare tutti gli oggetti in un assembly.

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

Puoi trovare campi all'interno di una classe usando Type.GetFields e puoi trovare gli attributi applicati a un campo usando MemberInfo.GetCustomAttributes o IsDefined - ma se devi trovare tutti i campi di un particolare tipo, dovrai:

  • Scorrere su tutti gli assembly che si desidera cercare
  • Scorrere su tutti i tipi all'interno di ciascun assieme
  • Scorrere su tutti i campi all'interno di ciascun tipo
  • Verifica presenza / assenza dell'attributo per ciascun campo

Ora, se stai davvero cercando di scoprire " è un attributo particolare applicato a un campo il cui valore è un riferimento a "questo" oggetto " allora è ancora più difficile, perché dovresti sapere tutto su ogni oggetto nel sistema. Dovresti anche tenere presente che potrebbero esserci due campi entrambi con lo stesso valore, ovvero facendo riferimento allo stesso oggetto. L'oggetto conta come "opzionale"? in quel caso o no?

Fondamentalmente, se l'oggetto deve avere una proprietà (ad es. opzionale o no), quella deve essere una proprietà dell'oggetto stesso, non il campo contenente la proprietà.

È possibile che io stia fraintendendo quello che stai cercando di fare, ma sospetto non è fattibile o almeno non è una buona idea. Potresti spiegare il quadro generale qui? Cosa stai davvero cercando di ottenere con questo attributo?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top