2025/03/27

Using C# Reflection to Get Public Method Call Count

用法:

    class Program
    {
        public static void SampleMethod()
        {
            Console.WriteLine("Hello World!");
            AnotherMethod();
        }

        public static void AnotherMethod()
        {
            Console.WriteLine("This is another method.");
        }

        static void Main(string[] args)
        {
            // 取得 SampleMethod 的 MethodInfo
            MethodInfo sampleMethodInfo = typeof(Program).GetMethod("SampleMethod");
            // 分析方法內的呼叫次數
            int callCount = MethodUtils.AnalyzeMethodCalls(sampleMethodInfo);
            Console.WriteLine($"SampleMethod has {callCount} method calls inside it.");
        }
    }

using System.Reflection;

namespace test
{
    /// 
    /// Method Utils
    /// 
    public static class MethodUtils
    {
        /// 
        /// 透過 Reflection 分析方法內部呼叫的數量
        /// 僅能分析public方法
        /// 
        /// MethodInfo 物件
        /// 方法內部呼叫的數量
        public static int AnalyzeMethodCalls(MethodInfo methodInfo)
        {
            // 方法呼叫次數
            int methodCallCount = 0;
            // 如果 MethodInfo 為空,則回傳方法呼叫次數
            if (methodInfo == null)
            {
                return methodCallCount;
            }

            // 取得方法的 IL 代碼
            var methodBody = methodInfo.GetMethodBody();
            // 如果方法的 IL 代碼為空,則回傳方法呼叫次數
            if (methodBody == null)
            {
                return methodCallCount;
            }

            // 取得 IL 代碼的位元組陣列
            var ilBytes = methodBody.GetILAsByteArray();
            // 如果 IL 代碼為空,則回傳方法呼叫次數
            if (ilBytes == null)
            {
                return methodCallCount;
            }

            // 查找 IL 代碼中的 Call 指令 (0x28)
            for (int i = 0; i < ilBytes.Length; i++)
            {
                // 0x28 Call 指令 (普通方法呼叫)
                if (ilBytes[i] == 0x28)
                {
                    // 增加呼叫計數
                    methodCallCount++;
                }
            }

            return methodCallCount;
        }
    }
}

參考資料:https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes?view=net-6.0