如何在.net中获取方法体的哈希值?

Woo*_*Bob 2 .net c#

我想生成一个方法体或整个类的哈希值,以便将它与之前的哈希值进行比较,从而检测运行时的更改.

我已经看到使用Mono.Cecil在Mono中实现了这一点.

是否可以在Microsoft.NET中执行此操作?如果是这样的话?

或者您使用了哪些其他方法?

背景

我想将我的实体的投影创建为只读的非规范化数据库 - 如果你愿意的话,这是一种本地缓存.

只要实体发生了变化,就会执行执行此操作的转换算法.然后它将采用相关实体并生成投影.但是,在启动时或作为部署的一部分,我想检查转换算法是否已更改,如果是,请删除并重新生成表,然后使用主存储中的所有实体重新填充它.

我已经在Event Source/CQRS博客中看到了这种方法,但如果您有替代/更好的方法来满足此要求,请随时发表评论.

基于Jon Skeet的答案的不完整解决方案

以下LinqPad C#程序试图实现此目的:

void Main()
{
    GetMethodHash(this.GetType(), "DoOriginal").Dump();
    GetMethodHash(this.GetType(), "DoSame").Dump();
    GetMethodHash(this.GetType(), "DoWithConstChange").Dump();
    GetMethodHash(this.GetType(), "DoWithCodeChange").Dump();
}

// Define other methods and classes here

private string DoOriginal(int data)
{
    return string.Format("data = {0}", data);
}

private string DoSame(int data)
{
    return string.Format("data = {0}", data);
}

private string DoWithConstChange(int data)
{
    return string.Format("data : {0}", data);
}

private string DoWithCodeChange(int data)
{
    return string.Format("data = {0} {1}", data, 999);
}

private string GetMethodHash(Type type, string methodName)
{
    var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance );
    var body = method.GetMethodBody();
    var il = body.GetILAsByteArray();

    using (var sha256 = System.Security.Cryptography.SHA256.Create())
    {
        byte[] hash = sha256.ComputeHash(il);
        string hashBase64 = Convert.ToBase64String(hash);
        return string.Format("{0}{1}", methodName.PadRight(20), hashBase64);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

DoOriginal          +PyMqwv5PVz7/7EnNL9A676XNw/g8x2KfEUa63wD9oU=
DoSame              +PyMqwv5PVz7/7EnNL9A676XNw/g8x2KfEUa63wD9oU=
DoWithConstChange   VZX2CkxwUHzJVt8Tn73jmL1I5dKYUFKyD9bPwPsItVk=
DoWithCodeChange    9kZkq0fDHUXqxOmclwso/r2pQLDyNVwTtkIppSkcdQg=
Run Code Online (Sandbox Code Playgroud)

我对它的第一次调查似乎在DoOriginal和DoWithConstChange之间产生了相同的哈希......但那是在午餐之前,现在它看起来还不错.所以无论是奇怪的事情还是我需要休息 - 我投票给后者.

接下来将添加引用的代码和结构.有什么建议?

Jon*_*eet 8

您可以使用MethodInfo.GetMethodBody()获取a MethodBody,然后使用您想要的任何类型的哈希(例如SHA-256)基于您喜欢的任何内容(例如IL字节数组)创建哈希.

当然,IL可能在没有源代码更改的情况下进行更改(例如,由于更改编译器) - 反之亦然(例如,如果局部变量名称已更改但在优化的IL中不存在).