dimanche 10 décembre 2017

generate predictable unique string based on a generic objects content

Story

I'm trying to write a generic method which combines property names, types and content value to generate a unique string for the value held by the object passed.

The idea is to generate a unique SHA3-512 Hash based on the generated string sequence which can be used to compare objects on generic bases by looking at their content.


Example

Let's say we have a class like this ...

class MyClass {
    private Int32 Id = 5;
    public String Name = "some string";
    protected DateTime CreateDate = DateTime.Parse("2017-08-21 15:00:07");
}

... and the mentioned method to generate the unique string

static String GetContentString<T>(T obj) where T : class {
  ...
}

In theory this should work somewhat like this:

var myObj = new MyClass();
var uniqueContentString = GetContentString(myObj);

Console.WriteLine(uniqueContentString);
>>> Id:Int32:5$Name:String:some string$CreateDate:DateTime:2017-08-21 15:00:07


Problem

I'm having difficulties building the GetContentString Method. This is what I have already:

Object obj = ... // given object
Type type = obj.GetType();
IList<PropertyInfo> propertyInfos = type.GetProperties().Where(x => x.CanRead).ToList(); // Marker #2

StringBuilder sb = new StringBuilder();
foreach (PropertyInfo pi in propertyInfos)
{
    sb.Append(pi.Name);
    sb.Append(":");
    sb.Append(pi.PropertyType.Name);
    sb.Append(":");
    sb.Append(pi.GetValue(obj) ?? "[ISNULL]"); // Marker #1
    sb.Append(":");
}

return sb.ToString();

I tried running the method for a few different types of values like "some string" or 1234 (Int32) and ran into a few issues.

Given a string, the method call throws an exception of type System.Reflection.TargetParameterCountException and the message Parameter count mismatch at #1. I found out that an optional index can be passed to an overloaded version of pi.GetValue(..) which then returns one of the single letters. But how do you know when to stop? If you call an index which doesn't exist it throwns an exception of the type System.Reflection.TargetInvocationException. How do you get the value of a string object using reflection?

Given an integer value, the method call doesn't find any properties at #2. Which brings up the question of how to get the value of an integer object using reflection?

And also some general questions; do you guys think this is a good approach to get a unique string? Is reflection the way to go here? Is it even possible to write a generic solution to this problem?





Aucun commentaire:

Enregistrer un commentaire