Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# .NET reflection
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.
 
class MyClass
{
    void methodA()
    {
        methodB();
        methodB();
    }
    void methodB()
    {
    }
}
Posted 16-Jan-12 8:13am
Edited 16-Jan-12 9:01am
Comments
SAKryukov at 16-Jan-12 13:15pm
   
Static or instance method?
--SA
Nathan Stiles at 16-Jan-12 13:23pm
   
SAKryukov it could be either as far as I'm concerned.
Nathan Stiles at 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.
SAKryukov at 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 at 29-Jun-12 23:16pm
   
See solution...
Sergey Alexandrovich Kryukov at 30-Jun-12 13:33pm
   
Aha. Did you write it by yourself?
If you did, I take my words back with my pleasure. Impressive.
 
Well, even though the code does not work as you require. As I say, it is not possible to count the number of calls in general case. Please see my comments to your solution.
 
Cheers,
--SA
Nathan Stiles at 1-Jul-12 11:19am
   
Yes I did write this. Thank you.
Sergey Alexandrovich Kryukov at 2-Jul-12 3:51am
   
Very good! Now you can bring to a complete solution to eliminate the flaw I pointed out. I think this would not be too hard, compared to what is already done.
--SA
BillWoodruff at 16-Jan-12 13:35pm
   
"the number of calls will not change at runtime." Confusing: to say: "I wanted to know before executing methodA" implies at runtime !
 
What you say implies, to me, that you can know exactly at design-time precisely how many times MethodB references exist: unless you are in a very strange situation ... which I cannot even imagine ... where somehow you do not have access to some design-time code being generated by some ? that defines additional references to MethodB.
Nathan Stiles at 16-Jan-12 13:39pm
   
Sorry to confuse you. The goal is to find a count of references to methodB. Basically the same count you would get from using find all references.
SAKryukov at 16-Jan-12 14:06pm
   
Yes, this is confusing. I actually answered to what OP means, in the second paragraph of my answer, please see.
In my comment (see above), I explained why I don't want to get into further detail.
--SA
Nathan Stiles at 1-Jul-12 11:21am
   
Yes I do know at design time how many calls exist. But that does not lighten the load, they still need to be counted manually.
BillWoodruff at 1-Jul-12 16:16pm
   
Hi Nathan, is there a way you could come up with a "thought experiment" here that will illustrate the difference between counting the number of references to a method in source code ...
 
... and: whatever actual scenario you are dealing with here: a concrete example to help us help you ?
 
Are you talking about the number of calls to a given method, from anywhere in some arbitrarily complex application composed of any number of classes which may be static, or: non-static classes made instances once at the program's start ... or: non-static classes, with instances created any possible number of times during the program's use ?
 
Imagine I write a program to calculate a fixed number of integers in the Fibonacci program: yes, then I can easily know exactly how many times the method to compute the next number is called: but that's not the way programs are written, and that is a fool's example whose only purpose is not to "mock you," but to try and get you to clarify what you are speaking of.
 
What happens when you have a public method in a static class that may be called by any number of libraries which are added as references (compiled as .dll's) to your project ?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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. Smile | :)
 
—SA
  Permalink  
v3
Comments
BillWoodruff at 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 at 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 at 1-Jul-12 14:09pm
   
[Misplaced, to be removed -- SA]
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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()
            {
            }
 
        }
    }
}
  Permalink  
v3
Comments
Sergey Alexandrovich Kryukov at 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 at 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 at 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 at 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 at 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
BillWoodruff at 1-Jul-12 11:43am
   
+3 for being an interesting approach to study your issue, I believe: honestly, haven't had time to analyze it yet, compile, examine the code, but looks worth the effort.
 
thanks, Bill

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



Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 1 Jul 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100