2009-03-26 33 views
17

Tôi là một người mới tuyệt đối trong sự phản ánh trong C#. Tôi muốn sử dụng sự phản chiếu để truy cập tất cả các trường riêng trong một lớp, bao gồm cả các trường được kế thừa.C#: Truy cập các thành viên cá nhân được thừa kế riêng tư thông qua sự phản ánh

Tôi đã thành công trong việc truy cập tất cả các trường riêng tư, ngoại trừ các trường được kế thừa, cũng như tất cả trường công khai và được bảo vệ. Tuy nhiên, tôi đã không thể truy cập vào các trường riêng, được kế thừa. Ví dụ sau minh họa:

class A 
{ 
    private string a; 
    public string c; 
    protected string d; 
} 

class B : A 
{ 
    private string b; 
} 

class test 
{ 
    public static void Main(string[] Args) 
    { 
     B b = new B();  
     Type t; 
     t = b.GetType(); 
     FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic 
             | BindingFlags.Instance); 
     foreach(FieldInfo fi in fields){ 
      Console.WriteLine(fi.Name); 
     } 
     Console.ReadLine(); 
    } 
} 

Không tìm thấy trường B.a.

Thậm chí có thể thực hiện được điều này không? Giải pháp hiển nhiên sẽ là chuyển đổi các trường riêng, được thừa kế thành các trường được bảo vệ. Điều này, tuy nhiên, là ngoài tầm kiểm soát của tôi vào lúc này.

Trả lời

14

Như Lee đã nói, bạn có thể làm điều này với đệ quy.

private static void FindFields(ICollection<FieldInfo> fields, Type t) { 
    var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 

    foreach (var field in t.GetFields(flags)) { 
     // Ignore inherited fields. 
     if (field.DeclaringType == t) 
      fields.Add(field); 
    } 

    var baseType = t.BaseType; 
    if (baseType != null) 
     FindFields(fields, baseType); 
} 

public static void Main() { 
    var fields = new Collection<FieldInfo>(); 
    FindFields(fields, typeof(B)); 
    foreach (FieldInfo fi in fields) 
     Console.WriteLine(fi.DeclaringType.Name + " - " + fi.Name); 
} 
+0

Thay vì mệnh đề "if" để bỏ qua các trường kế thừa, bạn chỉ có thể chỉ định BindingFlags.DeclaredOnly. – Timwi

+0

khi sử dụng BaseType trên một Type, chúng ta có thể truy cập thành viên private class Base không. Không có điều này không giải quyết bất kỳ vấn đề thế giới thực cho tôi, nhưng tôi chỉ tò mò vì sử dụng thuộc tính BaseType của lớp Type tôi tin rằng (trong khi viết nó) tôi đang truy cập Childs lớp cơ sở thành viên, do đó, có cách nào khác với ra bằng cách sử dụng BaseType bất động sản để đạt được như vậy? – Zenwalker

0

Bạn không thể truy nhập các trường riêng tư A bằng cách sử dụng loại B vì các trường đó không tồn tại trong B - chúng chỉ tồn tại trong A. Bạn cần phải chỉ định loại trực tiếp A hoặc truy lục thông qua các phương tiện khác (chẳng hạn như lấy lớp cơ sở từ loại B).

+3

Rác, tất nhiên chúng tồn tại trong B. Nếu chúng không có trong B, làm thế nào một phương pháp được kế thừa từ A truy cập vào trường riêng tư đó ? – Timwi

+4

Ví dụ của B có thể có các thành viên riêng của A, nhưng Loại B không có kiến ​​thức về các thành viên đó. – Andy

4

Tôi chưa thử, nhưng bạn sẽ có thể truy cập vào các thành viên riêng tư kiểu cơ sở thông qua thuộc tính Type.BaseType và tích lũy đệ quy tất cả các trường riêng thông qua hệ thống phân cấp kế thừa.

-1

Bạn có thể truy cập các thành viên tư nhân của loại A từ lớp B với 'Lớp học lồng nhau' . Bạn làm cho lớp A là lớp ngoài và lớp B như lớp bên trong

Class A 
{ 
... 
Class B 
{ 
....... 
    } 

} 
+2

Tôi không thể sửa đổi các lớp học. Tôi chỉ cố gắng thu thập thông tin về họ thông qua sự phản ánh. – Odrade

Các vấn đề liên quan