C# 代码编译时方法中的函数执行计数

C# 代码编译时方法中的函数执行计数,c#,reflection,C#,Reflection,我想计算函数“ExecuteAction”在类方法中出现的次数 public class A : B { public void X() { ExecuteAction(....); ExecuteAction(....); } } 分数是2,因为执行出现2x。我之所以需要它,是因为我构建了测试框架,并且希望外部测试操作员能够知道当前步骤执行的位置和结束的位置。我是否有可能改变我的方法 多谢各位 为什么不编写一个脚本来计算函数在源代码中出现的次数?大致如下: sta

我想计算函数“ExecuteAction”在类方法中出现的次数

public class A : B
{
  public void X()
  {
    ExecuteAction(....);
    ExecuteAction(....);
  }
}
分数是2,因为执行出现2x。我之所以需要它,是因为我构建了测试框架,并且希望外部测试操作员能够知道当前步骤执行的位置和结束的位置。我是否有可能改变我的方法


多谢各位

为什么不编写一个脚本来计算函数在源代码中出现的次数?大致如下:

static void Main(string[] args)
    {
        int count = 0;
        using (StreamReader sr = new StreamReader(System.IO.File.OpenRead(@"<filepath>/Program.cs")))
        {
            while (sr.Peek()>0)
            {
                string line = sr.ReadLine();
                if (line.Contains("Function(") 
                    && !(line.Contains("class") || line.Contains("static") || line.Contains("public")))
                {
                    count++;
                }
            }
        }
        Console.WriteLine(count);
        Console.Read();
    }
static void Main(字符串[]args)
{
整数计数=0;
使用(StreamReader sr=newstreamreader(System.IO.File.OpenRead(@/Program.cs)))
{
而(sr.Peek()>0)
{
字符串行=sr.ReadLine();
if(line.Contains)(“函数(”)
&&!(line.Contains(“class”)|| line.Contains(“static”)|| line.Contains(“public”))
{
计数++;
}
}
}
控制台写入线(计数);
Console.Read();
}

下面的方法演示了如何通过反射读取方法体并计算特定方法的所有调用:

class Foo {
    public void SomeMethod() {
        ExecuteAction();
        ExecuteAction();
    }
    public void ExecuteAction() {
        //
    }
}
// --- Read the IL ---
var mInfo = typeof(Foo).GetMethod("SomeMethod");
var token = typeof(Foo).GetMethod("ExecuteAction").MetadataToken;

var methodBody = mInfo.GetMethodBody();
var rawIL = methodBody.GetILAsByteArray();

int counter = 0;
var reader = new ILReader(rawIL);
while(reader.Read(mInfo)) {
    if(reader.OpCode == OpCodes.Call && object.Equals(reader.MetadataToken, token)) {
        System.Console.WriteLine("Method \"{0}\" call detected", reader.Operand);
        counter++;
    }
}
System.Console.WriteLine("Total: {0}", counter);
ILReader
类的实现如下(此特定任务的最小实现):

类读取器{ 只读字节[]msil; int-ptr; 公共ILReader(字节[]msil){ this.msil=msil; } 公共操作码操作码{get;private set;} public int MetadataToken{get;private set;} 公共对象操作数{get;private set;} 公共bool Read(MethodInfo MethodInfo){ 如果(ptr返回(int)b1 |(((int)b2)需要一些反汇编…嗯…我需要一些东西在编译开始之前运行这个脚本,更改源代码以放置“ExecuteAction(…)的计数,然后…编译源代码
class ILReader {
    readonly byte[] msil;
    int ptr;
    public ILReader(byte[] msil) {
        this.msil = msil;
    }
    public OpCode OpCode { get; private set; }
    public int MetadataToken { get; private set; }
    public object Operand { get; private set; }
    public bool Read(MethodInfo methodInfo) {
        if(ptr < msil.Length) {
            OpCode = ReadOpCode();
            Operand = ReadOperand(OpCode, methodInfo);
            return true;
        }
        return false;
    }
    OpCode ReadOpCode() {
        byte instruction = ReadByte();
        if(instruction != 254)
            return singleByteOpCode[instruction];
        else
            return doubleByteOpCode[ReadByte()];
    }
    object ReadOperand(OpCode code, MethodInfo methodInfo) {
        MetadataToken = 0;
        switch(code.OperandType) {
            case OperandType.InlineMethod:
                MetadataToken = ReadInt();
                System.Type[] methodArgs = null;
                if(methodInfo.GetType() != typeof(ConstructorInfo))
                    methodArgs = methodInfo.GetGenericArguments();
                System.Type[] typeArgs = null;
                if(methodInfo.DeclaringType != null)
                    typeArgs = methodInfo.DeclaringType.GetGenericArguments();
                return methodInfo.Module.ResolveMember(MetadataToken, typeArgs, methodArgs);
        }
        return null;
    }
    byte ReadByte() {
        return msil[ptr++];
    }
    int ReadInt() {
        byte b1 = ReadByte();
        byte b2 = ReadByte();
        byte b3 = ReadByte();
        byte b4 = ReadByte();
        return (int)b1 | (((int)b2) << 8) | (((int)b3) << 16) | (((int)b4) << 24);
    }
    #region static
    static ILReader() {
            CreateOpCodes();
        }
    static OpCode[] singleByteOpCode;
    static OpCode[] doubleByteOpCode;
    static void CreateOpCodes() {
        singleByteOpCode = new OpCode[225];
        doubleByteOpCode = new OpCode[31];

        FieldInfo[] fields = GetOpCodeFields();

        for(int i = 0; i < fields.Length; i++) {
            OpCode code = (OpCode)fields[i].GetValue(null);
            if(code.OpCodeType == OpCodeType.Nternal)
                continue;

            if(code.Size == 1)
                singleByteOpCode[code.Value] = code;
            else
                doubleByteOpCode[code.Value & 0xff] = code;
        }
    }
    static FieldInfo[] GetOpCodeFields() {
        return typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static);
    }
    #endregion static
}