Type.GUID能够在不同的编译中唯一标识每种类型吗?

12

可能是重复问题:
自动生成的.NET类型GUID一致吗?

我想将 Type 作为字典的键,但我更愿意使用完整类型名称或 Type.GUIDType.GUID 在这种情况下可靠和正确吗?

Ayende Rahien 写道:

你能依赖 System.Type.GUID 的稳定性吗?

通过“稳定”,我指它会在编译过程中为相同类型生成相同的值。经验证明,一个类型的 GUID 取决于以下因素:

  • 类型名称(包括命名空间)
  • 程序集名称
  • 程序集公钥

反射到系统,发现 System.Type.GUID 最终转换为调用 System.RuntimeType.GetGUID,这是运行时本身直接实现的一种可怕的 InternallCall 方法。

我在想...

5个回答

9
http://msdn.microsoft.com/en-us/library/system.type.guid.aspx的文档中可以了解到,Type.GUID的目的是获取使用[Guid("...")]的类关联的值。但是,即使没有关联这个属性,它也会返回一个guid。问题在于它从哪里获取这个guid。通过一个小测试可以发现,这个guid是稳定的。我检查了一个类的guid,并验证了当我重命名这个类时,它会改变。当我将类名改回时,我又得到了原始的guid。然而,由于这些guid似乎出现得很突然,不能保证它们随着时间、发布、框架版本等的变化而保持稳定。

6
不要使用它。
typeof(byte).GUID
00000000-0000-0000-0000-000000000000

typeof(int).GUID
00000000-0000-0000-0000-000000000000

typeof(short).GUID
00000000-0000-0000-0000-000000000000

ideone.com上进行了测试,它们运行的是Mono 2.8

编辑:在对各种(大型)程序集使用System.Reflection后,我无法找到两个GUID之间的冲突。因此,似乎0-GUID问题是特定于Mono的。


在什么条件下?使用哪个CLR版本?在我的情况下(使用LINQpad的.NET 4),我得到了非零结果,但在程序运行期间会有所不同。 - Ondrej Tucny
我也得到了非零值(.Net 4,简单控制台应用程序)。 - ken2k
为什么我得到了不同的GUID?你是如何得到全零的? - Cheng Chen
3
我想知道为什么会有两个赞成票.. 他们甚至没有进行简单的测试就投票了吗? - Cheng Chen
我需要为当前二进制文件生成一个唯一的ID。我尝试了在Windows上运行良好的GUID,但在Mono上却产生了这些0。虽然这是很久以前的事情,但我记得我通过对应用程序本身进行哈希处理来获取唯一标识符来解决了这个问题。对于我的目的来说,这已经足够好了。 - WHol

2

Type.FullNameType.AssemblyQualifiedName 可以满足你的需求。与 GUID 相比,它将大大简化调试(类型的有意义名称与未知 GUID 相比)。

另一个要点是 GUID 属性好像没有得到很好的文档支持,所以我不会依赖它。

编辑:你也可以使用 Type 实例本身作为键。


无论在何种上下文中使用,Type.FullName和Type.AssemblyQualifiedName都可能为空。 - gimlichael
@gimlichael,你的评论提到了一个重要问题。你有这样的上下文示例吗? - Joshcodes

1

我认为使用Type.GUID作为你的字典键不会出问题。如果GUID不可靠,那么大多数COM组件将无法工作。


1
你能指出一个证实这一点的来源吗? - Oded
@Oded 只要您不坚持认为 GUID 或元数据可能会发生变化,我认为这是可以的。但是,类型存在单个实例,因此可通过引用相等性进行比较,因此更适合作为字典键的候选项。我也很好奇 GUID 生成的内部机制。 - TakeMeAsAGuest

1

你应该动态构建字典,每次查找GUID,或者使用GuidAttribute类静态设置GUID。你不应该依赖于不被保证的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接