리플렉션을 통해 네임 스페이스의 모든 유형 가져 오기


268

C #에서 리플렉션을 통해 네임 스페이스의 모든 클래스를 어떻게 얻습니까?


질문을 편집 할 수 있습니까? 하위 텍스트 질문은 'C #의 네임 스페이스'보다 더 의사 소통합니다.
Gishu

여기서 볼 수 있습니다 . 두 가지 다른 샘플이 있습니다.
Fatih GÜRDAL

답변:


316

다음 코드 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));

83

FlySwat이 말했듯이 여러 어셈블리에서 동일한 네임 스페이스를 사용할 수 있습니다 (예 :) System.Collections.Generic. 해당 어셈블리가 아직로드되지 않은 경우 해당 어셈블리를 모두로드해야합니다. 완전한 대답을 얻으려면 :

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

다른 도메인 클래스를 원하지 않는 한 작동합니다. 모든 도메인 목록을 보려면 이 링크를 따르십시오 .


1
잘 작동합니다-작은 알림 : " && t.Namespace == @namespace" 를 제거하려고했습니다.
of.

@ Netsi1964 제거 && t.Namespace == @namespace하면 .net을 포함한 모든 어셈블리모든 클래스제공 됩니다. GetAssemblies모든 어셈블리 GetAssemblies().SelectMany(t => t.GetTypes())를 제공 하고 모든 어셈블리의 모든 유형 (클래스, 구조체 등)을 제공합니다.
nawfal

DotNet Core 2.2 (2.1에서)로 업그레이드했으며이 코드는 특정 어셈블리에서 작동을 멈췄습니다. 내가 원했던 어셈블리는 코드의 어느 곳에서도 참조되지 않았으므로로드되지 않았습니다! 2.1에서는로드되었지만 2.2는 게으른로드 인 것 같습니다.
Harvey

@Harvey .NET Core는 appdomain으로 시작합니까?
nawfal

@nawfal 그래. 이 코드는 이전에 2.1에서 작동했습니다. 나는 Assembly.Load(nameof(NameOfMyNamespace))잘 작동 하여 어셈블리를 강제로로드한다는 것을 알았습니다 .
Harvey

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

9
나는 의미하지 않으려 고 노력하지만,이 코드에서 발견 된 모든 항목을 통해 완전히 불필요한 목록과 반복이있다. "classlist"변수 및 foreach 통해 "namespacelist"는 "namespacelist"를 반환하는 것과 다른 기능을 제공하지 않습니다.
TheXenocide

10
@TheXenocide 코드 샘플의 목적은 항상 코드를 작성하는 "최상의"방법을 보여주는 것이 아니라 어떤 일이 어떻게 수행되는지 명확하게 전달하기위한 것입니다.
Ryan Farley

4
나는 교육을 위해 그것을 지적하고 있었다. 이해에 부정적인 영향을 미치는 나쁜 예를 위험에 빠뜨리기보다는 사람들이 우리가 할 수있는 가장 좋은 예를 통해 배우게하는 것이 우리의 책임입니다. 나는 이것이 특히 해롭다는 말은 아니지만 감정에 동의하지 않는다
TheXenocide

4
요청 된 질문에 도움이되지 않으면 답을 내려 투표합니다. 위로 / 아래로 투표 버튼 위로 마우스를 가져 가면 "이것이 도움이되었습니다"라는 힌트가 나타납니다. 대답을 위 / 아래로 투표하기로 결정한 것은 질문에 대답하는 데 도움이되었는지 여부입니다.
Ryan Farley

3
두 개의 목록과 두 개의 반복을 사용하는 유일한 방법은 두 개의 목록을 사용한 이유를 알아 내려고 결과 classlist에 대한 첫 번째 반복에 직접 추가하지 않는 속도를 늦추는 것 asm.GetTypes()입니다.
ProfK

20

특정 어셈블리, 네임 스페이스 및 클래스 이름의 경우 :

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

참고 : 프로젝트는 어셈블리를 참조해야합니다.


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

다른 어셈블리에 정의 된로드 유형에 도움이됩니다.

희망이 도움이됩니다!


Ryan Farley의 코드에 대해 생각하지 않아도 도움이되고 도움이되고 혼란스럽지 않습니다.
ProfK

당신은 또한 잠시 동안 혼란 스러웠습니다. 나는 여전히 Assembly a물건 이이 이벤트를 발생시킬 수있는 정상적인 처리를 나타냅니다. 오류 해결 a에 도움이 되지 않습니다 LoaderException. 내가 맞아?
ProfK

9

네임 스페이스가 여러 어셈블리를 브리지 할 수 있기 때문에 네임 스페이스에서 모든 유형을 가져올 수는 없지만 어셈블리의 모든 클래스를 가져 와서 해당 네임 스페이스에 속하는지 확인할 수 있습니다.

Assembly.GetTypes()로컬 어셈블리에서 작동하거나 먼저 어셈블리를로드 한 다음 호출 할 수 있습니다 GetTypes().


2
정답은 +1입니다. AppDomain.CurrentDomain.GetAssemblies도움이 될 수 있습니다.
nawfal

... 그리고 네임 스페이스와 일치하지 않는 것들을 걸러 내면서 그것들을 반복합니다.
TJ Crowder 2016 년

OP는 특별히 "네임 스페이스의 클래스"를 요청했지만 "어셈블리의 유형"을 표시하므로이 답변은 불완전합니다. 정답은 아마도 모든 어셈블리에서 클래스 만 열거하는 this 입니다.
mindplay.dk

6

@aku 답변과 마찬가지로 확장 방법을 사용하십시오.

string @namespace = "...";

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

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

5

한 행에 네임 스페이스 이름의 일부로 모든 클래스를 가져옵니다.

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

3

네임 스페이스는 실제로 런타임 디자인에서 수동적이며 주로 조직 도구로 사용됩니다. .NET에서 유형의 전체 이름은 네임 스페이스와 클래스 / Enum / Etc로 구성됩니다. 결합. 특정 어셈블리 만 통과하려면 어셈블리에서 반환 한 형식을 반복하면됩니다. GetExportedTypes () 유형의 값을 확인합니다. 네임 스페이스 . 현재 AppDomain에로드 된 모든 어셈블리를 살펴 보려면 AppDomain.CurrentDomain을 사용해야합니다. GetAssemblies ()


2
//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? 클래스에 속성이 있는지 여부를 테스트하는 것과 관련이 없습니다. 이것은 도움이되는 것보다 더 혼란 스럽다.
ProfK

1

아주 간단한

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

그리고 단순히 질문에 대답하지 않습니다. 이 작업은 특정 네임 스페이스에 관계없이 단일 어셈블리의 모든 유형 목록을 가져 오는 것입니다.
Ian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.