Làm thế nào để bạn có được tất cả các lớp trong một không gian tên thông qua sự phản chiếu trong C #?
Làm thế nào để bạn có được tất cả các lớp trong một không gian tên thông qua sự phản chiếu trong C #?
Câu trả lời:
Mã sau in tên của các lớp được chỉ namespace
định trong hội đồng hiện tại.
Như những người khác đã chỉ ra, một không gian tên có thể nằm rải rác giữa các mô-đun khác nhau, vì vậy trước tiên bạn cần có một danh sách các cụm.
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));
Như FlySwat nói, bạn có thể có cùng một không gian tên trải dài trong nhiều cụm (ví dụ System.Collections.Generic
). Bạn sẽ phải tải tất cả các hội đồng đó nếu chúng chưa được tải. Vì vậy, để có một câu trả lời đầy đủ:
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Điều này sẽ hoạt động trừ khi bạn muốn các lớp của các miền khác. Để có được danh sách tất cả các tên miền, hãy theo liên kết này.
&& t.Namespace == @namespace
" - vì lý do đó đã cho tôi tất cả các cụm .net :-)
&& t.Namespace == @namespace
bạn nhận được tất cả các lớp của tất cả các hội đồng , bao gồm cả .net. GetAssemblies
sẽ cung cấp cho bạn tất cả các hội đồng, và GetAssemblies().SelectMany(t => t.GetTypes())
sẽ cung cấp cho tất cả các loại (lớp, cấu trúc, v.v.) từ tất cả các hội đồng.
Assembly.Load(nameof(NameOfMyNamespace))
hoạt động tốt.
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: Đoạn mã trên minh họa những gì đang diễn ra. Nếu bạn thực hiện nó, một phiên bản đơn giản hóa có thể được sử dụng:
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
vào lần lặp đầu tiên trong asm.GetTypes()
kết quả.
Đối với một hội cụ thể, NameSpace và 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();
Lưu ý: Dự án phải tham khảo lắp ráp
Đây là một sửa chữa cho các lỗi LoaderException mà bạn có thể tìm thấy nếu một trong các kiểu con một kiểu trong một cụm khác:
// 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);
}
Điều đó sẽ giúp với các loại tải được xác định trong các hội đồng khác.
Mong rằng sẽ giúp!
Assembly a
thứ đại diện cho quá trình xử lý thông thường có thể gây ra sự kiện này. Tôi thấy không có ích gì a
trong việc giúp đỡ với LoaderException
lỗi. Tôi có đúng không
Bạn sẽ không thể có được tất cả các loại trong một không gian tên, bởi vì một không gian tên có thể kết nối nhiều cụm, nhưng bạn có thể lấy tất cả các lớp trong một cụm và kiểm tra xem chúng có thuộc không gian tên đó không.
Assembly.GetTypes()
hoạt động trên lắp ráp cục bộ hoặc bạn có thể tải một cụm đầu tiên sau đó gọi GetTypes()
nó.
AppDomain.CurrentDomain.GetAssemblies
có thể hữu ích
Giống như @aku trả lời, nhưng sử dụng các phương thức mở rộng:
string @namespace = "...";
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t.Namespace == @namespace)
.ToList();
types.ForEach(t => Console.WriteLine(t.Name));
Nhận tất cả các lớp theo một phần của tên không gian chỉ trong một hàng:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();
Không gian tên thực sự khá thụ động trong thiết kế thời gian chạy và phục vụ chủ yếu như các công cụ tổ chức. Tên đầy đủ của một loại trong .NET bao gồm Không gian tên và Class / Enum / Etc. kết hợp. Nếu bạn chỉ muốn đi qua một hội đồng cụ thể, bạn chỉ cần lặp qua các kiểu được trả về bởi hội đồng. GetExportedTypes () kiểm tra giá trị của loại. Không gian tên . Nếu bạn đang cố gắng đi qua tất cả các hội đồng được tải trong AppDomain hiện tại, nó sẽ liên quan đến việc sử dụng AppDomain.CienDomain. 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
tên MustHaveAttributes
tất cả về? Tôi thấy không có gì liên quan đến việc kiểm tra xem một lớp có thuộc tính hay không. Điều này là khó hiểu hơn là hữu ích.
Khá đơn giản
Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes();
foreach (var item in types)
{
}