Click here to Skip to main content
15,895,256 members
Please Sign up or sign in to vote.
1.50/5 (4 votes)
See more:
Using reflection or some other technique I want to know how many times methodB is called. Best would be to count number of calls for methodB winthin methodA. It would suffice to count the number of calls to methodB.

C#
class MyClass
{
    void methodA()
    {
        methodB();
        methodB();
    }
    void methodB()
    {
    }
}
Posted
Updated 16-Jan-12 8:01am
Comments
Sergey Alexandrovich Kryukov 16-Jan-12 13:15pm    
Static or instance method?
--SA
Nathan Stiles 16-Jan-12 13:23pm    
SAKryukov it could be either as far as I'm concerned.
Nathan Stiles 16-Jan-12 13:31pm    
SAKryukov the number of calls will not change at runtime. I wanted to know before executing methodA how many individual references to methodB exist in methodA or how many references to methodB exist in the assembly. Not how many times methodB has been called, that's as you say a simple count.
The current solution would be to right click methodB in VS and find all references that gives me the count I'm looking for. I wanted to skip having to manually count references.
Sergey Alexandrovich Kryukov 16-Jan-12 14:04pm    
OK, this is not a number of calls at all. I addressed this problem in the second paragraph of my answer. I'm just curious: did you vote 1 because you failed to see it? I simply don't want to discuss this really different problem with you any further, at least right now.

First, this problem is really difficult, so my introductory paragraph in my answer is enough. More comprehensive answer will need a really big article with code, etc. This is something well above the format of Quick Questions & Answers.

Secondly, please forgive me if I'm wrong, but I think this problem is well above your head. I can see this looking at the way you ask questions and argue. Of course I would be happy to be wrong here.
Nathan Stiles 29-Jun-12 23:16pm    
See solution...

Reflection cannot help here, because this is all run time. Reflection can only help you to pull static property of code. Do you even understand that the number of calls can be changed during run time at any moment? [EDIT] As further discussion demonstrated, this is not what OP meant. The problem was failure to explain what is meant by "call". [END EDIT]

It would be completely different story tf you meant to find all references to some method throughout the program, this is much more difficult task. Basically, it should involve decompilation of the code or static analysis of the solution if the source code through parsing it first. I don't even want to discuss it any further here. I you were capable of addressing such problems, I could see it in the way you formulate questions. Sorry. [EDIT] As further discussion demonstrated, this is what OP really meant to do. In this paragraph and in my new comments to the question, I tried to explain why I think this short explanation should be enough for now. [END EDIT]

I would say, there is only one reliable way to count calls: to program it in the calling method itself, increment some counter which is a field of the declaring class. This problem is just trivial. [EDIT] As further discussion demonstrated, this is irrelevant to what OP wanted. [END EDIT]

[EDIT]

Bill make some good points in his comments below.
The ability to predict run-time behavior is a big issue of computability theory.

The complexity of this problem can be clearly seen on the example of well-known halting problem: the answer to the question if some program will ever halt or is going to execute forever is statically undecideable:

Please see:
http://en.wikipedia.org/wiki/Halting_problem[^],
http://en.wikipedia.org/wiki/Computability_theory_(computer_science)[^],
http://en.wikipedia.org/wiki/Undecidable_problem[^].

It seems obvious that if that even the halting is undecideable, the prediction of the number of some calls is not better.

From the other hand, let's look at the proof of the halting theorem. The proof is non-constructing and involves the following idea: suppose the halting problem is solvable using some algorithm A. Then it can be proved then the algorithm A can be used to create the behavior of the program opposite the the prediction by A. "Non-constructive" means that the proof does not help to construct the program which behavior is undecideable, but we can see that such design can be more exotic. This suggests that, in many special cases, the behavior of program would be quite predictable.

Of course, this is true, so Bill is right here. The practically important problem here is: can a class of predictable programs be found, which would be non-trivial enough (that is, good enough for solving practical non-trivial problem) and could static analysis be practical. The problem is very difficult, but static analysis is already used to validate certain aspects of run-time behavior of a program statically. I'm actually working at one of such problems.

But of course, as now we know that Nathan meant a very different problem: to could the number of call statements which program the call to a certain method, in the body of some other method. This problem is solvable, because this is a pure static analysis, not directly related to the run time. I'm too lazy to get to solving it; perhaps Nathan can find a correct solution based on the one he already posted. :-)

—SA
 
Share this answer
 
v3
Comments
BillWoodruff 1-Jul-12 11:37am    
+5 I must agree with SAK's analysis here: unless: you are in a situation (one very hard to imagine, but possible), where every exact thing that happens at run-time can be predicted through either static code analysis (pre-compiled, or compiled to IL), or if you have "world-knowledge" of exactly what can, and will, happen at run-time because the end-user can do only a highly specific set of actions, and must do all those actions: how can you predict the number of a certain methods calls ?

I am not saying static pre-compile time code analysis is not a wonderful tool, and I like the solution Nathan presents here: in mind it's an answer to a slightly different issue than the OP.

But, overall, I feel we have to yet to reallly get the "big picture" behind this interesting question "in sharp focus."

Perhaps what we need to do here is "abandon all addiction" to thinking of what Nathan's asking here ... in terms of dynamic asynchronous event-driven user run-time interfaces: where an end-user may do any damn thing any time : :) ?
best, Bill
Sergey Alexandrovich Kryukov 1-Jul-12 14:10pm    
Thank you, Bill.
Of course, you have made very good points here; I credit this constructive and useful comment.
Please see my update to the question: last paragraphs after last [EDIT].
--SA
Sergey Alexandrovich Kryukov 1-Jul-12 14:09pm    
[Misplaced, to be removed -- SA]
C#
using System;
using System.Reflection;

namespace ReflectRefCount
{
    static class Program
    {
        static void Main()
        {
            Type t = typeof(A);
            MethodInfo mi = t.GetMethod("E");
            MethodBody mb = mi.GetMethodBody();
            byte[] byEmptyMethod = mb.GetILAsByteArray();
            mi = t.GetMethod("D");
            mb = mi.GetMethodBody();
            byte[] byMethodOneCall = mb.GetILAsByteArray();
            byte[] byCallSig = new byte[byMethodOneCall.Length - byEmptyMethod.Length];
            for (int i = 0; i < byCallSig.Length; i++)
            {
                byCallSig[i] = byMethodOneCall[i];
            }
            mi = t.GetMethod("B");
            mb = mi.GetMethodBody();
            byte[] byMethodTarget = mb.GetILAsByteArray();
            int cnt = match(byCallSig, byMethodTarget);
        }

        private static int match(byte[] needle, byte[] haystack)
        {
            int result = 0;
            int end = needle.Length - 1;
            int hend = haystack.Length - 1;
            for (int i = 0; i < haystack.Length; i++)
            {
                bool match = true;
                int pos = 0;
                while (match)
                {
                    int ipos = i + pos;
                    if (ipos > hend)
                    {
                        break;
                    }
                    match = false;
                    if (haystack[ipos]==needle[pos])
                    {
                        match = true;
                    }
                    if (pos == end)
                    {
                        if (match)
                        {
                            result++;
                        }
                        break;
                    }
                    pos++;
                }
            }
            return result;
        }

        public class A
        {
            public void B()
            {
                C();
                C();
                C();
                C();
                C();
            }
            private void C()
            {
            }
            public void D()
            {
                C();
            }
            public void E()
            {
            }

        }
    }
}
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 30-Jun-12 13:31pm    
Impressive, but as I say, it is nothing like a number of calls. This is... hard to say what... something related... number of call statements?

1) As I already explained, it's not possible to predict number of calls during run-time;

2) this code does not really correctly counts even the number of call statements;

To see it, it's enough to modify B:
public void B() {
for (int index = 0; index < 100; ++index)
C();
}

If this code counted number of calls, it would return 100; of course, I did not expect it.
If this code correctly counted number of code statements, it would return 1.

What to check up what it returns? It returns 0!

Again, this result is impressive anyway, but why did you even formally accept it? Not fair, I thing...
--SA
Nathan Stiles 30-Jun-12 13:51pm    
This does do what I was seeking. I understand that it's diffacult(not impossible) to determine the number of calls that will be made. But my task was to count the nmber of references to a method not the number of actual calls.

Well if someone else posts an actual working solution I will accept that. But for now my solution is the only one available.
Sergey Alexandrovich Kryukov 1-Jul-12 1:53am    
To predict number of calls is stricly impossible. Do you want an idea of the proof? As to the number of call statements in the code... you should have explained it in the very beginning. I demonstrated that this "solution" does not work. Do you want to argue against that?

You see, making a solution "only one available" does not make it correct. And it does not justify accepting it formally. Why not saying the truth instead of maneuvering? In relation to your requirement to count those call statement (which you call "references"), the statement "only one solution available" is not true. And "not true" means "lie". There are no solutions presented, no one. (As to my answer, it is not a solution of your problem, but it is based on your original post and my claims remain true -- the problem as you formulated it in first place is not solvable).

If you want to argue against the fact... well, I would not advise doing so. Either proof your point or admit it...

--SA
Nathan Stiles 1-Jul-12 11:18am    
It's not strictly impossible. It becomes quite a heated philosophical debate. But I take the stance that nothing, especially in programming is impossible. Can one write a program to check if another program will ever return?

Just to clarify. If you reread the original question. It's quite clear. There are no dynamic calls, loops, conditional measures, or anything. It's just one method called several times within another method.
Sergey Alexandrovich Kryukov 1-Jul-12 15:25pm    
No, this is pure mathematics. Please see my update in my answer.
And admit it: even at this time, your question asks about number of calls.
The notion that "nothing is impossible" is just wishful thinking, pretty silly and naive. No matter what "stance" would you take.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900