C# 通过反射获取命名空间中的所有类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/79693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting all types in a namespace via reflection
提问by
How do you get all the classes in a namespace through reflection in C#?
在 C# 中如何通过反射获取命名空间中的所有类?
回答by Ryan Farley
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: The above code illustrates what's going on. Were you to implement it, a simplified version can be used:
注意:上面的代码说明了发生了什么。如果您要实现它,可以使用简化版本:
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);
}
回答by FlySwat
You won't be able to get all types in a namespace, because a namespace can bridge multiple assemblies, but you can get all classes in an assembly and check to see if they belong to that namespace.
您将无法获取命名空间中的所有类型,因为命名空间可以桥接多个程序集,但您可以获取程序集中的所有类并检查它们是否属于该命名空间。
Assembly.GetTypes()
works on the local assembly, or you can load an assembly first then call GetTypes()
on it.
Assembly.GetTypes()
适用于本地程序集,或者您可以先加载程序集然后调用GetTypes()
它。
回答by aku
Following code prints names of classes in specified namespace
defined in current assembly.
As other guys pointed out, a namespace can be scattered between different modules, so you need to get a list of assemblies first.
以下代码打印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));
回答by TheXenocide
Namespaces are actually rather passive in the design of the runtime and serve primarily as organizational tools. The Full Name of a type in .NET consists of the Namespace and Class/Enum/Etc. combined. If you only wish to go through a specific assembly, you would simply loop through the types returned by assembly.GetExportedTypes()checking the value of type.Namespace. If you were trying to go through all assemblies loaded in the current AppDomain it would involve using AppDomain.CurrentDomain.GetAssemblies()
命名空间在运行时的设计中实际上是相当被动的,主要用作组织工具。.NET 中类型的全名由命名空间和类/枚举/等组成。结合。如果您只想通过特定的程序集,您只需遍历程序集返回的类型。GetExportedTypes()检查类型的值。命名空间。如果您尝试浏览当前 AppDomain 中加载的所有程序集,则将涉及使用 AppDomain.CurrentDomain。获取程序集()
回答by tsimon
Here's a fix for LoaderException errors you're likely to find if one of the types sublasses a type in another assembly:
如果其中一种类型对另一个程序集中的类型进行子类化,您可能会发现 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);
}
That should help with loading types defined in other assemblies.
这应该有助于加载其他程序集中定义的类型。
Hope that helps!
希望有帮助!
回答by Yordan Georgiev
//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
回答by JoanComasFdz
Just like @aku answer, but using extension methods:
就像@aku 回答一样,但使用扩展方法:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
回答by nawfal
As FlySwat says, you can have the same namespace spanning in multiple assemblies (for eg System.Collections.Generic
). You will have to load all those assemblies if they are not already loaded. So for a complete answer:
正如 FlySwat 所说,您可以在多个程序集中拥有相同的命名空间(例如System.Collections.Generic
)。如果尚未加载所有这些程序集,则必须加载它们。所以对于一个完整的答案:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
This should work unless you want classes of other domains. To get a list of all domains, follow this link.
除非您想要其他域的类,否则这应该有效。要获取所有域的列表,请点击此链接。
回答by Ivo Stoyanov
Get all classes by part of Namespace name in just one row:
仅在一行中按命名空间名称的一部分获取所有类:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
回答by John Peters
For a specific Assembly, NameSpace and ClassName:
对于特定的程序集、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();
Note: The project must reference the assembly
注意:项目必须引用程序集