![](/img/trans.png)
[英]How can I get the fully qualified namespace from a using directive in Roslyn?
[英]How can I get the most fully reduced type name of an arbitrary type in a given namespace context using Roslyn?
我正在編寫一個 function ,它采用任何具體或構造Type
,例如typeof(ValueTuple<Nullable<System.Int32>, double, List<string>>)
並返回一個字符串,該字符串是該類型的簡化 C# 語法表示(即(int?, double, List<string>)
在這個例子中)。
這是我到目前為止所擁有的:
public static string ToCSharpString(this Type type, string[] usingNamespaces = null, Assembly[] usingAssemblies = null)
{
var compilationUnit = SyntaxFactory.CompilationUnit();
if (usingNamespaces != null)
{
compilationUnit = compilationUnit.AddUsings(
Array.ConvertAll(usingNamespaces, n => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(n))));
}
else
{
compilationUnit = compilationUnit.AddUsings(
SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("System")));
}
MetadataReference[] metadataReferences;
if (usingAssemblies != null)
{
metadataReferences = Array.ConvertAll(usingAssemblies, u => MetadataReference.CreateFromFile(u.Location));
}
else
{
metadataReferences = new[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(type.Assembly.Location)
};
}
TypeSyntax typeName;
using (var provider = new CSharpCodeProvider())
{
typeName = SyntaxFactory.ParseTypeName(provider.GetTypeOutput(new CodeTypeReference(type)));
}
var field = SyntaxFactory.FieldDeclaration(
SyntaxFactory.VariableDeclaration(typeName).WithVariables(
SyntaxFactory.SingletonSeparatedList<VariableDeclaratorSyntax>(
SyntaxFactory.VariableDeclarator(
SyntaxFactory.Identifier("field")))));
compilationUnit = compilationUnit.AddMembers(
SyntaxFactory.ClassDeclaration("MyClass").AddMembers(
field))
.NormalizeWhitespace();
var tree = compilationUnit.SyntaxTree;
var compilation = CSharpCompilation.Create("MyAssembly", new[] { tree }, metadataReferences);
var semanticModel = compilation.GetSemanticModel(tree);
var root = tree.GetRoot();
var typeSymbol = semanticModel.GetDeclaredSymbol(compilationUnit
.DescendantNodes().OfType<ClassDeclarationSyntax>().Single()
.Members.OfType<FieldDeclarationSyntax>().Single()
.Declaration.Type);
return typeSymbol.ToDisplayString(new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
}
我試圖將幾種已知的轉換類型的方法串在一起。
現在我想將.ToDisplayString()
與幾個不同的選項一起使用,但我找不到不從語義 model 返回 null 的類型節點。
如何使用 SymbolDisplayFormat 格式化 TypeSyntax?
此外,我希望這會改變System.Int32
-> int
,但是,它不會自動修復Nullable<T>
或ValueTuple<T1...>
的實例
如何執行適當的代碼分析規則來替換這些類型名稱?
文檔 state GetDeclaredSymbol
僅適用於
從 MemberDeclarationSyntax、TypeDeclarationSyntax、EnumDeclarationSyntax、NamespaceDeclarationSyntax、ParameterSyntax、TypeParameterSyntax 或 UsingDirectiveSyntax 的別名部分派生的任何類型
你的似乎是QualifiedNameSyntax
,這似乎與預期的輸入非常一致,但顯然對 Roslyn 意味着其他東西(我承認我沒有費心檢查它是否真的繼承自預期的類型之一)。
但是,改為獲取TypeInfo
似乎可以使您的特定示例正常工作:
var typeSymbol = semanticModel.GetTypeInfo(compilationUnit // just changed this method
.DescendantNodes().OfType<ClassDeclarationSyntax>().Single()
.Members.OfType<FieldDeclarationSyntax>().Single()
.Declaration.Type);
return typeSymbol.Type.ToDisplayString(new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes)); // I'm getting "(int?, double, List)" here
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.