【发布时间】:2016-09-08 06:19:36
【问题描述】:
我想获取任何对象并获取代表该对象的 guid。
我知道这需要很多东西。我正在为常见应用寻找足够好的解决方案。
我的具体用例是缓存,我想知道用于创建我正在缓存的东西的对象在过去已经做了一个。将有 2 种不同类型的对象。每种类型只包含公共属性,并且可能包含一个列表/ienumable。
假设对象可以序列化,我的第一个想法是将其序列化为 json(通过本机 jsonserlizer 或 newtonsoft),然后获取 json 字符串并将其转换为 uuid 版本 5,详见此处的要点 How can I generate a GUID for a string?
如果它不可序列化(例如包含字典),我的第二种方法是使用公共属性上的反射来生成某种唯一字符串,然后将其转换为 uuid 版本 5。
这两种方法都使用 uuid 版本 5 将字符串转换为 guid。是否有经过验证的 c# 类可以生成有效的 uuid 5 guid?要点看起来不错,但要确定。
我正在考虑将 c# 命名空间和类型名称作为 uuid 5 的命名空间。这是对命名空间的有效使用吗?
我的第一种方法对于我的简单用例来说已经足够了,但我想探索第二种方法,因为它更灵活。
如果创建 guid 不能保证合理的唯一性,它应该会引发错误。超级复杂的物体肯定会失败。如果使用反射,我怎么知道是这种情况?
我正在寻找第二种方法的新方法或关注点/实施。
编辑:我在将近 3 年后赏金/重新打开它的原因是因为我再次需要它(并且再次缓存);也是因为在 c# 7.3 中引入了通用的非托管约束。 http://devblogs.microsoft.com/premier-developer/dissecting-new-generics-constraints-in-c-7-3/ 的博客文章似乎暗示,如果对象可以遵守非托管规范,您可以为键值存储找到合适的键。我是不是误会了什么?
这仍然是有限的,因为对象(泛型)必须遵守非常有限的非托管类型约束(没有字符串、没有数组等),但它更接近了一步。我不完全明白为什么获取内存流和获取 sha1 哈希的方法不能在非托管类型上完成。
我知道引用类型指向内存中的位置,并且获得代表所有整个对象的内存并不容易;但感觉可行。毕竟,对象最终是由一堆非托管类型的实现组成的(字符串是一个数组字符等)
PS: GUID 的要求很宽松,任何512位或以下的整数/字符串都可以
【问题讨论】:
-
你的意思是所谓的hash。例如,您可以使用 MD5。
-
你不是在找
GetHashCode吗? msdn.microsoft.com/en-us/library/… -
@tomas 哈希码不能保证是唯一的,只是希望没有冲突。它们也特定于该对象类型
-
@ParoX 好吧,谈论 any object 并为任何对象获取 unique id - 任何对象都是 unlimited 一堆对象,您将用一个限制为 16 个字节的 guid 表示无冲突的对象,因此具有 limited 唯一值(按设计)。你看到核心问题了吗?
-
这听起来像是一个 XY 问题meta.stackexchange.com/questions/66377/what-is-the-xy-problem 例如,您将如何区分
new object()和new object()?除了散列整个 XML 之外,您将如何在两个大的 XmlDocument 之间产生差异(性能任何人?)?没有适用于任何对象的灵丹妙药。注意 GetHashCode 不是“用于哈希表”,而是用于(不)相等比较。如果两个对象 GetHashCode() 不同,则对象不同(反之不成立)。确实不能解决你的问题。