Получить списки столбцов из неуниверсального IEnumerable с помощью Reflection

У меня есть метод, который принимает универсальный IEnumerable и создает списки уникальных значений для каждого столбца. Излишне говорить, что это очень медленно, я предполагаю, что это связано со всеми используемыми отражениями. Вот пример кода:

private void PopulateReferenceMatrices(IEnumerable newValue)
    {
        Type t = newValue.GetType();
        Type baseType = t.GetGenericArguments()[0];
        PropertyInfo[] properties;
        Dictionary<string, int> indexValues = new Dictionary<string, int>();
        properties = baseType.GetProperties();
        int numProperties = properties.Count(); 
        ListValues = new List<object>[numProperties];
        for (int i = 0; i < numProperties; i++)
        {
            indexValues.Add(properties[i].Name, i);
            FilterValues[i] = new List<object>();
        }
        //populate values into array
        foreach (dynamic da in newValue)
        {
            foreach (PropertyInfo d in properties)
            {
                Object property = d.GetValue(da);
                ListValues[indexValues[d.Name]].Add(property);
            }
        }
    }

Могу ли я создать список значений для каждого свойства, не просматривая IEnumerable построчно и не приводя каждое свойство к объекту?

Есть ли более быстрый способ сделать что-то подобное для каждого элемента в IEnumerable?:

public IList getRowValue(IEnumerable value, string propertyName)
{
    value.Select(x => x.propertyName).ToList();

}

Для чего вы используете отражение, чего вы пытаетесь достичь в целом?

johnny 5 09.05.2019 23:07

Это для пользовательского элемента управления datagrid со списком в каждом headerColumn для фильтрации данных в сетке. ListValues ​​— это значения для проверки или снятия отметки в этих списках. Поскольку у меня нет возможности узнать тип, передаваемый в пользовательскую сетку данных во время выполнения, я должен выяснить это на лету.

Rolan 09.05.2019 23:38

Почему вы используете dynamic da? Что такое GetProperty? Почему вы перебираете PropertyInfo объекты только для того, чтобы передать только d.Name методу?

NetMage 10.05.2019 00:00

Я думал, что динамика может ускорить работу (и в документах сказано, что она в любом случае обрабатывает большинство вещей как объект). Я подумал, что, возможно, есть способ более легкого извлечения свойства из динамической ссылки. GetProperty был вызовом функции CompilerServices.Versioned.CallByName, потому что кто-то написал, что это быстрее. Это не так (я верну его на GetValue(da). Что касается свойств, то в первый раз я в основном создаю словарь для быстрого доступа к индексу, в другой раз я использую его несколько раз.

Rolan 10.05.2019 00:08

Для чего нужен a? Это кажется ужасно сложным способом получить последовательный список целых чисел, как и выполнение поиска в словаре для получения целого числа. Как насчет for (int j1 = 0; j1 < numProperties; ++j1) ListValues[j1].Add(properties[j1].GetValue(da)); (также int numProperties = properties.Length;). Кроме того, почему это не общий метод с IEnumerable<T>?

NetMage 10.05.2019 01:37

Это вызывается методом onItemsSourceChanged в сетке данных, что дает мне неуниверсальный IEnumerable. Что касается того, почему бы не иметь IEnumerable<T>, я не знаю, можете ли вы сделать это, когда вы наследуете свой класс от существующего объекта WPF (это сделало бы это намного проще)? Если да, то как указать Т в XAML? Код, который вы предлагаете, заполняет значения немного быстрее. Спасибо! Поиск по словарю в основном используется в другом месте кода, где мне нужно получить список на основе имени свойства, всплывающего из события.

Rolan 10.05.2019 07:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
262
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Одна из возможных проблем здесь заключается в том, что вы передаете неуниверсальную коллекцию, которая может быть разными объектами, поэтому создание propertyInfo должно быть внутри цикла, чтобы убедиться, что вы можете прочитать это свойство из объекта. Если вы уверены, что все объекты внутри неуниверсальной коллекции имеют один и тот же тип, вы можете прочитать свойствоInfo вне цикла из первого объекта в списке (если он имеет хотя бы один экземпляр).

Вы можете попробовать это, см. комментарии к коду:

public static IList GetRowValue(IEnumerable value, string propertyName)
{
    // create an arraylist to be the result
    var result = new ArrayList();

    // loop in the objects
    foreach (var item in value)
    {
        // search for a property on the type of the object
        var property = item.GetType().GetProperty(propertyName);

        // if the property was found
        if (property != null)
        {
            // read the property value from the item
            var propertyValue = property.GetValue(item, null);

            // add on the result
            result.Add(propertyValue);
        }
    }

    return result;
}

См. рабочий пример с разными объектами в коллекциях: https://dotnetfiddle.net/bPgk4h

Учитывая, как определяется baseType, это общий IEnumerable<> по какой-то причине передается как IEnumerable.

NetMage 10.05.2019 01:40
Ответ принят как подходящий

Проблема не имела ничего общего с IEnumerable или отражением. Данные не были заполнены в IEnumerable, поэтому он делал тысячи вызовов базы данных, которые я заполнял матрицу. После исправления этой проблемы он загружается в кратчайшие сроки.

Другие вопросы по теме