Перебор свойств объекта в C#

У меня есть список Объектов Типа Клиента, и когда я перебираю этот список, я хотел бы иметь возможность перебирать свойства каждого Клиента. Затем я хотел бы распечатать это значение свойства в виде строки. Я получаю ошибку StackOverFlowException.

Позвольте мне предварить это словами:

  1. Это всего лишь библиотека классов, я вызываю функцию из другого места, и этот вызов работает.
  2. Вызов базы данных и возвращаемой информации верен (я проверил ее, прежде чем пытаться перебрать свойства)
  3. Моя конечная цель - преобразовать Список клиентов в 2D-массив, где каждый столбец представляет клиента, а каждая строка представляет свойства Клиента.

Заранее спасибо!

    using Dapper;
    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Xml.Linq;
    using System.Reflection.Emit;
    using System.Reflection;
    using System.Collections;

    namespace AtoCLib
    {
        public class DataAccessLayer
        {
            public static List<Customer> GetCustomerList(string startChar)
            {
                string sql = $"SELECT TOP (10) P.LastName, [CustomerID],[PersonID] ,[StoreID] ,[TerritoryID] ,[AccountNumber] FROM [AdventureWorks2017].[Sales].[Customer] C INNER JOIN [Person].[Person] P ON C.CustomerID = P.BusinessEntityID WHERE P.LastName >= '{startChar}'";
                List<Customer> CustomerList = new List<Customer>();

                try
                {
                    using (var connection = new SqlConnection("Data Source=SHCP-2035;Initial Catalog=AdventureWorks2017;Integrated Security=True"))
                    {
                        var Customers = connection.Query<Customer>(sql).AsList();

                        foreach (Customer customer in Customers)
                        {
                            CustomerList.Add(customer);
                        }
                    }
                }
                catch (Exception e)
                {

                    Console.Write(e);
                }

                return CustomerList;
            }

            public static void getCustListArray(string nameChar)
            {
                List<Customer> list = GetCustomerList(nameChar);
                string[,] customerArray = new string[10, 6];

                foreach (Customer customerObj in list)
                {
                    Customer tempCustomer = new Customer();
                    tempCustomer = customerObj;

                    foreach (PropertyInfo property in tempCustomer)
                    {
                        Console.WriteLine(property.GetValue(tempCustomer));
                    }
                }
            }
        }

        public class Customer : IEnumerable<PropertyInfo>
        {
            public int CustomerID { get; set; }
            public int? PersonID { get; set; }
            public int? StoreID { get; set; }
            public int? TerritoryID { get; set; }
            public string AccountNumber { get; set; }
            public string lastName { get; set; }

            public IEnumerator<PropertyInfo> GetEnumerator()
            {
                return GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }
    }

Ошибка:

Process is terminated due to StackruException.

2 ответа

Решение
public IEnumerator<PropertyInfo> GetEnumerator()
{
    return GetEnumerator();
}

Этот метод вызывает сам себя, в итоге ваш стек переполнится. Реализуйте это правильно:

public IEnumerator<PropertyInfo> GetEnumerator()
{
    foreach (var property in typeof(Customer).GetProperties())
    {
        yield return property;
    }
}

Да, вы получаете эту ошибку, потому что ваш метод Customer.GetEnumerator() вызывает себя, а затем снова, и это создает бесконечную рекурсию. Для получения всех открытых свойств объекта используйте следующий код в этом методе:

return this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

Но я думаю, что это не правильный способ сделать это внутри GetEnumerator() метод. Ваш класс не коллекция, или что-то вроде. Итак, используйте метод GetProperties() прямо из метода getCustArray():

foreach (PropertyInfo property in tempCustomer.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
    Console.WriteLine(property.GetValue(tempCustomer));
}
Другие вопросы по тегам