Поиск всех пространств имен в сборке с использованием Reflection (DotNET)

У меня есть assembly (загружена как ReflectionOnly), и я хочу найти все пространства имен в этой сборке, чтобы я мог преобразовать их в операторы «using» («Импорт» в VB) для шаблона файла с автогенерированным исходным кодом.

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

using System; using System.Collections; using System.Collections.Generic; 

вы получите только:

 using System; 

Я заметил, что в classе System.Type есть свойство Namespace, но есть ли лучший способ собирать пространства имен внутри сборки, не связанные с итерацией по всем типам и отбраковка повторяющихся строк пространства имен?

Очень важно, Дэвид

Нет, для этого нет ярлыка, хотя 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); } 

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

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

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

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

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

Немного 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); } 

У вас не будет другого выбора, кроме повторения всех classов.

Обратите внимание, что импорт не работает рекурсивно. «using System» не будет импортировать какие-либо classы из подзонных пространств, таких как System.Collections или System.Collections.Generic, вместо этого вы должны включить их все.

 public static void Main() { var assembly = ...; Console.Write(CreateUsings(FilterToTopLevel(GetNamespaces(assembly)))); } private static string CreateUsings(IEnumerable namespaces) { return namespaces.Aggregate(String.Empty, (u, n) => u + "using " + n + ";" + Environment.NewLine); } private static IEnumerable FilterToTopLevel(IEnumerable namespaces) { return namespaces.Select(n => n.Split('.').First()).Distinct(); } private static IEnumerable GetNamespaces(Assembly assembly) { return (assembly.GetTypes().Select(t => t.Namespace) .Where(n => !String.IsNullOrEmpty(n)) .Distinct()); } 
  • Что регистрирует сохранение в соглашении вызова ARM C?
  • Использование разных версий одной и той же сборки в одной папке
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Есть ли альтернатива Maven или порт для мира .NET?
  • Visual Studio «Не удалось скопировать» ... во время сборки
  • Загрузка нескольких версий одной и той же сборки
  • как загрузить все сборки из вашего каталога / bin
  • .NET Assembly Diff / Compare Tool - Что доступно?
  • Ошибка в построении gradleа после обновления Android Studio с log4j
  • Как сохранить сборки ASP.NET в AppDomain в живых?
  • В чем разница между MOV и LEA?
  • Давайте будем гением компьютера.