Я представляю решение ниже, но в идеале вам следует попытаться сломать абстракцию для этой проблемы, которая позволяет объекту, возвращающему IEnumerable<T>
, предоставить список «фильтруемых» свойств T
вместе со значениями, которые должны быть использовал. Таким образом, все, что возвращает данные из источника данных, может делать это с полным знанием. Это переносит большую часть работы обратно в ваш источник данных/службу/что-то еще, но делает ваш пользовательский интерфейс намного проще.
Поскольку вы не знаете свойства, вы можете сделать это (я предполагаю, что IEnumerable
, потому что я предполагаю, что общего решения нет, поскольку вы говорите, что вам нужно эм> отражение). Если у вас есть типизированное выражение (т. е. у вас действительно есть List<Product>
), то общее решение будет лучше, поскольку оно избавит вас от необходимости получать первый элемент:
public Dictionary<string, IEnumerable<object>>
GetAllPropertyDistincts(IEnumerable unknownValues)
{
//need the first item for the type:
var first = unknownValues.Cast<object>().First(); //obviously must NOT be empty :)
var allDistinct = first.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(p => new
{
PropName = p.Name,
Distinct = unknownValues.Cast<object>().Select(
o => property.GetValue(o, null)
).Distinct()
}).ToDictionary(v => v.PropName, v => v.Distinct);
}
Теперь у вас есть словарь, содержащий имя свойства каждого отдельного значения для каждого свойства каждого объекта в вашем нетипизированном перечислимом (ну, если предположить, что все они одного типа или базы). Примечание. Могут быть некоторые проблемы со свойствами определенных типов и значением по умолчанию IEqualityComparer
, которое использует метод расширения Distinct
, потому что это общий метод, и на данный момент он будет использовать EqualityComparer<object>.Default
, что не обязательно будет работать для некоторых типов.
Чтобы превратить это в общее решение, вы можете просто изменить первые четыре строки на:
public Dictionary<string, IEnumerable<object>>
GetAllPropertyDistincts<T>(IEnumerable<T> unknownValues)
{
var allDistinct = typeof(T)
С следующей строкой .GetProperties(BindingFlags.Public | BindingFlags.Instance)
, а затем измените внутренний вызов unknownValues.Cast<object>().Select(
на просто unknownValues.Select(
.
person
Andras Zoltan
schedule
02.05.2012
Product
? Они должны быть известны во время компиляции. - person Olivier Jacot-Descombes   schedule 02.05.2012