Kode berikut mencetak nama-nama kelas yang ditentukan namespaceditentukan 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.
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:
berfungsi dengan baik - pengingat kecil: Saya mencoba untuk menghapus " && t.Namespace == @namespace" - yang mana karena memberi saya semua .net rakitan :-)
Netsi1964
@ Netsi1964 jika Anda menghapus && t.Namespace == @namespaceAnda mendapatkan semua kelas dari semua majelis , termasuk. Net. GetAssembliesakan memberi Anda semua majelis, dan GetAssemblies().SelectMany(t => t.GetTypes())akan memberikan semua jenis (kelas, struct dll) dari semua majelis.
nawfal
Saya memutakhirkan ke DotNet Core 2.2 (dari 2.1) dan kode ini berhenti berfungsi untuk perakitan khusus saya. Perakitan yang saya inginkan tidak dirujuk di mana pun dalam kode sehingga tidak dimuat! Dalam 2.1 itu dimuat, tetapi 2,2 tampaknya memuat malas?
Harvey
@ Harvey Apakah .NET Core memiliki appdomain untuk memulai?
nawfal
@nawfal Ya. Kode ini berfungsi sebelumnya di 2.1. Saya menemukan bahwa saya memaksa memuat perakitan dengan menggunakan Assembly.Load(nameof(NameOfMyNamespace))bekerja dengan baik.
Harvey
28
using System.Reflection;
using System.Collections.Generic;//...staticList<string>GetClasses(string nameSpace){Assembly asm =Assembly.GetExecutingAssembly();List<string> namespacelist =newList<string>();List<string> classlist =newList<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;//...staticIEnumerable<string>GetClasses(string nameSpace){Assembly asm =Assembly.GetExecutingAssembly();return asm.GetTypes().Where(type => type.Namespace== nameSpace).Select(type => type.Name);}
Saya tidak berusaha menjadi kejam, tetapi ada daftar dan iterasi yang sama sekali tidak perlu melalui semua item yang ditemukan dalam kode ini; variabel "classlist" dan foreach melalui "namespacelist" tidak memberikan fungsi yang berbeda dengan mengembalikan "namespacelist"
TheXenocide
10
@TheXenocide tujuan dari contoh kode tidak selalu dimaksudkan untuk menunjukkan cara "terbaik" untuk menulis kode, tetapi untuk secara jelas menyampaikan bagaimana sesuatu dilakukan.
Ryan Farley
4
Saya baru saja menunjukkannya demi pendidikan; itu adalah tanggung jawab kita untuk membuat materi yang orang pelajari dari contoh terbaik kita daripada mengambil risiko contoh buruk yang secara negatif mempengaruhi pemahaman. Saya tidak mengatakan ini secara khusus merugikan, tetapi saya tidak setuju dengan sentimen
TheXenocide
4
Saya memilih jawaban jika tidak membantu pertanyaan yang diajukan. Petunjuk yang Anda lihat saat Anda mengarahkan kursor ke tombol suara naik / turun mengatakan "Ini sangat membantu". Keputusan untuk memilih naik / turun jawaban, bagi saya, adalah apakah itu membantu atau tidak dalam menjawab pertanyaan yang diajukan.
Ryan Farley
3
Satu-satunya hal yang Anda gunakan dua daftar dan dua iterasi membantu adalah memperlambat saya mencoba mencari tahu mengapa Anda menggunakan dua daftar dan tidak hanya menambahkan langsung classlistpada iterasi pertama atas asm.GetTypes()hasilnya.
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 assembliesAppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve+=newResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);Assembly a =System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();// process types here// method later in the class:staticAssemblyCurrentDomain_ReflectionOnlyAssemblyResolve(object sender,ResolveEventArgs args){returnSystem.Reflection.Assembly.ReflectionOnlyLoad(args.Name);}
Itu akan membantu dengan memuat jenis yang didefinisikan dalam majelis lain.
Tentu terlihat membantu, dan kurang membantu dan kurang membingungkan daripada kode Ryan Farley bahkan tanpa memikirkannya
ProfK
Anda juga membuat saya bingung untuk sementara waktu. Saya masih hanya bisa menebak bahwa Assembly abarang - barang tersebut mewakili pemrosesan normal yang mungkin menyebabkan peristiwa ini memanas. Saya melihat tidak ada gunanya amembantu dengan LoaderExceptionkesalahan. Apakah saya benar?
ProfK
9
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().
+1 untuk jawaban yang benar. AppDomain.CurrentDomain.GetAssembliesdapat membantu.
nawfal
... dan kemudian memutarnya, memfilter yang tidak cocok dengan namespace.
TJ Crowder
OP secara khusus meminta "kelas dalam ruang nama", sedangkan ini membuat Anda "mengetik dalam sebuah majelis" - jadi jawaban ini tidak lengkap. Jawaban yang benar mungkin adalah yang ini , yang menyebutkan kelas saja, dari semua majelis.
mindplay.dk
6
Sama seperti jawaban @aku, tetapi menggunakan metode ekstensi:
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{classProgram{staticvoidMain(string[] args ){Console.WriteLine(" START ");// what is in the assemblyAssembly 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 #endregionConsole.ReadLine();Console.WriteLine(" HIT A KEY TO EXIT ");Console.WriteLine(" END ");}}//eof ProgramclassClassOne{}//eof class classClassTwo{}//eof class[System.AttributeUsage(System.AttributeTargets.Class|System.AttributeTargets.Struct,AllowMultiple=true)]publicclassAttributeClass:System.Attribute{publicstringMustHaveDescription{get;set;}publicstringMusHaveVersion{get;set;}publicAttributeClass(string mustHaveDescription,string mustHaveVersion ){MustHaveDescription= mustHaveDescription;MusHaveVersion= mustHaveVersion;}}//eof class }//eof namespace
Tentang apa AttributeClassnama itu MustHaveAttributes? Saya tidak melihat apa pun yang berkaitan dengan pengujian apakah suatu kelas memiliki atribut atau tidak. Ini lebih membingungkan daripada membantu.
ProfK
1
Cukup sederhana
Type[] types =Assembly.Load(newAssemblyName("mynamespace.folder")).GetTypes();foreach(var item in types){}
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.
sumber
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:Ini akan berfungsi kecuali jika Anda ingin kelas domain lain. Untuk mendapatkan daftar semua domain, ikuti tautan ini.
sumber
&& 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, danGetAssemblies().SelectMany(t => t.GetTypes())
akan memberikan semua jenis (kelas, struct dll) dari semua majelis.Assembly.Load(nameof(NameOfMyNamespace))
bekerja dengan baik.NB: Kode di atas menggambarkan apa yang terjadi. Jika Anda ingin menerapkannya, versi yang disederhanakan dapat digunakan:
sumber
classlist
pada iterasi pertama atasasm.GetTypes()
hasilnya.Untuk Majelis tertentu, NameSpace dan ClassName:
Catatan: Proyek harus merujuk perakitan
sumber
Berikut ini adalah perbaikan untuk kesalahan LoaderException yang mungkin Anda temukan jika salah satu dari jenis-jenis itu menutupi suatu jenis dalam rakitan lain:
Itu akan membantu dengan memuat jenis yang didefinisikan dalam majelis lain.
Semoga itu bisa membantu!
sumber
Assembly a
barang - barang tersebut mewakili pemrosesan normal yang mungkin menyebabkan peristiwa ini memanas. Saya melihat tidak ada gunanyaa
membantu denganLoaderException
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 memanggilnyaGetTypes()
.sumber
AppDomain.CurrentDomain.GetAssemblies
dapat membantu.Sama seperti jawaban @aku, tetapi menggunakan metode ekstensi:
sumber
Dapatkan semua kelas dengan bagian nama Namespace hanya dalam satu baris:
sumber
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 ()
sumber
sumber
AttributeClass
nama ituMustHaveAttributes
? Saya tidak melihat apa pun yang berkaitan dengan pengujian apakah suatu kelas memiliki atribut atau tidak. Ini lebih membingungkan daripada membantu.Cukup sederhana
sumber