Нахождение всех Пространств имен в блоке с помощью Отражения (DotNET)

Я думаю, что они относительно сопоставимы и в функциях и в простоте использования. Только от того, чтобы быть C# базировался, я нахожу msbuild легче работать с, чем nants, хотя это - едва неопровержимый довод для переключателя.

, Что такое точно nant, не делающий для Вас? Или Вы просто надеетесь, что существует некоторая замечательная функция, которую можно пропускать?:)

Одна суперхорошая вещь о C# состоит в том, что, если у Вас есть .net платформа, у Вас есть все, что необходимо выполнить msbuild. Это фантастически, когда Вы работаете над многочисленными командами / проекты и имеете людей/аппаратные средства оборот.

Лично я предпочитаю SCons по ним обоим:)

20
задан starblue 12 October 2009 в 11:12
поделиться

6 ответов

Нет, для этого нет ярлыка, хотя LINQ делает это относительно легко. Например, в C # необработанный «набор пространств имен» будет выглядеть следующим образом:

var namespaces = assembly.GetTypes()
                         .Select(t => t.Namespace)
                         .Distinct();

Чтобы получить пространство имен верхнего уровня, вам, вероятно, следует написать метод:

var topLevel = assembly.GetTypes()
                       .Select(t => GetTopLevelNamespace(t))
                       .Distinct();

...

static string GetTopLevelNamespace(Type t)
{
    string ns = t.Namespace ?? "";
    int firstDot = ns.IndexOf('.');
    return firstDot == -1 ? ns : ns.Substring(0, firstDot);
}

Я заинтригован, почему вам нужны только пространства имен верхнего уровня, хотя ... это кажется странным ограничением.

36
ответ дан 29 November 2019 в 23:30
поделиться

Пространства имен - это на самом деле просто соглашение об именах в именах типов, поэтому они «существуют» только как шаблон, который повторяется во многих определенных именах типов. Итак, вам нужно перебрать все типы. Однако код для этого, вероятно, можно записать как одно выражение Linq.

4
ответ дан 29 November 2019 в 23:30
поделиться

Вот что-то вроде linq'ish способа, он все еще по сути перебирает каждый элемент, но код намного чище.

var nameSpaces = from type in Assembly.GetExecutingAssembly().GetTypes()
                 select  type.Namespace;
nameSpaces = nameSpaces.Distinct();

Также, если ваш код автоматически генерируется, вам может быть лучше чтобы полностью квалифицировать все, вам не придется беспокоиться о конфликтах имен в сгенерированном коде.

2
ответ дан 29 November 2019 в 23:30
поделиться

A bit of LINQ?

var qry = (from type in assembly.GetTypes()
           where !string.IsNullOrEmpty(type.Namespace)
           let dotIndex = type.Namespace.IndexOf('.')
           let topLevel = dotIndex < 0 ? type.Namespace
                : type.Namespace.Substring(0, dotIndex)
           orderby topLevel
           select topLevel).Distinct();
foreach (var ns in qry) {
    Console.WriteLine(ns);
}
2
ответ дан 29 November 2019 в 23:30
поделиться

You will have no other choice than iterating over all classes.

Note that imports don't work recursively. "using System" won't import any classes from subnamespaces like System.Collections or System.Collections.Generic, instead you must include them all.

1
ответ дан 29 November 2019 в 23:30
поделиться
public static void Main() {

    var assembly = ...;

    Console.Write(CreateUsings(FilterToTopLevel(GetNamespaces(assembly))));
}

private static string CreateUsings(IEnumerable<string> namespaces) {
    return namespaces.Aggregate(String.Empty,
                                (u, n) => u + "using " + n + ";" + Environment.NewLine);
}

private static IEnumerable<string> FilterToTopLevel(IEnumerable<string> namespaces) {
    return namespaces.Select(n => n.Split('.').First()).Distinct();
}

private static IEnumerable<string> GetNamespaces(Assembly assembly) {
    return (assembly.GetTypes().Select(t => t.Namespace)
            .Where(n => !String.IsNullOrEmpty(n))
            .Distinct());
}
1
ответ дан 29 November 2019 в 23:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: