2015-05-29 15 views
8

jak mogę niezawodnie uzyskać MethodInfo (odbicie) z IMethodSymbol (drzewo składni Roslyn). Mogę pobrać typ z IMethodSymbol, a typ ma wiele metod, z których jedna odpowiada instancji IMethodSymbol.Roslyn uzyskać MethodInfo z IMethodSymbol

np.

int i = 0; 
i.Equals(5); 

gdzie IMethodSymbol identyfikuje 'równa'

Należy zauważyć, że istnieją dwa [równa] metod działania [Int32] typ, który toczy i [obiektu], drugi lek [Int32] parametru.

Parsuję skrypty, nie mam żadnych instancji obszaru roboczego.

Wszelkie pomysły? Stevo

Odpowiedz

1

To nie jest możliwe, aby niezawodnie uzyskać MethodInfo z IMethodSymbol ponieważ trzeba mieć zespół ładowane że zawiera typ, że metoda jest włączona, co może mieć miejsce w przypadku scenariusza, który jest analizowany, ale może być , a nie w przypadku kodu wykonującego analizę.

Innymi słowy, kod skryptu, który uruchamiasz może mieć zainstalowany zespół X, który zawiera typ T, który ma na nim metodę M (i dlatego kod skryptu może zawierać kod, który wywołuje metodę M), ale analizator może nie być mieć zespół X obciążone i dlatego może nie obciążenie typu T i tak może nie uzyskać instancję MethodInfo na metodzie M.

jednak dla zespołu jak system, to chyba dość bezpiecznie założyć, że może dostęp do niego z kodu analizatora.

Wszystko, co musisz zrobić, to uzyskać przestrzeń nazw i nazwę typu, który ma tę metodę i uzyskać dla niej instancję TypeInfo. Następnie użyj GetMethod - przekazując mu nazwę metody i typy argumentów, aby uzyskać MethodInfo. Coś takiego:

var invocation = (InvocationExpressionSyntax)context.Node; 
var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbolInfo(invocation).Symbol; 
var declaringTypeName = string.Format(
    "{0}.{1}", 
    methodSymbol.ContainingType.ContainingAssembly.Name, 
    methodSymbol.ContainingType.Name 
); 
var methodName = methodSymbol.Name; 
var methodArgumentTypeNames = methodSymbol.Parameters.Select(
    p => p.Type.ContainingNamespace.Name + "." + p.Type.Name 
); 
var methodInfo = Type.GetType(declaringTypeName).GetMethod(
    methodName, 
    methodArgumentTypeNames.Select(typeName => Type.GetType(typeName)).ToArray() 
); 

Warto zauważyć, że często są analizatory przenośne biblioteki klas, które nie mają dostępu do pełnej refleksji API (co oznacza, że ​​powyższy kod nie będzie działać), ale jeśli jesteś po prostu za pomocą Roslyn w projekcie analizującym niektóre skrypty, prawdopodobnie nie musisz mieć tego ograniczenia.

Powiązane problemy