KeiStory

C# Reflection 을 이용해 특정 Property 들만 Select 하기

 

List<Class> 데이터모음에서 특정 Property 들만 Select 하는 방법을 알아봅니다.

데이터를 50만건 만들어 ExpandoObject 를 이용하여 처리합니다.

using System.Diagnostics;
using System.Dynamic;
using System.Reflection;

namespace PropertySelectTest
{
    internal class Program
    {
        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public string City { get; set; }
            public string Country { get; set; }
            public string Job { get; set; }
            public string Company { get; set; }
            public int Salary { get; set; }
            public int Experience { get; set; }
            public string Department { get; set; }
            public string Education { get; set; }
            public string Phone { get; set; }
            public string Email { get; set; }
            public string Address { get; set; }
            public string ZipCode { get; set; }
            public string State { get; set; }
            public string Gender { get; set; }
            public string Nationality { get; set; }
            public DateTime BirthDate { get; set; }
            public bool IsActive { get; set; }
            public DateTime JoinDate { get; set; }
        }

        public static void Main()
        {
            // 50만 건의 데이터를 생성합니다.
            var people = GenerateData(500000);

            var stopwatch = Stopwatch.StartNew();

            var selectedProperties = new List<string> { "Name", "City", "Job", "Salary", "IsActive", "State", "Gender", "Nationality" };

            var selectedPeople = SelectProperties(people, selectedProperties);

            stopwatch.Stop();
            Console.WriteLine($"Time taken: {stopwatch.ElapsedMilliseconds} ms");

            // 결과를 출력 (몇 건만 샘플로 출력)
            foreach (var person in selectedPeople.Take(10))
            {
                Console.WriteLine($"Name: {person.Name}, City: {person.City}, Job: {person.Job}, Salary: {person.Salary}, IsActive: {person.IsActive}");
            }
        }

        public static List<Person> GenerateData(int count)
        {
            var random = new Random();
            var people = new List<Person>();

            for (int i = 0; i < count; i++)
            {
                people.Add(new Person
                {
                    Name = $"Name_{i}",
                    Age = random.Next(20, 65),
                    City = $"City_{i % 100}",
                    Country = "Country",
                    Job = $"Job_{i % 50}",
                    Company = $"Company_{i % 30}",
                    Salary = random.Next(30000, 150000),
                    Experience = random.Next(1, 40),
                    Department = $"Department_{i % 10}",
                    Education = "Education",
                    Phone = $"Phone_{i}",
                    Email = $"Email_{i}@example.com",
                    Address = $"Address_{i}",
                    ZipCode = $"ZipCode_{i % 1000}",
                    State = "State",
                    Gender = (i % 2 == 0) ? "Male" : "Female",
                    Nationality = "Nationality",
                    BirthDate = DateTime.Now.AddYears(-random.Next(20, 65)),
                    IsActive = (i % 2 == 0),
                    JoinDate = DateTime.Now.AddYears(-random.Next(0, 40))
                });
            }

            return people;
        }

        public static List<dynamic> SelectProperties<T>(List<T> items, List<string> propertyNames)
        {
            // 프로퍼티 정보를 캐시합니다.
            var propertyInfoCache = propertyNames
                .Select(propName => new { Name = propName, Info = typeof(T).GetProperty(propName, BindingFlags.Public | BindingFlags.Instance) })
                .Where(p => p.Info != null)
                .ToList();

            return items.AsParallel().Select(item =>
            {
                var expandoObj = new ExpandoObject() as IDictionary<string, object>;

                foreach (var prop in propertyInfoCache)
                {
                    expandoObj[prop.Name] = prop.Info.GetValue(item);
                }

                return (dynamic)expandoObj;
            }).ToList();
        }
    }
}

결과

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band