Getting property name and distinct values of a type T from a List<T> with reflection

c#, propertyinfo, reflection

Solution

So it sounds like you're asking for something slightly different than the rest of us previously thought. You're not looking for the number of distinct values, or you're looking for the number of duplicates of each distinct value, which is essentially a group-by with a count of each group.

private static Dictionary<string, Dictionary<object, int>> 
    getDistinctValues<T>(List<T> list)
{
    var properties = typeof(T).GetProperties();

    var result = properties
        //The key of the first dictionary is the property name
        .ToDictionary(prop => prop.Name,
            //the value is another dictionary
            prop => list.GroupBy(item => prop.GetValue(item, null))
                //The key of the inner dictionary is the unique property value
                //the value if the inner dictionary is the count of that group.
                .ToDictionary(group => group.Key, group => group.Count()));

    return result;
}

At one point I had broken this up into two methods, but I condensed it down a bit to the point where I don't think it's needed. If you have trouble wrapping your head around all of the levels of nesting of this query feel free to ask for further clarifications.

Problem

I have a class Product with a set of properties: ``` public class Product { public string Id { get; set; } public string Name { get; set; } public string Categories { get; set; } } ``` From a component, I obtain a `List<Product>` and, for several reasons, I need to use Reflection to get the properties of `Product` and then get the `Distinct` values and their `Count()` for each property. Is it possible to achieve my goal through reflection? If not is there any other way to do it? Thanks! UPDATE The problem is that I do not know in advance which properties I have to use and which properties are in the `Product` class. That's why I think reflection is the best option. I can achieve the same result by using a `Switch - Case` construct where the switch compare the Property Name extarcted from the class and each `Case` corresponds to a specific Property Name. But the flexibility of this solution is not enough for my problem

Original source