Können Sie Ihre Frage bearbeiten? Die Subtext-Frage ist kommunikativer als der 'Namespace in C #'
Gishu
Sie können hier schauen . Es gibt 2 verschiedene Beispiele.
Fatih GÜRDAL
Antworten:
316
Der folgende Code druckt Namen von Klassen in der angegebenen namespaceaktuellen Assembly.
Wie andere Leute betonten, kann ein Namespace auf verschiedene Module verteilt sein, daher müssen Sie zuerst eine Liste der Assemblys abrufen.
Wie FlySwat sagt, können Sie denselben Namespace in mehreren Assemblys (z System.Collections.Generic. B. ) verwenden. Sie müssen alle diese Assemblys laden, wenn sie noch nicht geladen sind. Für eine vollständige Antwort:
funktioniert gut - eine kleine Erinnerung: Ich habe versucht, " && t.Namespace == @namespace" zu entfernen - was mir natürlich alle .net-Assemblys gab :-)
Netsi1964
@ Netsi1964 , wenn Sie entfernen && t.Namespace == @namespaceSie alle bekommen Klassen von allen Baugruppen , .net ist inklusive. GetAssembliesgibt Ihnen alle Assemblys und GetAssemblies().SelectMany(t => t.GetTypes())gibt alle Typen (Klassen, Strukturen usw.) aus allen Assemblys an.
Nawfal
Ich habe ein Upgrade auf DotNet Core 2.2 (von 2.1) durchgeführt und dieser Code funktioniert für meine spezifische Assembly nicht mehr. Die Assembly, die ich wollte, wurde nirgendwo im Code referenziert und wurde daher nicht geladen! In 2.1 wurde es geladen, aber 2.2 scheint faul zu laden?
Harvey
@ Harvey Hat .NET Core zunächst eine Appdomain?
Nawfal
@nawfal Ja. Dieser Code funktionierte zuvor in 2.1. Ich fand, dass ich das Laden einer Baugruppe erzwinge, indem ich gut Assembly.Load(nameof(NameOfMyNamespace))funktioniere.
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: Der obige Code zeigt, was los ist. Wenn Sie es implementieren, kann eine vereinfachte Version verwendet werden:
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);}
Ich versuche nicht gemein zu sein, aber es gibt eine völlig unnötige Liste und Iteration durch alle gefundenen Elemente in diesem Code; Die Variable "classlist" und foreach through "namespacelist" bieten keine andere Funktionalität als die Rückgabe von "namespacelist"
TheXenocide
10
@TheXenocide Der Zweck eines Codebeispiels ist nicht immer dazu gedacht, den "besten" Weg zum Schreiben von Code aufzuzeigen, sondern klar zu vermitteln, wie etwas getan wird.
Ryan Farley
4
Ich habe nur aus Gründen der Bildung darauf hingewiesen; Es liegt in unserer Verantwortung, die materiellen Menschen aus dem besten Beispiel zu lernen, das wir können, anstatt ein schlechtes Beispiel zu riskieren, das das Verständnis negativ beeinflusst. Ich sage nicht, dass dies besonders schädlich ist, aber ich bin nicht einverstanden mit dem Gefühl
TheXenocide
4
Ich stimme eine Antwort ab, wenn sie für die gestellte Frage nicht hilfreich ist. Der Hinweis, den Sie sehen, wenn Sie mit der Maus über die Schaltfläche zum Abstimmen nach oben / unten fahren, lautet "Dies war hilfreich". Die Entscheidung, eine Antwort nach oben / unten abzustimmen, ist für mich, ob sie bei der Beantwortung der gestellten Frage hilfreich war oder nicht.
Ryan Farley
3
Das einzige, was Ihnen mit zwei Listen und zwei Iterationen geholfen hat, war, mich zu verlangsamen und herauszufinden, warum Sie zwei Listen verwendet haben und nicht nur classlistbei der ersten Iteration über das asm.GetTypes()Ergebnis direkt hinzugefügt haben .
ProfK
20
Für eine bestimmte Assembly, NameSpace und ClassName:
Hier ist eine Korrektur für LoaderException-Fehler, die Sie wahrscheinlich finden, wenn einer der Typen einen Typ in einer anderen Assembly unterverteilt:
// 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);}
Dies sollte beim Laden von Typen helfen, die in anderen Baugruppen definiert sind.
Sicher sieht es hilfreich aus und ist weniger hilfreich und weniger verwirrend als der Code von Ryan Farley, auch ohne darüber nachzudenken.
ProfK
Du hast mich aber auch eine Weile verwirrt. Ich kann immer noch nur vermuten, dass das Assembly aZeug die normale Verarbeitung darstellt, die dieses Ereignis auslösen könnte. Ich sehe keinen aSinn darin, bei LoaderExceptionFehlern zu helfen . Habe ich recht?
ProfK
9
Sie können nicht alle Typen in einem Namespace abrufen, da ein Namespace mehrere Assemblys überbrücken kann. Sie können jedoch alle Klassen in einer Assembly abrufen und prüfen, ob sie zu diesem Namespace gehören.
Assembly.GetTypes()funktioniert auf der lokalen Assembly, oder Sie können zuerst eine Assembly laden und dann aufrufen GetTypes().
+1 für die richtige Antwort. AppDomain.CurrentDomain.GetAssemblieskann hilfreich sein.
Nawfal
... und durchlaufen sie dann und filtern diejenigen heraus, die nicht mit dem Namespace übereinstimmen.
TJ Crowder
OP hat speziell nach "Klassen in einem Namespace" gefragt, während Sie dadurch "eine Assembly eingeben" - diese Antwort ist also unvollständig. Die richtige Antwort ist wahrscheinlich diese , die nur Klassen aus allen Assemblys auflistet.
mindplay.dk
6
Genau wie @aku Antwort, aber mit Erweiterungsmethoden:
Namespaces sind im Design der Laufzeit eigentlich eher passiv und dienen in erster Linie als organisatorische Werkzeuge. Der vollständige Name eines Typs in .NET besteht aus dem Namespace und Class / Enum / Etc. kombiniert. Wenn Sie nur eine bestimmte Baugruppe durchlaufen möchten, durchlaufen Sie einfach die von der Baugruppe zurückgegebenen Typen. GetExportedTypes () überprüft den Wert des Typs. Namespace . Wenn Sie versuchen würden, alle in der aktuellen AppDomain geladenen Assemblys durchzugehen, müssten Sie AppDomain.CurrentDomain verwenden. 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
Worum geht es bei AttributeClassdem Namen MustHaveAttributes? Ich sehe nichts in Bezug auf das Testen, ob eine Klasse Attribute hat oder nicht. Das ist eher verwirrend als hilfreich.
ProfK
1
Ziemlich einfach
Type[] types =Assembly.Load(newAssemblyName("mynamespace.folder")).GetTypes();foreach(var item in types){}
Und ganz einfach die Frage nicht beantworten. Dazu wird lediglich eine Liste aller Typen in einer einzelnen Assembly abgerufen, unabhängig von einem bestimmten Namespace.
Antworten:
Der folgende Code druckt Namen von Klassen in der angegebenen
namespace
aktuellen Assembly.Wie andere Leute betonten, kann ein Namespace auf verschiedene Module verteilt sein, daher müssen Sie zuerst eine Liste der Assemblys abrufen.
quelle
Wie FlySwat sagt, können Sie denselben Namespace in mehreren Assemblys (z
System.Collections.Generic
. B. ) verwenden. Sie müssen alle diese Assemblys laden, wenn sie noch nicht geladen sind. Für eine vollständige Antwort:Dies sollte funktionieren, es sei denn, Sie möchten Klassen anderer Domänen. Folgen Sie diesem Link, um eine Liste aller Domains zu erhalten .
quelle
&& t.Namespace == @namespace
" zu entfernen - was mir natürlich alle .net-Assemblys gab :-)&& t.Namespace == @namespace
Sie alle bekommen Klassen von allen Baugruppen , .net ist inklusive.GetAssemblies
gibt Ihnen alle Assemblys undGetAssemblies().SelectMany(t => t.GetTypes())
gibt alle Typen (Klassen, Strukturen usw.) aus allen Assemblys an.Assembly.Load(nameof(NameOfMyNamespace))
funktioniere.NB: Der obige Code zeigt, was los ist. Wenn Sie es implementieren, kann eine vereinfachte Version verwendet werden:
quelle
classlist
bei der ersten Iteration über dasasm.GetTypes()
Ergebnis direkt hinzugefügt haben .Für eine bestimmte Assembly, NameSpace und ClassName:
Hinweis: Das Projekt muss auf die Baugruppe verweisen
quelle
Hier ist eine Korrektur für LoaderException-Fehler, die Sie wahrscheinlich finden, wenn einer der Typen einen Typ in einer anderen Assembly unterverteilt:
Dies sollte beim Laden von Typen helfen, die in anderen Baugruppen definiert sind.
Ich hoffe, das hilft!
quelle
Assembly a
Zeug die normale Verarbeitung darstellt, die dieses Ereignis auslösen könnte. Ich sehe keinena
Sinn darin, beiLoaderException
Fehlern zu helfen . Habe ich recht?Sie können nicht alle Typen in einem Namespace abrufen, da ein Namespace mehrere Assemblys überbrücken kann. Sie können jedoch alle Klassen in einer Assembly abrufen und prüfen, ob sie zu diesem Namespace gehören.
Assembly.GetTypes()
funktioniert auf der lokalen Assembly, oder Sie können zuerst eine Assembly laden und dann aufrufenGetTypes()
.quelle
AppDomain.CurrentDomain.GetAssemblies
kann hilfreich sein.Genau wie @aku Antwort, aber mit Erweiterungsmethoden:
quelle
Holen Sie sich alle Klassen nach einem Teil des Namespace-Namens in nur einer Zeile:
quelle
Namespaces sind im Design der Laufzeit eigentlich eher passiv und dienen in erster Linie als organisatorische Werkzeuge. Der vollständige Name eines Typs in .NET besteht aus dem Namespace und Class / Enum / Etc. kombiniert. Wenn Sie nur eine bestimmte Baugruppe durchlaufen möchten, durchlaufen Sie einfach die von der Baugruppe zurückgegebenen Typen. GetExportedTypes () überprüft den Wert des Typs. Namespace . Wenn Sie versuchen würden, alle in der aktuellen AppDomain geladenen Assemblys durchzugehen, müssten Sie AppDomain.CurrentDomain verwenden. GetAssemblies ()
quelle
quelle
AttributeClass
dem NamenMustHaveAttributes
? Ich sehe nichts in Bezug auf das Testen, ob eine Klasse Attribute hat oder nicht. Das ist eher verwirrend als hilfreich.Ziemlich einfach
quelle