Mark Miller Ответов: 2

Есть ли способ получить доступ к общедоступным свойствам класса POCO в виде массива/списка?


Дано:
public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Если я позже определю список< gt; Из Person Объекты:
List<Person> people = new List<Person>();

Я знаю, что могу обрабатывать индивидуальные Person например, объекты в списке, использующие индекс:
Person mom = people[0];

Но могу ли я получить доступ к отдельным свойствам a Person следующим образом?:
string fname = people[0][0];


Что я уже пробовал:

Использование LINQPad 5...

void Main()
{
	
	List<Person> people = new List<Person>();
	people.Add(new Person { FirstName = "Mark", LastName = "Miller" });
	people.Add(new Person { FirstName = "Nancy", LastName = "Miller" });
	
	Person mom = people[1];
	
// this line fails... is there a way around this?
	string fname = mom.Properties[0];

}

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

2 Ответов

Рейтинг:
2

Mark Miller

Спасибо Ричарду - я мог бы изменить свои классы, чтобы включить свойство индекса.
Работа над простым способом сброса содержимого списков в простой CSV-файл для просмотра во время отладки.

Вместо того чтобы иметь несколько методов "сброса", я бы хотел только один.
Спасибо снова.


Richard Deeming

Если вы хотите ответить на решение, нажмите кнопку "есть вопрос или комментарий?" нажмите кнопку под этим решением и оставьте комментарий.

Mark Miller

Понял, спасибо, и спасибо за идею индексатора. Работает как заклинание.

Рейтинг:
12

Richard Deeming

Нет, вам нужно будет использовать имя свойства:

string fname = people[0].FirstName;
Синтаксис, который вы предлагаете, будет работать только в том случае, если в вашем классе есть индексатор:
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    
    public string this[int index]
    {
        get
        {
            switch (index)
            {
                case 0: return FirstName;
                case 1: return LastName;
                default: throw new IndexOutOfRangeException();
            }
        }
    }
}
...
string fname = people[0][0];
Индексаторы - Руководство По Программированию На C# | Microsoft Docs[^]

Если вы хотите перебрать все свойства в своем классе, вам придется использовать отражение или TypeDescriptor.
Отражение (C#) | Microsoft Docs[^]
Класс TypeDescriptor (System.ComponentModel) | Microsoft Docs[^]

Например:
using System.Collections.Generic;
using System.ComponentModel;
...
public static void DumpList<T>(IEnumerable<T> list)
{
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
    foreach (T item in list)
    {
        Console.WriteLine("{");
        foreach (PropertyDescriptor property in properties)
        {
            Console.WriteLine("    {0} = {1}", property.Name, property.GetValue(item));
        }
        Console.WriteLine("}");
    }
}
Использование:
List<Person> people = new List<Person>
{
    new Person { FirstName = "Mark", LastName = "Miller" },
    new Person { FirstName = "Nancy", LastName = "Miller" }
};

DumpList(people);