Bagaimana Anda mendapatkan semua kelas di namespace melalui refleksi di C #?
Bagaimana Anda mendapatkan semua kelas di namespace melalui refleksi di C #?
Jawaban:
Kode berikut mencetak nama-nama kelas yang ditentukan namespace
ditentukan dalam majelis saat ini.
Seperti yang ditunjukkan orang lain, namespace dapat tersebar di antara modul yang berbeda, jadi Anda harus mendapatkan daftar rakitan terlebih dahulu.
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));
Seperti yang dikatakan FlySwat, Anda dapat memiliki namespace yang sama yang mencakup banyak majelis (misalnya System.Collections.Generic
). Anda harus memuat semua rakitan itu jika belum dimuat. Jadi untuk jawaban yang lengkap:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Ini akan berfungsi kecuali jika Anda ingin kelas domain lain. Untuk mendapatkan daftar semua domain, ikuti tautan ini.
&& t.Namespace == @namespace
" - yang mana karena memberi saya semua .net rakitan :-)
&& t.Namespace == @namespace
Anda mendapatkan semua kelas dari semua majelis , termasuk. Net. GetAssemblies
akan memberi Anda semua majelis, dan GetAssemblies().SelectMany(t => t.GetTypes())
akan memberikan semua jenis (kelas, struct dll) dari semua majelis.
Assembly.Load(nameof(NameOfMyNamespace))
bekerja dengan baik.
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: Kode di atas menggambarkan apa yang terjadi. Jika Anda ingin menerapkannya, versi yang disederhanakan dapat digunakan:
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
pada iterasi pertama atas asm.GetTypes()
hasilnya.
Untuk Majelis tertentu, NameSpace dan 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();
Catatan: Proyek harus merujuk perakitan
Berikut ini adalah perbaikan untuk kesalahan LoaderException yang mungkin Anda temukan jika salah satu dari jenis-jenis itu menutupi suatu jenis dalam rakitan lain:
// 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);
}
Itu akan membantu dengan memuat jenis yang didefinisikan dalam majelis lain.
Semoga itu bisa membantu!
Assembly a
barang - barang tersebut mewakili pemrosesan normal yang mungkin menyebabkan peristiwa ini memanas. Saya melihat tidak ada gunanya a
membantu dengan LoaderException
kesalahan. Apakah saya benar?
Anda tidak akan bisa mendapatkan semua tipe dalam namespace, karena namespace dapat menjembatani banyak majelis, tetapi Anda bisa mendapatkan semua kelas dalam sebuah majelis dan memeriksa untuk melihat apakah mereka termasuk dalam namespace itu.
Assembly.GetTypes()
bekerja pada rakitan lokal, atau Anda dapat memuat rakitan terlebih dahulu kemudian memanggilnya GetTypes()
.
AppDomain.CurrentDomain.GetAssemblies
dapat membantu.
Sama seperti jawaban @aku, tetapi menggunakan metode ekstensi:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
Dapatkan semua kelas dengan bagian nama Namespace hanya dalam satu baris:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Namespaces sebenarnya agak pasif dalam desain runtime dan berfungsi terutama sebagai alat organisasi. Nama lengkap tipe dalam .NET terdiri dari Namespace dan Class / Enum / Etc. digabungkan. Jika Anda hanya ingin melalui perakitan tertentu, Anda hanya akan mengulang jenis yang dikembalikan oleh perakitan. GetExportedTypes () memeriksa nilai tipe. Namespace . Jika Anda mencoba untuk melewati semua majelis yang dimuat di AppDomain saat ini, itu akan melibatkan penggunaan 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
nama itu MustHaveAttributes
? Saya tidak melihat apa pun yang berkaitan dengan pengujian apakah suatu kelas memiliki atribut atau tidak. Ini lebih membingungkan daripada membantu.
Cukup sederhana
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}