2013-03-12 32 views
14

Tôi có một lớp tĩnh chứa rất nhiều lớp tĩnh. Mỗi lớp tĩnh bên trong chứa các trường. Tôi muốn lấy tất cả các trường của tất cả các lớp tĩnh bên trong.Nhận tất cả các trường từ các lớp tĩnh bên trong lớp tĩnh với sự phản chiếu

public static class MyClass 
{ 
    public static class MyInnerClass1 
    { 
     public const string Field1 = "abc"; 
     public const string Field2 = "def"; 
     public const string Field3 = "ghi"; 
    } 
    public static class MyInnerClass2 
    { 
     public const int Field1 = 1; 
     public const int Field2 = 2; 
     public const int Field3 = 3; 
    } 
    ... 
} 

Tôi muốn in tên của mỗi lớp bên trong theo sau là tên và giá trị của từng trường.

Ví dụ:

MyInnerClass

Field1 = "abc"

...

Tôi không có vấn đề với việc tên của tất cả các lớp:

var members = typeof(MyClass).GetMembers(BindingFlags.Public | BindingFlags.Static); 

var str = ""; 
foreach (var member in members) 
{ 
    str += member.Name +" ";    
} 

Hoặc tên và giá trị của tất cả các lĩnh vực trong một lớp học cụ thể:

var fields = typeof(MyClass.MyInnerClass1).GetFields(); 
foreach (var field in fields) 
{ 
    str += field.Name + "-"; 
    str += field.GetValue(typeof(MyClass.MyInnerClass1)); 
} 

Nhưng làm thế nào để kết hợp này? Tên và số lượng lớp tĩnh bên trong có thể thay đổi.

Trả lời

16

Hãy thử như sau

var builder = new StringBuilder(); 
foreach (var type in typeof(MyClass).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)) 
{ 
    if (!type.IsAbstract) 
    { 
    continue; 
    } 

    builder.AppendLine(type.Name); 
    foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { 
    var msg = String.Format("{0} = {1}", field.Name, field.GetValue(null)); 
    builder.AppendLine(msg); 
    } 
} 

string output = builder.ToString(); 

Việc sử dụng !type.IsAbstract được thực hiện để cỏ dại trên các loại lồng không tĩnh. Một loại tĩnh trong C# được tạo ra như abstract dưới mui xe.

Giải pháp của tôi cũng sẽ nhận cả hai thành viên public và không công khai (cả loại và trường). Tôi không chắc đây có phải là ý định của bạn hay không, vì vậy bạn có thể muốn sửa đổi phần đó trong giải pháp của tôi.

9

Bạn cần phải đệ quy lặp qua type.GetNestedTypes():

IEnumerable<FieldInfo> GetAllFields(Type type) { 
    return type.GetNestedTypes().SelectMany(GetAllFields) 
       .Concat(type.GetFields()); 
} 
Các vấn đề liên quan