0

So I have a list of Objects lets say for example:

var animals = new List<Animal>() //add Animals`

I know I can convert these to strings from This Question like:

List<Animal> animals = new List<Animal>();
List<string> strings = animals.Select(a => (string)a).ToList();

BUT I would like to get List<string> from the list of animals based on a property that I feed in as a string at runtime

For example:

private List<string> GetList(string property)
{
    return animals.Select(x => filterByReflection(property)).ToList();
}

so I can call:

var names = GetList("Name");
var types = GetList("Type");
var ages = GetList("Age");

Is this possible?

5 Answers 5

2

Full working example:

class Program
{
    static List<Animal> animals = new List<Animal>();

    static void Main(string[] args)
    {
        animals.Add(new Animal() { Age = 3, Name = "Terry", Type = "Tiger" });
        animals.Add(new Animal() { Age = 1, Name = "Bob", Type = "Badger" });
        animals.Add(new Animal() { Age = 7, Name = "Alfie", Type = "Dog" });

        GetList("Age").ForEach(Console.WriteLine);

        Console.Read();
    }

    public static List<string> GetList(string property)
    {
        return animals.Select(o => o.GetType().GetProperty(property).GetValue(o).ToString()).ToList();
    }
}

class Animal
{
    public string Name { get; set; }
    public string Type { get; set; }
    public int Age { get; set; }
}
Sign up to request clarification or add additional context in comments.

Comments

2

Yes, something like this:

private List<string> GetList(string property)
{
    return animals.Select(x => GetProperty(x, property)).ToList();
}

private static string GetProperty(Animal animal, string property)
{
    Type type = typeof(Animal);
    PropertyInfo propertyInfo = type.GetProperty(property);
    return (string)propertyInfo.GetValue(animal);
}

Comments

0

So I found I can use these methods to get PropertyInfo via Reflection

private string GetValue(object item, string propString)
    {
        if (item != null)
        {
            if (!string.IsNullOrEmpty(propString))
            {
                try
                {
                    var property = GetProperty(item.GetType().GetTypeInfo(), AutoCompleteSourceMember);
                    if (property != null)
                    {
                        var value = property.GetValue(item);
                        if (value != null)
                        {
                            return value.ToString();
                        }

                    }
                    return string.Empty;

                }
                catch (Exception ex)
                {
                    return string.Empty;
                }
            }
            else
            {
                return item.ToString();
            }
        }
        return string.Empty;
    }

    private static PropertyInfo GetProperty(TypeInfo typeInfo, string propertyName)
    {
        var propertyInfo = typeInfo.GetDeclaredProperty(propertyName);
        if (propertyInfo == null && typeInfo.BaseType != null)
        {
            propertyInfo = GetProperty(typeInfo.BaseType.GetTypeInfo(), propertyName);
        }
        return propertyInfo;
    }

and use it like:

private List<string> GetList(string property)
{
    return animals.Select(x => GetValue(x,property)).ToList();
}

Comments

0

Since you know that they are strings you can directly cast the result of filterByReflection to a string:

private List<string> GetList(string property)
{
    return animals.Select(x => (string)filterByReflection(property)).ToList();
}

More generally you can make this method generic:

private List<T> GetList<T>(string property)
{
    return animals.Select(x => (T)filterByReflection(property)).ToList();
}

Of course if you pass in a property name that does not return a string in the first case or a T in the second you will get an InvalidCastException at run time.

Comments

0

A generic function:

public static class Extensions
{
    public static IEnumerable<P> SelectProperty<T, P>(this IEnumerable<T> source, string propertyName)
    {
        var selector = (Func<T, P>)Delegate.CreateDelegate(typeof(Func<T, P>), typeof(T).GetProperty(propertyName).GetGetMethod());
        return source.Select(selector);
    }
}

and usage:

private List<string> GetList(string property)
{
    return animals.SelectProperty<Animal, string>(property).ToList();
}

This is the fastest reflection based approach, because reflection is done just once instead of for each item as in other answers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.