Получение всех типов в пространстве имен с помощью отражения - PullRequest
243 голосов
/ 17 сентября 2008

Как вы получаете все классы в пространстве имен через отражение в C #?

Ответы [ 11 ]

295 голосов
/ 17 сентября 2008

Следующий код печатает имена классов в указанном namespace, определенном в текущей сборке.
Как отметили другие ребята, пространство имен может быть разбросано по разным модулям, поэтому сначала нужно получить список сборок.

string nspace = "...";

var q = from t in Assembly.GetExecutingAssembly().GetTypes()
        where t.IsClass && t.Namespace == nspace
        select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));
69 голосов
/ 12 мая 2013

Как говорит FlySwat, у вас может быть одинаковое пространство имен, охватывающее несколько сборок (например, System.Collections.Generic). Вам придется загрузить все эти сборки, если они еще не загружены. Итак, для полного ответа:

AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(t => t.GetTypes())
                       .Where(t => t.IsClass && t.Namespace == @namespace)

Это должно работать, если вы не хотите классов других доменов. Чтобы получить список всех доменов, перейдите по этой ссылке .

21 голосов
/ 17 сентября 2008
using System.Reflection;
using System.Collections.Generic;
//...

static List<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();

    List<string> namespacelist = new List<string>();
    List<string> classlist = new List<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;
//...

static IEnumerable<string> GetClasses(string nameSpace)
{
    Assembly asm = Assembly.GetExecutingAssembly();
    return asm.GetTypes()
        .Where(type => type.Namespace == nameSpace)
        .Select(type => type.Name);
}
15 голосов
/ 19 января 2016

Для конкретной сборки, NameSpace и ClassName:

var assemblyName = "Some.Assembly.Name"
var nameSpace = "Some.Namespace.Name";
var className = "ClassNameFilter";

var asm = Assembly.Load(assemblyName);
var classes = asm.GetTypes().Where(p =>
     p.Namespace == nameSpace &&
     p.Name.Contains(className) 
).ToList();

Примечание: проект должен ссылаться на сборку

12 голосов
/ 17 сентября 2008

Вот исправление ошибок LoaderException, которые вы, вероятно, найдете, если один из типов подклассов типа в другой сборке:

// Setup event handler to resolve assemblies
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);

Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();
// process types here

// method later in the class:
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
    return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}

Это должно помочь с типами загрузки, определенными в других сборках.

Надеюсь, это поможет!

9 голосов
/ 17 сентября 2008

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

Assembly.GetTypes() работает в локальной сборке, или вы можете сначала загрузить сборку, а затем вызвать GetTypes().

5 голосов
/ 22 декабря 2014

Получить все классы по части имени пространства имен в одной строке:

var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
5 голосов
/ 09 января 2013

Точно так же, как ответ @aku, но с использованием методов расширения:

string @namespace = "...";

var types = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.IsClass && t.Namespace == @namespace)
    .ToList();

types.ForEach(t => Console.WriteLine(t.Name));
3 голосов
/ 17 сентября 2008

Пространства имен на самом деле довольно пассивны в дизайне среды выполнения и служат главным образом как организационные инструменты. Полное имя типа в .NET состоит из пространства имен и класса / Enum / Etc. вместе взятые. Если вы хотите только пройти через определенную сборку, вы просто зациклите типы, возвращаемые сборкой. GetExportedTypes () проверка значения типа. Пространство имен . Если вы пытаетесь просмотреть все сборки, загруженные в текущем домене приложений, это будет связано с использованием AppDomain.CurrentDomain. GetAssemblies ()

2 голосов
/ 29 февраля 2016

Довольно просто

Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}
...