У меня есть метод, который принимает универсальный 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();
}
Это для пользовательского элемента управления datagrid со списком в каждом headerColumn для фильтрации данных в сетке. ListValues — это значения для проверки или снятия отметки в этих списках. Поскольку у меня нет возможности узнать тип, передаваемый в пользовательскую сетку данных во время выполнения, я должен выяснить это на лету.
Почему вы используете dynamic da? Что такое GetProperty? Почему вы перебираете PropertyInfo объекты только для того, чтобы передать только d.Name методу?
Я думал, что динамика может ускорить работу (и в документах сказано, что она в любом случае обрабатывает большинство вещей как объект). Я подумал, что, возможно, есть способ более легкого извлечения свойства из динамической ссылки. GetProperty был вызовом функции CompilerServices.Versioned.CallByName, потому что кто-то написал, что это быстрее. Это не так (я верну его на GetValue(da). Что касается свойств, то в первый раз я в основном создаю словарь для быстрого доступа к индексу, в другой раз я использую его несколько раз.
Для чего нужен a? Это кажется ужасно сложным способом получить последовательный список целых чисел, как и выполнение поиска в словаре для получения целого числа. Как насчет for (int j1 = 0; j1 < numProperties; ++j1) ListValues[j1].Add(properties[j1].GetValue(da)); (также int numProperties = properties.Length;). Кроме того, почему это не общий метод с IEnumerable<T>?
Это вызывается методом onItemsSourceChanged в сетке данных, что дает мне неуниверсальный IEnumerable. Что касается того, почему бы не иметь IEnumerable<T>, я не знаю, можете ли вы сделать это, когда вы наследуете свой класс от существующего объекта WPF (это сделало бы это намного проще)? Если да, то как указать Т в XAML? Код, который вы предлагаете, заполняет значения немного быстрее. Спасибо! Поиск по словарю в основном используется в другом месте кода, где мне нужно получить список на основе имени свойства, всплывающего из события.





Одна из возможных проблем здесь заключается в том, что вы передаете неуниверсальную коллекцию, которая может быть разными объектами, поэтому создание 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.
Проблема не имела ничего общего с IEnumerable или отражением. Данные не были заполнены в IEnumerable, поэтому он делал тысячи вызовов базы данных, которые я заполнял матрицу. После исправления этой проблемы он загружается в кратчайшие сроки.
Для чего вы используете отражение, чего вы пытаетесь достичь в целом?