【发布时间】:2010-09-09 22:20:42
【问题描述】:
如何通过 C# 中的反射获取命名空间中的所有类?
【问题讨论】:
-
你能编辑你的问题吗...潜台词问题比“C#中的命名空间”更具交流性
-
你可以看here。有 2 个不同的样本。
标签: c# .net reflection namespaces
如何通过 C# 中的反射获取命名空间中的所有类?
【问题讨论】:
标签: c# .net reflection namespaces
对于特定的程序集、命名空间和类名:
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();
注意:项目必须引用程序集
【讨论】:
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);
}
【讨论】:
classlist asm.GetTypes() 结果。
仅在一行中按命名空间名称的一部分获取所有类:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
【讨论】:
以下代码打印当前程序集中定义的指定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));
【讨论】:
很简单
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}
【讨论】:
正如 FlySwat 所说,您可以在多个程序集中拥有相同的命名空间(例如 System.Collections.Generic)。如果尚未加载所有这些程序集,则必须加载它们。因此,要获得完整的答案:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
除非您想要其他域的类,否则这应该可以工作。要获取所有域的列表,请关注this link.
【讨论】:
&& t.Namespace == @namespace” - 这给了我所有 .net程序集:-)
&& t.Namespace == @namespace,您将获得 所有程序集 的所有 类,包括 .net 的。 GetAssemblies 将提供所有程序集,GetAssemblies().SelectMany(t => t.GetTypes()) 将提供所有程序集的所有类型(类、结构等)。
Assembly.Load(nameof(NameOfMyNamespace)) 强制加载程序集工作得很好。
您将无法获取命名空间中的所有类型,因为命名空间可以桥接多个程序集,但您可以获取程序集中的所有类并检查它们是否属于该命名空间。
Assembly.GetTypes() 作用于本地程序集,或者您可以先加载程序集,然后对其调用GetTypes()。
【讨论】:
AppDomain.CurrentDomain.GetAssemblies 可能会有所帮助。
就像@aku 回答,但使用扩展方法:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.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
【讨论】:
AttributeClass 名称 MustHaveAttributes 到底是什么意思?我看不到任何与测试类是否具有属性有关的内容。这比有用更令人困惑。
以下是针对 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);
}
这应该有助于加载其他程序集中定义的类型。
希望有帮助!
【讨论】:
Assembly a 的东西代表了可能导致此事件触发的正常处理。我认为 a 在帮助解决 LoaderException 错误方面没有用。我说的对吗?
命名空间在运行时的设计中实际上是相当被动的,主要用作组织工具。 .NET 中类型的全名由命名空间和类/枚举/等组成。结合。如果您只想通过特定的程序集,您只需循环通过程序集返回的类型。GetExportedTypes() 检查类型的值。Namespace。如果您尝试浏览当前 AppDomain 中加载的所有程序集,则需要使用 AppDomain.CurrentDomain.GetAssemblies()
【讨论】: