C# Как прочитать имена всех переменных родительского и дочернего классов из дочернего класса

#c#

Вопрос:

я хочу перечислить свои переменные(защищенные,общедоступные) из абстрактного родительского класса и унаследованного класса.

 abstract class Parent 
{
   public string var1 = "something";            
   public virtual GetAllVar() 
   {
      foreach(var item in AllVarOfMyClassCurrent) 
      {
         Console.Writeline(item.Name " - ");
      }
   }            
}
    
class Child : Parent 
{
    public string var2 = "somethingAgain";
}
    
Child c = new Child();
c.GetAllVar();
 

С помощью базы методов мой результат таков :
Var1 —

Результат, который я бы дал : Var1 — Var2 —

Спасибо

Комментарии:

1. Что находится внутри «AllVarOfMyClassCurrent»? Где это определено?

2. Какова цель этого? Это только для печати свойств класса для отладки? Для сериализации?

3. @Mohsenne AllVarOfMyClassCurrent это то, что я хочу по справедливости, это метод или что-то еще, чтобы получить переменные.

4. @JonasH да, это для сериализации, в основном в подписи

5. Есть ли какая-либо причина, по которой вы не можете использовать существующие библиотеки сериализации? Как правило, подобные вещи требуют много размышлений, и существуют библиотеки, которые уже проделали тяжелую работу.

Ответ №1:

Попробуйте использовать отражение, чтобы получить поля класса. Что-то вроде этого:

 abstract class Parent
{
    public string var1 = "something";

    public void GetAllVar()
    {
        foreach (var item in GimmeTheFields())
        {
            Console.WriteLine(item.Name   " - ");
        }
    }

    private FieldInfo[] GimmeTheFields()
    {
        // necessary bingind flags to retrieve public, private, protected fields.
        var bindingFlags = BindingFlags.Instance |
               BindingFlags.NonPublic |
               BindingFlags.Public;

        // get current type's fields
        var fields = this.GetType().GetFields(bindingFlags);
        
        // Check if current type has a parent
        var baseType = this.GetType().BaseType;
        while(baseType != null)
        {
            // if so, union properties that we have access to from subtype
            // to those properties we can get from basetype
            var parentFields = baseType.GetFields(bindingFlags);
            fields = parentFields.Union(fields).ToArray();

            // now let's analyze baseType's basetype :)
            baseType = baseType.BaseType;
        }

        return fields;
    }
}

class Child : Parent
{
    public string var2 = "somethingAgain";
}

public static void Main(string[] args)
{
    Child c = new Child();
    c.GetAllVar();
}
 

Выход:

 var1 -
var2 -
 

Но действительно ли вам это нужно? Возможно, вы можете использовать некоторые существующие библиотеки сериализации.

Ответ №2:

Спасибо @Dorin Baba

Я уже видел флаги, значит, с вашим ответом все в порядке :

         private FieldInfo[] GetFields()
        {
            BindingFlags allFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
            return this.GetType().GetFields(allFlags);
        }
 

Комментарии:

1. Да, но с этим методом есть проблема. Если родительский var1 является частным, вы не получите это свойство, вот почему я ввел этот цикл while. Если var1 является частным, ребенок даже не знает о его существовании, потому что он является частным и содержится в родительском классе 🙂 Но если var2 является частным, что является собственностью ребенка, вы получите его