I'm looking for a way to ensure that method 'A' calls method 'B'. So roughly, the deal is..
class one
{
internal static void MethodA()
{
//Do Something here. SHOULD be calling B.
}
void MethodB()
{
//MUST be called by MethodA.
}
}
class two
{
internal void MethodA()
{
//Test that MethodA calls MethodB
}
}
I should point out that i'm stuck on .Net 2.0 for this one so ExpressionTrees are a no go. I'm not even sure they'd help but that was my initial thought.
EDIT: This is for an internal tool to visualize cyclomatic complexity of the source so I'm not concerned with breaking encapsulation here. Also,..it's likely this is going to have to be done just using System.Reflection.
This is doable in many cases, but is going to take some typing on your part. The first thing you want to do is use an ILReader class - there's an outline of one here (and the one that Florian Doyon posted). Then you want to wrap that in a class like this:
public class MethodCalls : IEnumerable<MethodInfo>
{
MethodBase _method;
public MethodCalls(MethodBase method)
{
_method = method;
}
public IEnumerator<MethodInfo> GetEnumerator()
{
// see here: http://blogs.msdn.com/haibo_luo/archive/2005/10/04/476242.aspx
ILReader reader = new ILReader(_method);
foreach (ILInstruction instruction in reader) {
CallInstruction call = instruction as CallInstruction;
CallVirtInstruction callvirt = instruction as CallVirstInstruction;
if (call != null)
{
yield return ToMethodInfo(call);
}
else if (callvirt != null)
{
yield return ToMethodInfo(callvirt);
}
}
}
}
MethodInfo ToMethodInfo(CallInstruction instr) { /* ... */ }
MethodInfo ToMethodInfo(CallVirtInstruction instr) { /* ... */ }
Neither of the two flavors of ToMethodInfo are defined because CallInstruction is not defined either. Nonetheless, this outline will hopefully turn your problem into:
public static bool Calls(MethodBase caller, MethodInfo callee)
{
return new MethodCalls(caller).Contains(callee);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With