Getting the fully qualified name of a type from a TypeInfo object

前端 未结 3 956
栀梦
栀梦 2021-02-12 19:47

Is it somehow possible to get the fully qualified name of the type contained in a TypeInfo object?

In the debugger many of these values nicely show up as

相关标签:
3条回答
  • 2021-02-12 20:03

    The ToDisplayString method lets you pass in a "format" object which has a huge number of options for controlling how you want to format stuff:

    var symbolDisplayFormat = new SymbolDisplayFormat(
        typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
    
    string fullyQualifiedName = typeSymbol.ToDisplayString(symbolDisplayFormat);
    

    The reason your getting keywords like "int" is the default format is including the SymbolDisplayMiscellaneousOptions.UseSpecialTypes flag which specifies to use the language keywords for special types vs. the regular name.

    0 讨论(0)
  • 2021-02-12 20:14

    I couldn't find something built-in either and I'm quite sure this isn't the most elegant way, but it worked for me to construct a qualified type name like this:

    private static string GetQualifiedTypeName(ISymbol symbol)
    {
        return symbol.ContainingNamespace 
            + "." + symbol.Name 
            + ", " + symbol.ContainingAssembly;
    }
    

    If you don't need an assembly qualified type name don't concatenate ContainingAssembly at the end of the last line.

    0 讨论(0)
  • 2021-02-12 20:14

    Using the semantic model you can also do it like i did it here:

    var typeInfo = context.SemanticModel.GetTypeInfo(identifierNameSyntax);
    var namedType = typeInfo.Type as INamedTypeSymbol;
    if (namedType != null && namedType.Name == nameof(ConfiguredTaskAwaitable) && GetFullNamespace(namedType) == typeof(ConfiguredTaskAwaitable).Namespace)
        return true;
    

    where "GetFullNamespace" works like this:

        public static IEnumerable<string> GetNamespaces(INamedTypeSymbol symbol)
        {
            var current = symbol.ContainingNamespace;
            while (current != null)
            {
                if (current.IsGlobalNamespace)
                    break;
                yield return current.Name;
                current = current.ContainingNamespace;
            }
        }
    
        public static string GetFullNamespace(INamedTypeSymbol symbol)
        {
            return string.Join(".", GetNamespaces(symbol).Reverse());
        }
    
        public static string GetFullTypeName(INamedTypeSymbol symbol)
        {
            return string.Join(".", GetNamespaces(symbol).Reverse().Concat(new []{ symbol.Name }));
        }
    

    Obviously Jason Malinowski's answer is more convenient for simple cases

    0 讨论(0)
提交回复
热议问题