Para saber dónde se usa un método MyClass.Foo()
, debe analizar todas las clases de todos los ensamblados que tengan una referencia al ensamblaje que contiene MyClass
. Escribí una simple prueba de concepto de cómo se puede ver este código.En mi ejemplo he usado this library (es sólo a single .cs file) escritos por John Broadus Evain:
me escribió una pequeña clase de prueba para analizar:
public class TestClass
{
public void Test()
{
Console.WriteLine("Test");
Console.Write(10);
DateTime date = DateTime.Now;
Console.WriteLine(date);
}
}
Y escribí este código para imprimir todos los métodos utilizados en TestClass.Test()
:
MethodBase methodBase = typeof(TestClass).GetMethod("Test");
var instructions = MethodBodyReader.GetInstructions(methodBase);
foreach (Instruction instruction in instructions)
{
MethodInfo methodInfo = instruction.Operand as MethodInfo;
if(methodInfo != null)
{
Type type = methodInfo.DeclaringType;
ParameterInfo[] parameters = methodInfo.GetParameters();
Console.WriteLine("{0}.{1}({2});",
type.FullName,
methodInfo.Name,
String.Join(", ", parameters.Select(p => p.ParameterType.FullName + " " + p.Name).ToArray())
);
}
}
me dio el siguiente resultado:
System.Console.WriteLine(System.String value);
System.Console.Write(System.Int32 value);
System.DateTime.get_Now();
System.Console.WriteLine(System.Object value);
Este ejemplo obviamente no está completo, porque no maneja los parámetros de ref y out, y no maneja argumentos genéricos. Estoy seguro de que olvidó otros detalles también. Simplemente muestra que se puede hacer.
¿Necesita detectar solo llamadas estáticas al método? ¿Deben detectarse las llamadas con Reflection y Reflection Emit? –
¿Y debería funcionar esto con un código no administrado? No todas las DLL admiten la reflexión. –
@Darin: esos serían la guinda del pastel, pero no son necesarios. @James: No creo que tenga que preocuparme por el código no administrado. ¿Cómo podría hacer esto en dlls que no son compatibles con la reflexión? – user420667