C#のリフレクションを使用して、名前空間のすべてのクラスをどのように取得しますか?
C#のリフレクションを使用して、名前空間のすべてのクラスをどのように取得しますか?
回答:
次のコード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));
FlySwatが言うように、複数のアセンブリ(たとえばSystem.Collections.Generic
)で同じ名前空間を使用できます。それらがまだロードされていない場合は、それらのすべてのアセンブリをロードする必要があります。だから完全な答えのために:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
他のドメインのクラスが必要でない限り、これは機能するはずです。すべてのドメインのリストを取得するには、このリンクをクリックしてください。
&& t.Namespace == @namespace
」を削除しようとしました- すべての .netアセンブリを提供した原因です:-)
&& t.Namespace == @namespace
と、.netを含むすべてのアセンブリのすべてのクラスが取得されます。すべてのアセンブリを提供し、すべてのアセンブリからすべてのタイプ(クラス、構造体など)を提供します。GetAssemblies
GetAssemblies().SelectMany(t => t.GetTypes())
Assembly.Load(nameof(NameOfMyNamespace))
うまく機能することを使用して、アセンブリの読み込みを強制することがわかりました。
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()
結果に直接追加しなかったということです。
特定のアセンブリ、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();
注:プロジェクトはアセンブリを参照する必要があります
タイプの1つが別のアセンブリのタイプをサブレースする場合に見つかる可能性が高い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
。私は正しいですか?
名前空間は複数のアセンブリをブリッジできるため、名前空間内のすべての型を取得することはできませんが、アセンブリ内のすべてのクラスを取得し、それらがその名前空間に属しているかどうかを確認できます。
Assembly.GetTypes()
ローカルアセンブリで機能するか、最初にアセンブリを読み込んでから呼び出すことができますGetTypes()
。
AppDomain.CurrentDomain.GetAssemblies
役立ちます。
@aku answerと同じですが、拡張メソッドを使用します。
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
名前空間は、ランタイムの設計では実際にはかなり受動的であり、主に編成ツールとして機能します。.NETの型のフルネームは、名前空間とClass / Enum / Etcで構成されます。組み合わせた。特定のアセンブリのみを処理する場合は、アセンブリによって返される型をループするだけです。タイプの値をチェックするGetExportedTypes()。名前空間。現在のAppDomainに読み込まれているすべてのアセンブリを調べようとした場合、AppDomain.CurrentDomainを使用する必要があります。GetAssemblies()
//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
ですか?クラスに属性があるかどうかのテストに関連することは何もありません。これは役立つよりも混乱します。