如何将Microsoft.CodeAnalysis.ITypeSymbol与System.Type进行比较

我使用以下命令从SyntaxNode成功收到了ITypeSymbol:

SemanticModel.GetTypeInfo(sytaxNode).ConvertedType 

现在我想知道这个ITypeSymbol对应于我的执行代码中存在的System.Type实例,如typeof(IEnumerable)someObject.GetType()

我试过了

 typeInfo.ConvertedType.ToString() == type.ToString() 

但是这些不使用相同的格式规则,例如对于像IEnumerable这样的generics

TypeInfo.ToString() == "System.Collections.Generic.IEnumerable"

 typeof(IEnumerable).ToString() == "System.Collections.Generic.IEnumerable`1[System.Int32]" 

此外,我认为最好比较AssemblyQualifiedNames而不仅仅是命名空间和类型名称,以避免可能的名称冲突。

理想情况下,我希望能够在我的执行代码中获得与我从语义模型中获得的ITypeInfo相对应的实际System.Type实例(假设所需的程序集已加载和/或可用)。 这将允许检查类型是否可以从其他类型等分配。

您可以使用Compilation.GetTypeByMetadataName()获取类型名称的INamedTypeSymbol

所以试试这个:

 semanticModel.GetTypeInfo(sytaxNode).ConvertedType.Equals( semanticModel.Compilation.GetTypeByMetadataName(typeof(WhateverType).FullName)) 

这不适用于封闭的generics类型,对于那些你需要做更多的事情。 例如:

 var ienumerableType = semanticModel.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1"); var intType = semanticModel.Compilation.GetTypeByMetadataName("System.Int32"); var type = ienumerableType.Construct(intType); 

基于@Tamas的答案,我创建了以下递归解决方案,适用于封闭的generics类型。

  static bool TypeSymbolMatchesType(ITypeSymbol typeSymbol, Type type, SemanticModel semanticModel) { return GetTypeSymbolForType(type, semanticModel).Equals(typeSymbol); } static INamedTypeSymbol GetTypeSymbolForType(Type type, SemanticModel semanticModel) { if (!type.IsConstructedGenericType) { return semanticModel.Compilation.GetTypeByMetadataName(type.FullName); } // get all typeInfo's for the Type arguments var typeArgumentsTypeInfos = type.GenericTypeArguments.Select(a => GetTypeSymbolForType(a, semanticModel)); var openType = type.GetGenericTypeDefinition(); var typeSymbol = semanticModel.Compilation.GetTypeByMetadataName(openType.FullName); return typeSymbol.Construct(typeArgumentsTypeInfos.ToArray()); }