如何检测异步方法主体中的源代码更改 [英] How to detect source code changes in async method body

查看:97
本文介绍了如何检测异步方法主体中的源代码更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在运行时检测类方法的源代码是否已更改.基本上,我检索方法主体(IL),使用md5对其进行哈希处理并将其存储在数据库中.下次我检查方法时,可以比较哈希值.

I'm trying to detect during runtime if the source code of a method of a class has been changed. Basically I retrieve the method body (IL), hash it with md5 and store it in the database. Next time I check the method, I can compare the hashes.

public class Changed
{
    public string SomeValue { get; set; }

    public string GetSomeValue()
    {
        return SomeValue + "add something";
    }

    public async Task<string> GetSomeValueAsync()
    {
        return await Task.FromResult(SomeValue + "add something");
    }
}

我正在使用Mono.Cecil检索方法主体:

I'm using Mono.Cecil to retrieve the method bodies:

var module = ModuleDefinition.ReadModule("MethodBodyChangeDetector.exe");

var typeDefinition = module.Types.First(t => t.FullName == typeof(Changed).FullName);

// Retrieve all method bodies (IL instructions as string)
var methodInstructions = typeDefinition.Methods
    .Where(m => m.HasBody)
    .SelectMany(x => x.Body.Instructions)
    .Select(i => i.ToString());

var hash = Md5(string.Join("", methodInstructions));

这很好用,除了标记为异步的方法.每当我向SomeValue方法添加一些代码时,哈希值都会更改.每当我向GetSomeValueAsync方法添加一些代码时,哈希值都不会更改.有谁知道如何检测异步方法的方法主体是否已更改?

This works great, except for methods marked as async. Whenever I add some code to the SomeValue method, the hash changes. Whenever I add some code to GetSomeValueAsync method, the hash does not change. Does anyone know how to detect if the method body of an async method has changed?

推荐答案

感谢@xanatos和@Wormbo的帮助,我找到了解决方案.

I've found a solution, thanks to @xanatos and @Wormbo who put me in the right direction.

对于异步方法,C#编译器会生成一个包含方法主体的帮助程序类.这些帮助程序类可以在主类型的NestedTypes属性中找到.因此,如果我们包含嵌套类型的方法主体,则可以创建正确的哈希值:

In the case of an async method, the C# compiler generates a helper class which contain the method body. These helper classes can be found in the NestedTypes property of the main type. So, if we include the method bodies of the nested types, we can create the correct hash:

var module = ModuleDefinition.ReadModule("MethodBodyChangeDetector.exe");

var typeDefinition = module.Types.First(t => t.FullName == typeof(Changed).FullName);

// Retrieve all method bodies (IL instructions as string)
var methodInstructions = typeDefinition.Methods
    .Where(m => m.HasBody)
    .SelectMany(x => x.Body.Instructions)
    .Select(i => i.ToString());

var nestedMethodInstructions = typeDefinition.NestedTypes
    .SelectMany(x=>x.Methods)
    .Where(m => m.HasBody)
    .SelectMany(x => x.Body.Instructions)
    .Select(i => i.ToString());


Md5(string.Join("", methodInstructions) + string.Join("", nestedMethodInstructions));

这篇关于如何检测异步方法主体中的源代码更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆