问题
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 System.Int32
but when it's printed out, not one of them contains this fully qualified name. I need this to provide as an argument to 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
Note that this should work for every type so I can't just concatenate the namespace with the name.
Alternatively: is there another (more suited?) way to get the exact type?
For context: I want to check if the type-parameters of a class contain a few specific methods. Therefore my approach was to get the parameters from the TypeArgumentListSyntax
and get the TypeInfo
from each TypeSyntax
object.
回答1:
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.
回答2:
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.
回答3:
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
来源:https://stackoverflow.com/questions/23305594/getting-the-fully-qualified-name-of-a-type-from-a-typeinfo-object