Trovare il PropertyInfo ospita dal MethodInfo di getter / setter
-
21-08-2019 - |
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?
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