Как проверить, является ли строка пространством имен - PullRequest
8 голосов
/ 09 апреля 2010

У меня есть строка, и я хочу проверить, представляет ли она правильное пространство имен, например. System.IO в порядке, но System.Lol нет.

Полагаю, нужно использовать какое-то отражение, но я не могу этого понять.

Есть мысли?

Ответы [ 5 ]

8 голосов
/ 09 апреля 2010

Попробуйте этот подход:

using System.CodeDom.Compiler;
using System.Linq;

class NamespaceTester : IDisposable
{
    private CodeDomProvider provider = CodeDomProvider.CreateProvider("c#");
    private CompilerParameters settings = new CompilerParameters();
    private CompilerResults results;

    public bool Test(string[] namespaces)
    {
        results = provider.CompileAssemblyFromSource(
            settings,
            namespaces.Select(n => String.Format("using {0};", n)).ToArray());
        return results.Errors
            .OfType<CompilerError>()
            .Any(e => String.Equals(
                e.ErrorText,
                "CS0234",
                StringComparison.Ordinal));
    }

    public void Dispose()
    {
        if (results != null)
        {
            System.IO.File.Delete(results.CompiledAssembly.Location);
        }
    }
}

, где CS0234:

Тип или имя пространства имен name не существует в классе или пространстве имен 'scope' (вам не хватает сборки ссылка?)

Добавление пользовательских ссылок:

settings.ReferencedAssemblies.Add("Foobar.dll")

Использование:

public static void Main(string[] args)
{
    using (var tester = new NamespaceTester())
    {
        var success = tester.Test(new[] {
            "System.IO",
            "System.LOL"
        });
    }
}
4 голосов
/ 09 апреля 2010

Ваш вопрос «Как проверить, является ли строка пространством имен», действителен, только если вы считаете, , где вы проверяете пространства имен.

Пространства имен - это префиксы к именам классов, а классы находятся в области сборки. Чтобы проверить, существует ли пространство имен, вам нужно решить, какие сборки вы готовы просмотреть, чтобы найти существование пространства имен.

После того, как вы определились, какие сборки вы готовы просмотреть, вы можете выполнить итерацию по ним для существования определенного пространства имен, например:

public bool NamespaceExists(IEnumerable<Assembly> assemblies, string ns)
{
    foreach(Assembly assembly in assemblies)
    {
        if(assembly.GetTypes().Any(type => type.Namespace == ns))
            return true;
    }

    return false;
}
2 голосов
/ 09 апреля 2010

Не могли бы вы сделать это?

Assembly asm = Assembly.GetExecutingAssembly();
List<string> namespaceList = new List<string>();

foreach (Type type in asm.GetTypes())
{
    namespaceList.Add(type.Namespace);
}

Тогда просто проверьте, есть ли строка в списке?

(Имейте в виду, это не проверенный код!)

0 голосов
/ 09 апреля 2010

Нет никакого отражения в пространствах имен. Пространства имен определяют полное имя типа. Итак, что вам нужно сделать, это:

  • Перечислите все типы (вы не указываете исходный набор, скажем, .NET Framework, затем вам нужно включить все сборки .NET по умолчанию (посмотрите на те, на которые ссылается VS при создании проекта), или вашу собственную сборку , затем набирает в сборке).
  • Ищите свойство Namespace для данного типа

Что нужно использовать:

Сборка. Метод загрузки

Assembly.GetTypes метод

Свойство Type.Namespace

0 голосов
/ 09 апреля 2010

CLR на самом деле не имеет понятия «пространства имен»: они действительно немного больше, чем соглашение об именах. Таким образом, не существует API для «перечисления пространств имен», «получения пространств имен» или даже «получения всех типов в этом пространстве имен».

Лучшее, что вы можете сделать, - это перебрать все загруженные сборки, затем перебрать все экспортированные типы в каждой из этих сборок и проверить, является ли данная строка «префиксом» для любого из этих имен типов. Я полагаю, что это решение не будет самым быстрым в мире, но оно также не будет полностью неработоспособным.

...