根据通用对象内容

时间:2017-12-10 17:51:58

标签: c# generics reflection

故事

我尝试编写一个泛型方法,它结合了属性名称,类型和内容值,以生成唯一字符串 值保持< / strong>由对象传递。

我们的想法是根据生成的字符串序列生成唯一的SHA3-512哈希可用于比较通用基础上的对象他们的内容

实施例

我们说我们有这样的课程......

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

...以及提到的生成唯一字符串的方法

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

从理论上讲,这应该有点像

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

问题

我在构建GetContentString方法时遇到了困难。 这就是我已经

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();

我尝试为"some string"1234 (Int32)等几种不同类型的值运行该方法,但遇到了一些问题。

给定一个字符串,方法调用会抛出类型为System.Reflection.TargetParameterCountException的异常,并在Parameter count mismatch处抛出消息#1。我发现可选索引可以传递给pi.GetValue(..)的重载版本,然后返回单个字母之一。 但是你怎么知道什么时候停止?如果你调用一个不存在的索引,它会抛出System.Reflection.TargetInvocationException类型的异常。 如何使用反射获取字符串对象的值?

给定一个整数值,方法调用在#2找不到任何属性。这提出了如何使用反射获取整数对象的值的问题?

还有一些一般性问题; 你们认为这是获得独特字符串的好方法吗?是反思的方式去这里?是否可以为此问题编写通用解决方案

1 个答案:

答案 0 :(得分:1)

不看反射,如果使用.net框架能够进行JSON序列化怎么样? 反思不是非常快,你会在第一个未处理的例外情况下遇到问题。

然后,如果你的对象可以包含复杂的属性,那么你应该以递归的方式做到这一点,这对于json序列化来说不是问题!