Вы можете отредактировать свой вопрос ... подтекстный вопрос является более коммуникативным, чем «Пространство имен в C #»
Gishu
Вы можете посмотреть здесь . Есть 2 разных образца.
Фатих Гюрдал
Ответы:
317
Следующий код печатает имена классов в указанных, namespaceопределенных в текущей сборке.
Как отмечали другие ребята, пространство имен может быть разбросано по разным модулям, поэтому сначала нужно получить список сборок.
Как говорит FlySwat, у вас может быть одно и то же пространство имен, охватывающее несколько сборок (например, System.Collections.Generic). Вам придется загрузить все эти сборки, если они еще не загружены. Итак, для полного ответа:
работает отлично - небольшое напоминание: я пытался удалить " && t.Namespace == @namespace" - который, конечно, дал мне все сборки .net :-)
Netsi1964
@ Netsi1964 если вы удалите && t.Namespace == @namespaceвы получаете все классы из всех узлов , в том числе .net х. GetAssembliesпредоставит вам все сборки и GetAssemblies().SelectMany(t => t.GetTypes())все типы (классы, структуры и т. д.) из всех сборок.
Nawfal
Я обновил до DotNet Core 2.2 (с 2.1), и этот код перестал работать для моей конкретной сборки. Сборка, которую я хотел, нигде не упоминалась в коде, поэтому не была загружена! В 2.1 это было загружено, но у 2.2, кажется, есть ленивая загрузка?
Харви
@ Харви Есть ли у .NET Core домен приложения для начала?
nawfal
@nawfal Да. Этот код работал ранее в 2.1. Я обнаружил, что я принудительно загружаю сборку с помощью Assembly.Load(nameof(NameOfMyNamespace))работал нормально.
Харви
28
using System.Reflection;
using System.Collections.Generic;//...staticList<string>GetClasses(string nameSpace){Assembly asm =Assembly.GetExecutingAssembly();List<string> namespacelist =newList<string>();List<string> classlist =newList<string>();foreach(Type type in asm.GetTypes()){if(type.Namespace== nameSpace)
namespacelist.Add(type.Name);}foreach(string classname in namespacelist)
classlist.Add(classname);return classlist;}
NB: приведенный выше код иллюстрирует, что происходит. Если бы вы это реализовали, можно использовать упрощенную версию:
using System.Linq;
using System.Reflection;
using System.Collections.Generic;//...staticIEnumerable<string>GetClasses(string nameSpace){Assembly asm =Assembly.GetExecutingAssembly();return asm.GetTypes().Where(type => type.Namespace== nameSpace).Select(type => type.Name);}
Я не пытаюсь быть злым, но есть совершенно ненужный список и итерация по всем найденным элементам в этом коде; переменная «classlist» и foreach через «namespacelist» не предоставляют никакой функциональности, отличной от возврата «namespacelist»
TheXenocide
10
@ TheXenocide Цель примера кода не всегда состоит в том, чтобы показать «лучший» способ написания кода, но чтобы ясно показать, как что-то делается.
Райан Фарли
4
Я просто указывал на это ради образования; наша ответственность состоит в том, чтобы научить людей учиться на лучшем примере, который мы можем, вместо того, чтобы рисковать плохим примером, который негативно влияет на понимание. Я не говорю, что это в особенности вредно, но я не согласен с
мнением
4
Я отказываюсь от ответа, если он не помогает в вопросе, который был задан. Подсказка, которую вы видите при наведении курсора на кнопку «вверх / вниз», гласит: «Это было полезно». Для меня решение о том, чтобы проголосовать за вопрос вверх или вниз, заключается в том, было ли это полезным для ответа на заданный вопрос.
Райан Фарли
3
Единственное, что вам помогло, используя два списка и две итерации, - это замедлило меня, пытаясь понять, почему вы использовали два списка, а не просто добавили прямую к classlistпервой итерации по asm.GetTypes()результату.
Вот исправление ошибок LoaderException, которые вы, вероятно, найдете, если один из типов подклассов типа в другой сборке:
// Setup event handler to resolve assembliesAppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve+=newResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);Assembly a =System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();// process types here// method later in the class:staticAssemblyCurrentDomain_ReflectionOnlyAssemblyResolve(object sender,ResolveEventArgs args){returnSystem.Reflection.Assembly.ReflectionOnlyLoad(args.Name);}
Это должно помочь с типами загрузки, определенными в других сборках.
Конечно, выглядит полезным, и менее полезным и менее запутанным, чем код Райана Фарли, даже не задумываясь об этом.
ProfK
Вы также немного запутали меня. Я до сих пор могу только догадываться, что Assembly aматериал представляет собой нормальную обработку, которая может вызвать это событие. Я не вижу смысла aв помощи с LoaderExceptionошибками. Я прав?
ProfK
9
Вы не сможете получить все типы в пространстве имен, потому что пространство имен может соединять несколько сборок, но вы можете получить все классы в сборке и проверить, принадлежат ли они этому пространству имен.
Assembly.GetTypes()работает на локальной сборке, или вы можете сначала загрузить сборку, а затем вызвать GetTypes()ее.
+1 за правильный ответ. AppDomain.CurrentDomain.GetAssembliesможет быть полезным
Nawfal
... а затем перебрать их, отфильтровывая те, которые не соответствуют пространству имен.
TJ Crowder
В OP специально запрашивались «классы в пространстве имен», тогда как при этом вы получаете «типы в сборке», поэтому этот ответ неполон. Правильный ответ, вероятно, такой , который перечисляет только классы из всех сборок.
mindplay.dk
6
Точно так же, как ответ @aku, но с использованием методов расширения:
Пространства имен на самом деле довольно пассивны в дизайне среды выполнения и служат главным образом как организационные инструменты. Полное имя типа в .NET состоит из пространства имен и класса / Enum / Etc. вместе взятые. Если вы хотите пройти только через определенную сборку, вы просто перебираете типы, возвращаемые сборкой. GetExportedTypes () проверяет значение типа. Пространство имен . Если вы пытаетесь просмотреть все сборки, загруженные в текущий AppDomain, это будет связано с использованием AppDomain.CurrentDomain. GetAssemblies ()
//a simple combined code snippet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MustHaveAttributes{classProgram{staticvoidMain(string[] args ){Console.WriteLine(" START ");// what is in the assemblyAssembly a =Assembly.Load("MustHaveAttributes");Type[] types = a.GetTypes();foreach(Type t in types){Console.WriteLine("Type is {0}", t );}Console.WriteLine("{0} types found", types.Length);#region Linq//#region Action//string @namespace = "MustHaveAttributes";//var q = from t in Assembly.GetExecutingAssembly ().GetTypes ()// where t.IsClass && t.Namespace == @namespace// select t;//q.ToList ().ForEach ( t => Console.WriteLine ( t.Name ) );//#endregion Action #endregionConsole.ReadLine();Console.WriteLine(" HIT A KEY TO EXIT ");Console.WriteLine(" END ");}}//eof ProgramclassClassOne{}//eof class classClassTwo{}//eof class[System.AttributeUsage(System.AttributeTargets.Class|System.AttributeTargets.Struct,AllowMultiple=true)]publicclassAttributeClass:System.Attribute{publicstringMustHaveDescription{get;set;}publicstringMusHaveVersion{get;set;}publicAttributeClass(string mustHaveDescription,string mustHaveVersion ){MustHaveDescription= mustHaveDescription;MusHaveVersion= mustHaveVersion;}}//eof class }//eof namespace
Какое AttributeClassимя MustHaveAttributesвсе о? Я не вижу ничего, связанного с проверкой, есть ли у класса атрибуты или нет. Это больше сбивает с толку, чем полезно.
ProfK
1
Довольно просто
Type[] types =Assembly.Load(newAssemblyName("mynamespace.folder")).GetTypes();foreach(var item in types){}
Ответы:
Следующий код печатает имена классов в указанных,
namespace
определенных в текущей сборке.Как отмечали другие ребята, пространство имен может быть разбросано по разным модулям, поэтому сначала нужно получить список сборок.
источник
Как говорит FlySwat, у вас может быть одно и то же пространство имен, охватывающее несколько сборок (например,
System.Collections.Generic
). Вам придется загрузить все эти сборки, если они еще не загружены. Итак, для полного ответа:Это должно работать, если вы не хотите классов других доменов. Чтобы получить список всех доменов, перейдите по этой ссылке.
источник
&& t.Namespace == @namespace
" - который, конечно, дал мне все сборки .net :-)&& t.Namespace == @namespace
вы получаете все классы из всех узлов , в том числе .net х.GetAssemblies
предоставит вам все сборки иGetAssemblies().SelectMany(t => t.GetTypes())
все типы (классы, структуры и т. д.) из всех сборок.Assembly.Load(nameof(NameOfMyNamespace))
работал нормально.NB: приведенный выше код иллюстрирует, что происходит. Если бы вы это реализовали, можно использовать упрощенную версию:
источник
classlist
первой итерации поasm.GetTypes()
результату.Для конкретной сборки NameSpace и ClassName:
Примечание: проект должен ссылаться на сборку
источник
Вот исправление ошибок LoaderException, которые вы, вероятно, найдете, если один из типов подклассов типа в другой сборке:
Это должно помочь с типами загрузки, определенными в других сборках.
Надеюсь, это поможет!
источник
Assembly a
материал представляет собой нормальную обработку, которая может вызвать это событие. Я не вижу смыслаa
в помощи сLoaderException
ошибками. Я прав?Вы не сможете получить все типы в пространстве имен, потому что пространство имен может соединять несколько сборок, но вы можете получить все классы в сборке и проверить, принадлежат ли они этому пространству имен.
Assembly.GetTypes()
работает на локальной сборке, или вы можете сначала загрузить сборку, а затем вызватьGetTypes()
ее.источник
AppDomain.CurrentDomain.GetAssemblies
может быть полезнымТочно так же, как ответ @aku, но с использованием методов расширения:
источник
Получить все классы по части имени пространства имен в одной строке:
источник
Пространства имен на самом деле довольно пассивны в дизайне среды выполнения и служат главным образом как организационные инструменты. Полное имя типа в .NET состоит из пространства имен и класса / Enum / Etc. вместе взятые. Если вы хотите пройти только через определенную сборку, вы просто перебираете типы, возвращаемые сборкой. GetExportedTypes () проверяет значение типа. Пространство имен . Если вы пытаетесь просмотреть все сборки, загруженные в текущий AppDomain, это будет связано с использованием AppDomain.CurrentDomain. GetAssemblies ()
источник
источник
AttributeClass
имяMustHaveAttributes
все о? Я не вижу ничего, связанного с проверкой, есть ли у класса атрибуты или нет. Это больше сбивает с толку, чем полезно.Довольно просто
источник