簡體   English   中英

從TypeInfo對象獲取類型的完全限定名稱

[英]Getting the fully qualified name of a type from a TypeInfo object

是否有可能獲得TypeInfo對象中包含的類型的完全限定名稱?

在調試器中,很多這些值很好地顯示為System.Int32但是當它打印出來時,其中沒有一個包含這個完全限定的名稱。 我需要這個作為Type.GetType()的參數。

var typeInfo = semanticModel.GetTypeInfo(argument);
var w = typeInfo.ToString(); // Microsoft.CodeAnalysis.TypeInfo
var y = typeInfo.Type.ToString(); // int
var z = typeInfo.Type.ToDisplayString(); // int 
var a = typeInfo.Type.OriginalDefinition.ToDisplayString(); // int
var b = typeInfo.Type.OriginalDefinition.ToString(); // int
var c = typeInfo.Type.Name; // Int32
var d = typeInfo.Type.MetadataName; // Int32
var e = typeInfo.Type.ToDisplayParts(); // {int}
var f = typeInfo.Type.ContainingNamespace; // System

請注意,這應該適用於每種類型,因此我不能只是將名稱空間與名稱連接起來。

或者:是否有其他(更適合?)的方式來獲得確切的類型?

對於上下文:我想檢查類的類型參數是否包含一些特定的方法。 因此,我的方法是從TypeArgumentListSyntax獲取參數並從每個TypeSyntax對象獲取TypeInfo

ToDisplayString方法允許您傳入一個“格式”對象,該對象具有大量選項,用於控制您希望格式化內容的方式:

var symbolDisplayFormat = new SymbolDisplayFormat(
    typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);

string fullyQualifiedName = typeSymbol.ToDisplayString(symbolDisplayFormat);

獲取像“int”這樣的關鍵字是默認格式的原因是包括SymbolDisplayMiscellaneousOptions.UseSpecialTypes標志,該標志指定使用特殊類型的語言關鍵字與常規名稱。

我也找不到內置的東西,我很確定這不是最優雅的方式,但是我可以構建一個像這樣的限定類型名稱:

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

如果您不需要程序集限定類型名稱,請不要在最后一行的末尾連接ContainingAssembly

使用語義模型你也可以像我在這里做的那樣:

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;

其中“GetFullNamespace”的工作方式如下:

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

顯然Jason Malinowski的答案對於簡單案例來說更方便

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM