从GUID获取类型

Tam*_*ege 12 .net c# reflection types

由于各种原因,我需要在C#中实现类型缓存机制.幸运的是,CLR提供Type.GUID了唯一标识类型.不幸的是,我找不到任何方法来查找基于此GUID的类型.有Type.GetTypeFromCLSID(),但根据我的文档(和实验)的理解是,做了非常,非常不同.

是否有任何方法可以获得基于其GUID的类型,而不是循环遍历所有已加载的类型并与其GUID进行比较?

编辑:我忘了提到我真的很喜欢固定宽度的"类型指纹",这就是为什么GUID对我这么有吸引力.当然,在一般情况下,该类型的完全限定名称可以使用.

Rem*_*anu 7

为什么不使用指定的财产,即.AssemblyQualifiedName?此属性记录为"可以持久化并稍后用于加载类型".

GUID用于COM互操作.

  • Anon:不会发生:)在世界上所有计算机一起创建2 ^ 128种类型之前,宇宙将崩溃. (5认同)
  • @Doc:如果您创建超过2 ^ 128种类型怎么办? (2认同)
  • Remus Rusanu:我真的不想讨论细节,因为它们确实超出了范围,但我有很好的理由使用我所做的数据结构,而且我通常知道我在做什么(至少我会我喜欢这样认为)。开发时间是这里的次要问题。我很想谈论它,因为它确实很有趣,但不幸的是,我认为这个问题不是这样做的合适媒介。不过,谢谢您的建议,一般来说,您是对的,现成的东西在大多数情况下是最有用的。 (2认同)

Joe*_*ger 5

这可能只是已经发布的答案的摘要,但我认为如果不首先构建 Guid->Type 的映射,就没有办法做到这一点。

我们在初始化框架中这样做:

static TypeManager()
    {
        AppDomain.CurrentDomain.AssemblyLoad += (s, e) =>
        {
            _ScanAssembly(e.LoadedAssembly);
        };

        foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
        {
            _ScanAssembly(a);
        }
    }

    private static void _ScanAssembly(Assembly a)
    {
        foreach (Type t in a.GetTypes())
        {
           //optional check to filter types (by interface or attribute, etc.)
           //Add type to type map   
        }
    }
Run Code Online (Sandbox Code Playgroud)

处理 AssemblyLoad 事件负责处理动态加载的程序集。

据我了解,Type.GUID 使用类型的程序集版本作为 Guid 生成算法的一部分。如果您增加程序集版本号,这可能会导致麻烦。根据您的应用程序,使用另一个答案中描述的 GetDeterministicGuid 方法可能是可取的。


Pet*_*one 4

不要循环比较。填充 aDictionary<Type>并使用该Contains方法。

Dictionary<Type> types = new Dictionary<Types>();
... //populate 

if (types.Contains(someObject.GetType())) 
  //do something
Run Code Online (Sandbox Code Playgroud)

这肯定会给你一个固定大小的条目,因为它们都是对象引用(Type 的实例本质上是工厂对象)。