Domanda

faccio un po 'di analisi di tipo in fase di esecuzione utilizzando la riflessione. Se ho un esempio MethodInfo, come posso capire se questo è un metodo "reale" o è un metodo getter / setter di un immobile? E se si tratta di una proprietà, come posso trovare la sua PropertyInfo ospitare di nuovo?

È stato utile?

Soluzione

Ecma 335 specifica (ma non richiede) che i compilatori utilizzano il get_ / prefissi set_ (capitolo 22.28). Non so qualsiasi linguaggio che rompe tale raccomandazione. Rendendo più semplice:

public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) {
  if (!method.IsSpecialName) return null;
  return t.GetProperty(method.Name.Substring(4), 
    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
}

Altri suggerimenti

Bene, il metodo dietro un getter e setter sono metodi "reali".

Re Tracking Torna in una proprietà - il modello (di ritorno vs prendere 1 arg) vi aiuterà a restringere esso -. Ma dovrete chiamare GetGetMethod / GetSetMethod su ogni per trovare la proprietà

Si potrebbe probabilmente provare il Name (meno get __ / set__) - ma che si sente fragile. Ecco la versione più lunga (senza uso di <=>):

static PropertyInfo GetProperty(MethodInfo method)
{
    bool takesArg = method.GetParameters().Length == 1;
    bool hasReturn = method.ReturnType != typeof(void);
    if (takesArg == hasReturn) return null;
    if (takesArg)
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
    }
    else
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
    }
}

Se vuoi in MethodBase.IsSpecialName . I metodi che non devono essere chiaramente visibili, come ad esempio accesso alle proprietà, i metodi di sottoscrizione di eventi e sovraccarichi operatore non usi questo flag.

Per quanto ne so, non c'è un modo per trovare la PropertyInfo senza iterazione attraverso le proprietà e confrontando i metodi.

Mi piacerebbe davvero lasciare questo come un commento, ma non posso dal mio rappresentante non è abbastanza alta: (

Theres un bug nel codice di Marc Gravell: se un indicizzatore tornerà null, anche quando esiste una proprietà genitore. Il suo bello avere così veloce-fail, ma penso che possiamo farlo solo quando non ha né un valore di ritorno o di un parametro:

    [Pure]
    public static PropertyInfo GetParentProperty(this MethodInfo method)
    {
        if (method == null) throw new ArgumentNullException("method");
        var takesArg = method.GetParameters().Length == 1;
        var hasReturn = method.ReturnType != typeof(void);
        if (!(takesArg || hasReturn)) return null;

        if (takesArg && !hasReturn)
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method);
        }
        else
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method);
        }
    }

Il trucco per giocare con BindingFlags.DeclaredOnly e IsSpecialName

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