C # Reflection - can I check if one method is calling another

I am looking for a way to ensure that method "A" calls method "B". So rude, the fact is that ..

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 must point out that I am stuck on .Net 2.0 for this, so ExpressionTrees is not an option. I’m not even sure that they will help, but that was my initial thought.

EDIT: This is an internal tool for visualizing the cyclic complexity of a source, so I'm not interested in breaking encapsulation here. Also, this probably needs to be done simply using System.Reflection.

+3
source share
6 answers

There is a code snippet for an IL reader, you may need to fix it to support generics.

http://www.codeproject.com/KB/cs/sdilreader.aspx

!

+2

, . , , ILReader - ( , ). :

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) { /* ... */ }

ToMethodInfo , CallInstruction . , , , :

public static bool Calls(MethodBase caller, MethodInfo callee)
{
    return new MethodCalls(caller).Contains(callee);
}
+3

Mono Cecil, MethodA call/callvirt, MethodB.

+2

, , , , . (, Moq, ) , .

+1

, , .

, , :

void MethodB() {
    var methodA = BuildDelegate("Method" + "A");
    methodA();
}
+1

? , MethodB .

class one
{
    internal static void MethodA()
    {
        //Do Something here.  SHOULD be calling B.
    }

    internal virtual void MethodB()
    {
         //MUST be called by MethodA.
    }
}

class three : one
{
    public bool wasCalled;
    override void MethodB()
    {
         wasCalled=true;
    }
}


class two
{
    internal void MethodA()
    {
        three.ClassA();
        if (three.wasCalled)
        {
        }
    }
} 
+1

Source: https://habr.com/ru/post/1729906/


All Articles