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

如何在c#中通过反射获得命名空间中的所有类?

199412 次浏览
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;
}

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

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);
}

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

Assembly.GetTypes()在本地程序集上工作,或者你可以先加载一个程序集,然后在它上调用GetTypes()

下面的代码打印当前程序集中定义的指定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));

名称空间在运行时的设计中实际上相当被动,主要用作组织工具。. net中类型的全名由命名空间和类/Enum等组成。的总和。如果只希望遍历特定的程序集,则只需遍历程序集返回的类型。GetExportedTypes ()检查type.名称空间的值。如果要遍历当前AppDomain中加载的所有程序集,则需要使用AppDomain. currentdomain . __abc2

如果其中一个类型子类化了另一个程序集中的类型,你可能会发现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);
}

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

希望有帮助!

//a simple combined code snippet


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;


namespace MustHaveAttributes
{
class Program
{
static void Main ( string[] args )
{
Console.WriteLine ( " START " );


// what is in the assembly
Assembly 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
#endregion


Console.ReadLine ();
Console.WriteLine ( " HIT A KEY TO EXIT " );
Console.WriteLine ( " END " );
}
} //eof Program




class ClassOne
{


} //eof class


class ClassTwo
{


} //eof class




[System.AttributeUsage ( System.AttributeTargets.Class |
System.AttributeTargets.Struct, AllowMultiple = true )]
public class AttributeClass : System.Attribute
{


public string MustHaveDescription { get; set; }
public string MusHaveVersion { get; set; }




public AttributeClass ( string mustHaveDescription, string mustHaveVersion )
{
MustHaveDescription = mustHaveDescription;
MusHaveVersion = mustHaveVersion;
}


} //eof class


} //eof namespace

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

string @namespace = "...";


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


types.ForEach(t => Console.WriteLine(t.Name));

正如FlySwat所说,你可以在多个程序集中拥有相同的命名空间(例如System.Collections.Generic)。如果还没有加载所有这些程序集,则必须加载它们。完整的答案是:

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

这应该工作,除非你想要其他域的类。要获得所有域的列表,请执行这个链接。

在一行中通过Namespace名称的一部分获取所有类:

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

对于特定的程序集,命名空间和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();

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

很简单

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