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

时间:2020-03-05 18:57:50  来源:igfitidea点击:

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

解决方案

回答

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()

回答

以下代码在当前程序集中定义的指定"名称空间"中打印类的名称。
正如其他人指出的那样,名称空间可以分散在不同的模块之间,因此我们需要首先获取程序集列表。

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中类型的全名由命名空间和Class / Enum / Etc组成。结合。如果只希望通过特定的程序集,则只需遍历Assembly.GetExportedTypes()返回的类型,并检查type.Namespace的值。如果尝试遍历当前AppDomain中加载的所有程序集,则将涉及使用AppDomain.CurrentDomain.GetAssemblies()

回答

这是一个针对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