Wie erhalten Sie alle Klassen in einem Namespace durch Reflektion in C#?Alle Typen in einem Namespace über Reflektion abrufen
Antwort
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;
}
Hinweis: Sie können dies tun, vorausgesetzt, Sie geben die Baugruppe und das NS ein, nach dem gesucht werden soll. Typen können in mehreren Assemblies definiert werden und zum selben NS gehören. – Gishu
Das ist wahr Gishu. Ich nehme an, es wäre besser, sowohl die Assembly als auch den Namespace von der Assembly zu übergeben, die die Mehrdeutigkeit entfernen soll. –
"Namespace" - reserviertes Schlüsselwort, Sie sollten @ Präfix hinzufügen, um diesen Code kompilieren zu lassen – aku
Sie werden nicht alle Typen in einem Namensraum erhalten werden können, da ein Namensraum mehrere Baugruppen überbrücken können, aber Sie können alle Klassen in einer Baugruppe erhalten und prüfen, ob sie zu diesem Namespace gehört.
Assembly.GetTypes()
arbeitet an der lokalen Baugruppe, oder Sie können zuerst eine Baugruppe laden und dann GetTypes()
darauf aufrufen.
+1 für die richtige Antwort. 'AppDomain.CurrentDomain.GetAssemblies' kann hilfreich sein. – nawfal
... und dann durch sie hindurchgehen und diejenigen herausfiltern, die nicht mit dem Namespace übereinstimmen. –
Der folgende Code gibt Namen von Klassen in der angegebenen namespace
Klasse aus, die in der aktuellen Baugruppe definiert sind.
Wie andere Kerle darauf hingewiesen haben, kann ein Namespace zwischen verschiedenen Modulen verteilt sein. Daher müssen Sie zuerst eine Liste von Assemblys abrufen.
Namensräume sind eigentlich eher passiv im Design der Laufzeit und dienen in erster Linie als organisatorische Werkzeuge. Der vollständige Name eines .NET-Typs besteht aus dem Namespace und Class/Enum/Etc. kombiniert. Wenn Sie nur eine bestimmte Baugruppe durchgehen möchten, durchlaufen Sie einfach die von der Baugruppe zurückgegebenen Typen. GetExportedTypes() Überprüfung des Wertes des Typs. Namespace. Wenn Sie versuchen würden, alle in der aktuellen Anwendungsdomäne geladenen Assemblys zu durchlaufen, würde dies die Verwendung von AppDomain.CurrentDomain erfordern. GetAssemblies()
Hier ist ein Update für Loader Fehler Sie wahrscheinlich zu finden, wenn einer der Typen ein Typ in einer anderen Baugruppe sublasses:
// 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);
}
, die mit Ladearten in anderen Baugruppen definiert helfen sollte.
Hoffe, dass hilft!
Sicher sieht hilfreich aus, und weniger hilfreich und weniger verwirrend als Ryan Farleys Code, auch ohne darüber nachzudenken. – ProfK
Sie haben mich auch für eine Weile verwirrt. Ich kann immer noch nur vermuten, dass das 'Assembly-a'-Material die normale Verarbeitung darstellt, die dieses Ereignis auslösen könnte. Ich sehe keine Verwendung von 'a' in' LoaderException'-Fehlern. Habe ich recht? – ProfK
//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
Was ist'AttributeClass'? Der Name 'MustHaveAttributes' geht um? Ich sehe nichts in Bezug auf das Testen, ob eine Klasse Attribute hat oder nicht. Das ist verwirrender als hilfreich. – ProfK
Genau wie @aku Antwort, aber mit Erweiterungsmethoden:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
Wie FlySwat sagt, können Sie den gleichen Namensraum in mehreren Baugruppen Spanning haben (zB System.Collections.Generic
). Sie müssen alle diese Assemblys laden, wenn sie nicht bereits geladen sind. Also für eine vollständige Antwort:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Dies sollte funktionieren, es sei denn, Sie möchten Klassen anderer Domänen. Um eine Liste aller Domains zu erhalten, folgen this link.
funktioniert gut - eine kleine Erinnerung: Ich habe versucht, "' && t.Namespace == @ Namespace "zu entfernen - was für mich ** alle ** .net Assemblys :-) – Netsi1964
@ Netsi1964, wenn Sie' && t entfernen.Namespace == @ Namespace Sie erhalten alle * Klassen * von * allen Assemblies *, einschließlich .net's. 'GetAssemblies' gibt Ihnen alle Assemblys und' GetAssemblies(). SelectMany (t => t.GetTypes()) 'gibt alle Typen (Klassen, Strukturen usw.) von allen Assemblies. – nawfal
Holen Sie sich alle Klassen, indem einen Teil des Namen Namespace in nur eine Zeile:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Für eine bestimmte Assembly mit einem Klassennamen Filter:
var asm = Assembly.Load("Some.Assembly.Name");
var nameSpace = "Some.Namespace.Name";
var classes = asm.GetTypes().Where(p =>
p.Namespace == nameSpace &&
p.Name.Contains("ClassNameFilter")
).ToList();
Hinweis: das Projekt muss die Baugruppe
Ganz einfach
ReferenzType[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}
können Sie Ihre Frage bearbeiten ... die Subtextfrage ist kommunikativer als der 'Namespace in C#' – Gishu
Sie können [hier] (http: // stackoverflow.com/questions/949246/how-to-alle Klassen innerhalb Namespace zu bekommen. Es gibt 2 verschiedene Proben. –