C# 快速散列对象的方法集中在包含特定属性的属性上?
我已经创建了自己的序列化形式,它将提供的对象转换为字符串,然后我可以得到一个MD5哈希值。散列用于快速比较,以查看特定属性是否已更改。然而,我的代码非常慢,我想知道是否有人有更好的想法 我只需要担心用自定义[DatabaseMap]属性标记的对象中的属性。我不太关心散列方法,而是关心对象在散列之前的序列化方式 有更好的方法吗C# 快速散列对象的方法集中在包含特定属性的属性上?,c#,serialization,hash,md5,C#,Serialization,Hash,Md5,我已经创建了自己的序列化形式,它将提供的对象转换为字符串,然后我可以得到一个MD5哈希值。散列用于快速比较,以查看特定属性是否已更改。然而,我的代码非常慢,我想知道是否有人有更好的想法 我只需要担心用自定义[DatabaseMap]属性标记的对象中的属性。我不太关心散列方法,而是关心对象在散列之前的序列化方式 有更好的方法吗 public static string GetHash(this IBaseObject source) { if (source ==
public static string GetHash(this IBaseObject source)
{
if (source == null)
return string.Empty;
// step 1, calculate MD5 hash from input
var hasher = new ThreadLocal<MD5>(MD5.Create);
byte[] inputBytes = Encoding.UTF8.GetBytes(SerializeDataMembers(source, hasher)); // serialize the object
byte[] hash = hasher.Value.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < hash.Length; i++)
// {
// sb.Append(hash[i].ToString("X2"));
// }
// return sb.ToString();
return BitConverter.ToString(hash);
}
private static string SerializeDataMembers(IBaseObject source, MD5 hasher)
{
StringBuilder sb = new StringBuilder();
var properties = source.GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
var attrs = Attribute.GetCustomAttributes(prop);
if (attrs.OfType<DatabaseMap>().Any())
{
if (prop.PropertyType == typeof (byte[]))
{
sb.Append(Convert.ToBase64String(hasher.ComputeHash((byte[])prop.GetValue(source))));
}
else
{
sb.Append(prop.GetValue(source));
}
}
}
return sb.ToString();
}
public静态字符串GetHash(此IBaseObject源)
{
if(source==null)
返回字符串。空;
//步骤1,从输入计算MD5散列
var hasher=newthreadlocal(MD5.Create);
byte[]inputBytes=Encoding.UTF8.GetBytes(SerializeDataMembers(source,hasher));//序列化对象
byte[]hash=hasher.Value.ComputeHash(inputBytes);
//步骤2,将字节数组转换为十六进制字符串
//StringBuilder sb=新的StringBuilder();
//for(int i=0;i
这个图案给了我一个想法。我完全删除了任何散列,对于我关心的特定属性属性,在它们的setter中,我比较它们的旧值到新值是否有任何变化,如果有,我增加一个计数器。速度是难以置信的快,没有散列
private void CompareChange<T>(T old, T newValue)
{
if (!EqualityComparer<T>.Default.Equals(old, newValue))
Interlocked.Increment(ref _ChangeCount);
}
private void CompareChange(T旧,T新值)
{
如果(!EqualityComparer.Default.Equals(旧值、新值))
联锁增量(参考变更计数);
}
既然可以,为什么还要经历MD5比较对象的所有麻烦呢?我需要一种快速的方法来散列一个对象,然后再生成一个散列,看看是否有任何标记有特定属性的属性被更改了。我最初使用ServiceStack.Text序列化了对象,但是这序列化了整个对象,而我只关心某些属性。然后我提出了上面的解决方案,但我相信有更快的方法。散列方法不是问题所在。我认为正确的做法是为接口实现一个可获取属性的方法。但我不会比较两个对象。用例是当对象被初始化时,我对其进行散列-稍后当有人想要将对象提交到数据存储时,会创建另一个散列(在同一对象上),然后与原始散列进行比较。如果这些散列不同,则会发生提交,否则由于没有进行任何更改而不会发生任何事情。