Reputation: 295
Is it possible to compute the hash of a class at runtime in C# (presumably through reflection)? To be clear, I don't want to compute the hashcode of an instance of said class, I want to compute the hash of the class code itself (if a function in the class changes, I'd expect a different hash code to be computed). Ideally this would only be sensitive to changes in the object code (and not just a hash of the string representation of the code itself).
Thanks in advance for your help,
-- Breck
Upvotes: 9
Views: 1789
Reputation: 1965
I know this question is old, but I wanted to share my HashClassCalculator
that gives an hash of the code of all methods and properties. So, if anything change in those, the hash will change.
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;
}
}
Upvotes: 0
Reputation: 16032
You don't need to use reflection. You can try System.Type.GetHashCode()
. I'm not sure how it works, if not optimal, than you can always use type.FullName.GetHashCode()
Upvotes: -1
Reputation: 116421
If you have the Type
you can use GetMethod
to get an instance of MethodInfo
, which in turn has a GetMethodBody
that returns the IL for said method. You can then hash that.
I am curious. Why do you want to do this in the first place?
Upvotes: 11