I have several special methods, and I want analyze they calls in compiled assembly.
Example:
public static class SrcHelper {
[MySpecialMethod]
[Conditional( "DEBUG" )]
public static void ToDo( params object[] info ) {
/* do nothing */
/* this method is not called when code is compiled in RELEASE mode */
}
}
// ... somewhere else in another assembly ...
Array CreateArraySampleMethod( int size ) {
// This call has only informative character. No functionality is required.
SrcHelper.ToDo( "Should create array of ", typeof( MyClass ), " with specified size." );
throw new NotImplementedException();
}
From this compiled code I want get the argument values { “Should create array of “, MyClass, ” with specified size.” }.
I tried use Cecil from Mono, and I found the instructions for call “ToDo” method. But now am I confused how to identify instruction with argument values.
I know, there can be complex situation, and some argument’s value can not be resolved. But I need resolve only constant values – it’s enough for my purpose.
Thanks.
EDIT:
The “ToDo” method (and similar ones) should be used as alternative to comments ( //, /* … */ ), and after compilation, should be IL analyzed and autogenerated documentation and todo-list for concrete assembly.
The code generation is somewhat confusing but can be done for simple cases:
compiling:
(adding "x" to force it to use a params overload)
gives
So you have to do is parse the il to detect the arguments being pushed into the compiler generated array. a heristic that is fragile but might be sufficient it to say:
This is rough but may be sufficient for your needs.
An AOP style approach will get you what you want at runtime by simply instrumenting every call to dump the values but at sompile time the approach above is your only realistic option given only the IL.
The code generated may be very different in Release builds, You will be unable to spot the auto generated array verses someone explicitly creating it themselves (which may be further away from the call site or even in a different method/constructor/class.
Proviso
I should note after your edit for why you want to do this that Attribute based annotations are a far better solution, I cannot see why you would want to do this in the method when you can attribute it directly…