Получение пространства имен класса

введите описание изображения здесьможете ли вы помочь мне узнать пространство имен из VariableDeclarationSyntax, StatementSyntax и IdentifierNameSyntax?

Я просто использую приведенный ниже код, но он всегда отвечает только пространству имен «Microsoft.CodeAnalysis.CSharp.Syntax».

строка namespaceName = идентификаторSyntax.GetType().BaseType.Namespace;

Пожалуйста, рассмотрите следующий пример:

Package X;

Class A {};

Class B
{
A a;
}

Здесь оба класса доступны в пакете X; Поэтому я не хочу ссылаться на пространство имен класса A в B, если я использую экземпляр A в классе B. Но я хочу, чтобы имя пространства имен класса A использовалось Roslyn. есть ли способ получить его?


person Rengasamy    schedule 24.06.2016    source источник
comment
Я думаю, что реальная проблема заключается в том, что когда вы вызываете GetType(), это метод GetType, который существует в базовом типе объекта .net — это не один из методов Roslyn (он возвращает тип фактической ссылки на узел, а не введите анализируемый код, который описывает узел). Надеюсь, вторая часть моего (пересмотренного) ответа иллюстрирует, как получить интересующий вас тип.   -  person Dan Roberts    schedule 24.06.2016
comment
есть ли способ получить эти имена с помощью SyntaxNode?   -  person Rengasamy    schedule 24.06.2016
comment
Вам нужна семантическая модель.   -  person SLaks    schedule 24.06.2016
comment
Вы рады, что мой ответ касается вашего первоначального вопроса? Есть ли что-нибудь еще, что вы хотели бы принять для того, чтобы принять это?   -  person Dan Roberts    schedule 28.06.2016
comment
См. stackoverflow.com/a/40612165/1498252.   -  person Arci    schedule 15.08.2018


Ответы (1)


Из синтаксиса IdentifierNameSyntax, если вы хотите определить, в каком пространстве имен объявлен этот идентификатор, вы можете сделать следующее (и поэтому вы сможете сделать то же самое с другими типами узлов):

var ns = context.Node.Ancestors().OfType<NamespaceDeclarationSyntax>().FirstOrDefault();

Обратите внимание, что это иногда будет нулевым. Например, если вы анализируете следующий контент

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {   
    }
}

Тогда «Система», «Коллекции», «Универсальный» и т. д. приведут к экземплярам IdentifierNameSyntax, но они не находятся в пространстве имен.

В качестве альтернативы, если у вас есть VariableDeclarationSyntax и вы хотите знать, какое пространство имен содержит тип переменной, вы можете сделать это:

var variableDeclaration = (VariableDeclarationSyntax)context.Node;
var type = context.SemanticModel.GetTypeInfo(variableDeclaration.Type).Type;
if ((type != null) && !(type is IErrorTypeSymbol)) // This will happen if the type lookup fails
{
    var ns = type.ContainingNamespace;
}

Если бы вы анализировали строку

var x = new SqlCommand();

тогда «тип» будет «System.Data.SqlClient.SqlCommand», и поэтому «ns» будет пространством имен «System.Data.SqlClient»;

person Dan Roberts    schedule 24.06.2016
comment
Он возвращает только те пространства имен, которые используются в текущем файле. Мне нужно получить доступ к пространствам имен, которые не записаны в файле. - person Rengasamy; 24.06.2016
comment
Извините, вы имели в виду, что хотите знать, на какие пространства имен ссылается код, а не на какие пространства имен определены в коде? Итак, если была строка var command = new SqlCommand(); то вы хотите знать, что SqlCommand из пространства имен System.Data? - person Dan Roberts; 24.06.2016
comment
Вопрос изменен. Пожалуйста, отправьте это @Dan Roberts - person Rengasamy; 24.06.2016
comment
есть ли способ получить эти имена с помощью SyntaxNode? - person Rengasamy; 24.06.2016
comment
Я не верю, что существует — он не может быть надежным, даже если бы он был, поскольку существует так много сценариев, когда тип был бы объявлен в другом месте модели, а не в синтаксическом дереве из исходного кода, который вы в настоящее время рассматривают. Прежде чем прибегать к этому более дорогому методу, я полагаю, вы могли бы определить все пространства имен и все типы, которые ЕСТЬ в текущем синтаксическом дереве, а затем посмотреть, совпадают ли какие-либо из них? (Даже тогда это работает только тогда, когда тип ясен - я думаю, что для разрешения var определенно требуется доступ к SemanticModel). - person Dan Roberts; 24.06.2016