Create a subset of the object based on an array of property names

I have a class and an array of property names, which are defined as follows:

public class Dog {
    public string Name { get; set; }
    public string Breed { get; set; }
    public int Age { get; set; }
}

var desiredProperties = new [] {"Name", "Breed"};

I also have a method that returns a list of dog objects:

List<Dog> dogs = GetAllDogs();

Is there a way to return a subset dogsthat contains only the properties defined in the array desiredProperties? In the end, this resulting list will be serialized for JSON.

I’ve been struggling with this problem for some time, given that the user will be allowed to specify any combination of properties (provided that they are all valid) as a result in the array. Some more examples:

var desiredProperties = new [] {"Name", "Age"};
// Sample output, when serialized to JSON:
// [
//   { Name: "Max", Age: 5 },
//   { Name: "Spot", Age: 2 }
// ]

var desiredProperties = new [] {"Breed", "Age"};
// [
//   { Breed: "Scottish Terrier", Age: 5 },
//   { Breed: "Cairn Terrier", Age: 2 }
// ]
+4
source share
3 answers

you can write a function for this. Use the extension method below.

public static class Extensions
{
    public static object GetPropertyValue(this object obj, string propertyName)
    {
        return obj.GetType().GetProperty(propertyName).GetValue(obj);
    }

    public static List<Dictionary<string, object>> FilterProperties<T>(this IEnumerable<T> input, IEnumerable<string> properties)
    {
        return input.Select(x =>
        {
            var d = new Dictionary<string, object>();
            foreach (var p in properties)
            {
                d[p] = x.GetPropertyValue(p);
            }
            return d;
        }).ToList();
    }
}

var dogs = GetAllDogs();

var f1 = dogs.FilterProperties(new[]
{
    "Name", "Age"
});

var f2 = dogs.FilterProperties(new[]
{
    "Breed", "Age"
});

Console.WriteLine(JsonConvert.SerializeObject(f1));
Console.WriteLine(JsonConvert.SerializeObject(f2));

[{ "": "", "": 2}, { "Name": "", "": 5}]
[{ "": "-", "": 2}, { "": " ", "": 5}]

+4

, , :

var list = new List<Dog>();
list.Add(new Dog {Name = "Max", Breed = "Bull Terrier", Age = 5});
list.Add(new Dog {Name = "Woofie", Breed = "Collie", Age = 3});
var desiredProperties = new[] {"Name", "Breed"};
var exportDogs = new List<Dictionary<string, object>>();
foreach(var dog in list)
{
    var exportDog = new Dictionary<string, object>();
    foreach(var property in desiredProperties)
    {
        exportDog[property] = dog.GetType().GetProperty(property).GetValue(dog, null);
    }
    exportDogs.Add(exportDog);
}
var output = JsonConvert.SerializeObject(exportDogs);

:

[{"Name":"Max","Breed":"Bull Terrier"},{"Name":"Woofie","Breed":"Collie"}]

, - :

var output = list.Select(dog => new {dog.Name, dog.Breed});

.

0

something like this ... not verified ...

    var desiredProperties = new [] {"Name", "Breed"};
    var lst = (from asm in AppDomain.CurrentDomain.GetAssemblies()
                        from asmTyp in asm.GetTypes()
                        where typeof(dog).IsAssignableFrom(asmTyp) && desiredProperties.All(p=> PropertyExists(asmTyp, p))
                        select asmTyp).ToArray();

    private bool PropertyExists(Type dogType, string name)
    {
        bool ret=true;
        try{ dogType.GetProperty(name);}
        catch{ret=false};

        return ret;
    }
0
source

All Articles