简体   繁体   English

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

[英]How to compare a Microsoft.CodeAnalysis.ITypeSymbol to a System.Type

I have successfully received an ITypeSymbol from a SyntaxNode by using: 我使用以下命令从SyntaxNode成功收到了ITypeSymbol:

SemanticModel.GetTypeInfo(sytaxNode).ConvertedType

Now I would like to know if this ITypeSymbol corresponds to a System.Type instance that is present in my executing code, like typeof(IEnumerable<int>) or someObject.GetType() . 现在我想知道这个ITypeSymbol对应于我的执行代码中存在的System.Type实例,如typeof(IEnumerable<int>)someObject.GetType()

I tried 我试过了

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

But these do not use the same formatting rules, for instance for generics like IEnumerable<int> 但是这些不使用相同的格式规则,例如对于像IEnumerable<int>这样的泛型

TypeInfo.ToString() == "System.Collections.Generic.IEnumerable<int>"

while

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

Moreover I think it would be better to compare AssemblyQualifiedNames in stead of just the Namespace and type name to avoid possible name clashes. 此外,我认为最好比较AssemblyQualifiedNames而不仅仅是命名空间和类型名称,以避免可能的名称冲突。

Ideally I would like to be able to get the actual System.Type instance in my executing code that corresponds to the ITypeInfo I got from the semantic model (provided that the required assembly is loaded and/or available). 理想情况下,我希望能够在我的执行代码中获得与我从语义模型中获得的ITypeInfo相对应的实际System.Type实例(假设所需的程序集已加载和/或可用)。 That would allow checking if the type is assignable from some other type etc. 这将允许检查类型是否可以从其他类型等分配。

You can get the INamedTypeSymbol for a type name with Compilation.GetTypeByMetadataName() . 您可以使用Compilation.GetTypeByMetadataName()获取类型名称的INamedTypeSymbol

So try this: 试试这个:

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

This won't work with closed generic types, for those you'll need to do a bit more. 这不适用于封闭的泛型类型,对于那些你需要做更多的事情。 For example: 例如:

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

Based on the answer from @Tamas, I created the following recursive solution that works for closed generic types. 基于@Tamas的答案,我创建了以下递归解决方案,适用于封闭的泛型类型。

    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<ITypeSymbol>());
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM