通过反射获取命名空间中的所有类型

252 .net c# reflection namespaces

如何通过C#中的反射获取命名空间中的所有类?

aku*_*aku 304

下面的代码打印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));
Run Code Online (Sandbox Code Playgroud)


naw*_*fal 73

正如FlySwat所说,您可以在多个程序集中使用相同的名称空间(例如System.Collections.Generic).如果尚未加载,则必须加载所有这些程序集.所以有一个完整的答案:

AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(t => t.GetTypes())
                       .Where(t => t.IsClass && t.Namespace == @namespace)
Run Code Online (Sandbox Code Playgroud)

除非您需要其他域的类,否则这应该有效.要获取所有域的列表,请单击此链接.


Rya*_*ley 24

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;
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码说明了发生了什么.如果您要实现它,可以使用简化版本:

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我并不想做出意思,但是在这段代码中,所有找到的项目都有一个完全不必要的列表和迭代; "classlist"变量和foreach通过"namespacelist"提供的功能与返回"namespacelist"不同 (9认同)
  • @TheXenocide代码示例的目的并不总是要显示编写代码的"最佳"方式,而是要清楚地表达完成某些事情的方式. (9认同)
  • 如果对所提出的问题没有帮助,我会投下答案.当您将鼠标悬停在向上/向下投票按钮上时,您看到的提示显示"这很有帮助".对我来说,决定上/下投票的答案是,它是否有助于回答所提出的问题. (4认同)
  • 我只是为了教育而指出它; 我们有责任让材料人们从最好的榜样中学习,而不是冒着一个负面影响理解的坏榜样.我不是说这特别是有害的,但我不同意这种情绪 (3认同)
  • 使用两个列表和两次迭代的唯一帮助就是让我慢下来试图找出你为什么使用两个列表并且不仅仅在第一次迭代时直接添加到`classlist`而不是`asm.GetTypes()`结果. (3认同)
  • 当您只有一个数据列表可供使用时,这里有两个列表是糟糕的代码。它并没有让任何事情变得更清晰,并且会鼓励阅读它的初学者养成不良的编码习惯。 (3认同)

Joh*_*ers 16

对于特定的Assembly,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();
Run Code Online (Sandbox Code Playgroud)

注意:项目必须引用程序集


tsi*_*mon 12

如果其中一个类型是另一个程序集中的类型,则可能会找到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);
}
Run Code Online (Sandbox Code Playgroud)

这应该有助于加载在其他程序集中定义的类型.

希望有所帮助!


Fly*_*wat 9

您将无法获取命名空间中的所有类型,因为命名空间可以桥接多个程序集,但您可以获取程序集中的所有类并检查它们是否属于该命名空间.

Assembly.GetTypes()适用于本地程序集,或者您可以先加载程序集然后调用GetTypes()它.

  • +1为正确答案。AppDomain.CurrentDomain.GetAssemblies`可能会有所帮助。 (2认同)

Joa*_*Fdz 5

就像@aku回答,但使用扩展方法:

string @namespace = "...";

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

types.ForEach(t => Console.WriteLine(t.Name));
Run Code Online (Sandbox Code Playgroud)


Ivo*_*nov 5

通过名称空间名称的一部分获取所有类,只需一行:

var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Run Code Online (Sandbox Code Playgroud)