Reflection e membri di classe base

Ieri mi è capitato di dover recuperare tutti i "campi" pubblici e non di una classe, della sua classe base, della base della sua base, della... vabè, ci siamo capiti!

Non veniva volutamente considerata l'ereditarietà multipla (d'altronde non è contemplata neanche nelle CLS).

Il modo che ho trovato io, che probabilmente sarà ben lungi dall'essere definito come il migliore, è semplicemente quello fare la ricerca in tute le classi base fino ad arrivare al null.

Un pochino di attenzione hanno meritato i campi protected, che sono giustamente visibili nella classe derivata, ma lo sono anche nella classe base. Il flag BindingFlags.NonPublic giustamente recupera sia quelli privati che quelli protetti e per capire se sono protected (ed escluderli, in quanto presenti già nella classe derivata) basta verificare che non siano nè pubblici, nè privati!

Se può interessare allego un esempietto:

    class ReflectionTests
    {
        
public static void DoTest()
        {
            Type t = 
typeof(BB);

            BindingFlags flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            
bool includeProtected = true;

            Console.WriteLine("----------------------------------------");

            
while (t != null)
            {
                Console.WriteLine(
string.Concat("Type: ", t.Name)); 

                WriteFields(t, flags, includeProtected);

                flags = BindingFlags.Instance | BindingFlags.NonPublic;
                includeProtected = 
false;

                Console.WriteLine("----------------------------------------");

                t = t.BaseType;
            }
        }

        
private static void WriteFields(Type t, BindingFlags flags, bool includeProtected)
        {
            FieldInfo[] fields = t.GetFields(flags);
            Console.WriteLine("Fields:");
            
foreach (FieldInfo f in fields)
            {
                
if (includeProtected || (f.IsPrivate || f.IsPublic))
                {
                    Console.WriteLine(
string.Format("Name: {0} | IsPrivate: {1} | IsPublic: {2}", f.Name, f.IsPrivate, f.IsPublic));
                }
            }
            Console.WriteLine();
        }
    }

    
class AA : MyBase
    {
        
public string aaPublicField = string.Empty;
        
private string aaPrivateField = string.Empty;
        
protected string aaProtectedField = string.Empty;
    }

    
class BB : AA
    {
        
private string bbPrivateField = string.Empty;
        
private string bbProtectedField = string.Empty;
        
private string bbPublicField = string.Empty;
    }

    
class MyBase
    {
        
private string basePrivateField = string.Empty;
        
protected string baseProtectedField = string.Empty;
    }

 

 

Print | posted @ venerdì 11 agosto 2006 13:33

Comments have been closed on this topic.