Доступ к полям вложенных объектов - PullRequest
0 голосов
/ 16 июня 2020

Я хочу получить доступ к именам полей объекта, который вложен в структуру следующим образом:

public class Playerframe
{
  public string Attr1;
  public string Attr2;
}

public class MatchMoment
{
  public int MomentNr;
  public Dictionary <int, Playerframe> PlayerData;
}

public DataTable CreateTable (List<dynamic>Moments)
{
 DataTable table = new DataTable();
 List<string> = Moments[0]...... 

 /// get all class Properties, including the Playerframe properties in order 
 /// to create correctly named DataTable columns
 /// The List<string> should finally contain {"MomentNr","Attr1","Attr2"}

 return table;
}

Теперь мой вопрос будет заключаться в том, как получить доступ к именам полей (например, Attr1), хранящимся в значение словаря в объекте объекта MatchMoment с использованием System.Reflection?

Я хочу написать функцию, которая создает объект с данными из свойств любого данного объекта, который определен в параметре метода, как показано выше.

Спасибо за вашу помощь!

Макс

1 Ответ

1 голос
/ 17 июня 2020

Я думаю, что следующий фрагмент может дать вам то, что вы хотите. По сути, он выполняет итерацию по свойствам типа элемента списка, чтобы получить их имена, а в случае общего типа свойства c рекурсивно получает имена свойств аргументов универсального типа c.

public DataTable CreateTable(List<dynamic> Moments)
{
    var table = new DataTable();

    var elementType = GetElementType(Moments);
    var propertyNames = GetPropertyNames(elementType);

    // Do something with the property names . . .

    return table;
}

private static Type GetElementType(IEnumerable<dynamic> list) =>
    list.GetType().GetGenericArguments()[0];

private static IEnumerable<string> GetPropertyNames(Type t)
{
    return t.GetProperties().SelectMany(getPropertyNamesRecursively);

    IEnumerable<string> getPropertyNamesRecursively(PropertyInfo p) =>
        p.PropertyType.IsGenericType
            ? p.PropertyType.GetGenericArguments().SelectMany(GetPropertyNames)
            : new[] { p.Name };
}

Обратите внимание, что это смотрит только на свойства, а ваши текущие классы используют исключительно поля. Однако использование свойств считается наилучшей практикой для доступа publi c к данным, поэтому, возможно, стоит изменить ваши поля на свойства. Если вы действительно хотите сохранить их как поля, вам, возможно, придется немного подправить его, но идея рекурсивного развертывания типов generi c остается прежней.

...