คุณจะรับคลาสทั้งหมดในเนมสเปซผ่านการสะท้อนใน 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
" - ซึ่งเป็นสาเหตุให้ฉันทั้งหมด . แอสเซมบลีสุทธิ :-)
&& t.Namespace == @namespace
คุณจะได้รับคลาสทั้งหมดของชุดประกอบทั้งหมดรวมถึง. net GetAssemblies
จะให้คุณประกอบทั้งหมดและGetAssemblies().SelectMany(t => t.GetTypes())
จะให้ทุกประเภท (ชั้นเรียน structs ฯลฯ ) จากการประกอบทั้งหมด
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();
หมายเหตุ: โครงการจะต้องอ้างอิงการชุมนุม
นี่คือการแก้ไขข้อผิดพลาด 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 แต่ใช้วิธีการขยาย:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
รับคลาสทั้งหมดโดยเป็นส่วนหนึ่งของชื่อเนมสเปซในแถวเดียว:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
จริง ๆ แล้ว Namespaces ค่อนข้างแฝงอยู่ในการออกแบบรันไทม์และใช้เป็นเครื่องมือขององค์กรเป็นหลัก ชื่อเต็มของประเภทใน. NET ประกอบด้วย Namespace และ Class / Enum / Etc รวม ถ้าคุณเพียงต้องการผ่านแอสเซมบลีเฉพาะคุณเพียงแค่วนรอบชนิดที่ส่งคืนโดยแอสเซมบลี GetExportedTypes ()ตรวจสอบค่าประเภท namespace หากคุณกำลังพยายามผ่านชุดประกอบทั้งหมดที่โหลดใน 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
ทั้งหมดเกี่ยวกับ? ฉันไม่เห็นอะไรเกี่ยวข้องกับการทดสอบว่าคลาสมีคุณสมบัติหรือไม่ นี่คือความสับสนมากกว่าที่เป็นประโยชน์
ค่อนข้างง่าย
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}