在C#中是否有可能在运行时计算类的哈希值(可能是通过反射实现)?要明确的是,我不想计算所述类的实例的哈希码,我想计算类代码本身的哈希值(如果类中的函数发生变化,则期望计算出不同的哈希值)。理想情况下,这只会对对象代码的更改敏感(而不仅仅是代码本身的字符串表示的哈希值)。
感谢您的帮助,
-- Breck
感谢您的帮助,
-- Breck
Type
,则可以使用 GetMethod
获取 MethodInfo
实例,该实例具有 GetMethodBody
,返回所述方法的 IL。然后,您可以对其进行哈希处理。我知道这个问题很老了,但我想分享一下我的HashClassCalculator
,它可以给出所有方法和属性代码的哈希值。因此,如果这些内容发生任何变化,哈希值也会改变。
internal static class HashClassCalculator
{
private static Dictionary<Type, string> hashes = new ();
private static object lockingObject = new ();
/// <summary>
/// Calculate an hash of the code for a specific type
/// </summary>
/// <param name="type">Type to hash the code</param>
/// <returns>MD5 hash of the class code</returns>
/// <remarks>Thread protected + Cached for faster access</remarks>
public static string CalculateHash(Type type)
{
if (hashes.ContainsKey(type)) return hashes[type]; // Fast return
var currentHash = "";
lock (lockingObject)
{
if (hashes.ContainsKey(type)) return hashes[type]; // Fast return
var allFlag = System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.Static;
var hasher = MD5.Create();
// Get all properties hashes
var props = type.GetProperties(allFlag);
foreach (var prop in props)
{
var hashBytes = hasher.ComputeHash(prop.GetMethod.GetMethodBody().GetILAsByteArray());
currentHash += Convert.ToBase64String(hashBytes); // Concatenate all the hashes
}
// Get all methods hashes
var methods = type.GetMethods(allFlag);
foreach (var method in methods)
{
if (method.DeclaringType != type) continue;
var hashBytes = hasher.ComputeHash(method.GetMethodBody().GetILAsByteArray());
currentHash += Convert.ToBase64String(hashBytes); // Concatenate all the hashes
}
// Hashing all hashes into one smaller
var hashOfHashes = hasher.ComputeHash(Encoding.ASCII.GetBytes(currentHash));
currentHash = Convert.ToBase64String(hashOfHashes);
// Add to cache
hashes.Add(type, currentHash);
}
return currentHash;
}
}
System.Type.GetHashCode()
。我不确定它是如何工作的,如果不够优化,那么你可以随时使用type.FullName.GetHashCode()
。