Our application makes use of serialized snapshots of state which is just a serialized version of the class at a point in time.
We have a version number on the class which we increment each time the class is modified which we use to indicate that the previous snapshots are invalid and to ignore them.
Occasionally someone forgets to increment the version and we get errors.
I'd like to generate a hash for the structure of the class and use that to store snapshots, so if it ever changes then the previous snapshots would automatically invalidated.
I've though about using Roslyn to load a representation of the class and call GetHashCode on that but can't work out how to load an existing class into Roslyn.
Also I've looked into Visual Studio generating hashes at build time: https://learn.microsoft.com/en-us/archive/msdn-magazine/2017/march/visual-studio-hashing-source-code-files-with-visual-studio-to-assure-file-integrity but this seems like overkill.
So how do I generate a hash of an existing C# class structure (not an instance of a class)?
Update:
This is a POCO with no methods. Changes that invalidate snapshot include adding, removing or renaming properties.
I would suggest using reflection to get that.
Something along the lines of:
private int GetHashOfClass(Type myType)
{
int hash = 0;
foreach (var f in myType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic))
{
if (f.MemberType == MemberTypes.Field ||
(f.MemberType & MemberTypes.Property) != 0)
{
hash ^= CreateHash(f.Name);
}
if (f is FieldInfo fi)
{
hash ^= CreateHash(fi.FieldType.Name);
}
}
return hash;
}
That generates a hashcode from the fields and properties of a class. CreateHash
is just a function that generates a hash from a string. Do not use the existing string.GetHashCode
, because the result of that function will change each time the application is started.