Blaise
Blaise

Reputation: 22212

How to access a property of a class by its name?

I find it hard to clearly describe the case in a one-sentence title. Here is the example:

public class Person
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

public enum PersonProperties
{
    FirstName = 1,
    MiddleName = 2,
    LastName = 3
}

I am hoping to do this:

foreach (var p in Persons) {
var nameCollection=new List<string>();
foreach (var s in (SectionsEnum[]) Enum.GetValues(typeof (SectionsEnum)))
{
    nameCollection.Add(p.GetPropertyByName(s);
}
}

Now, how can we implement the GetPropertyByName() part?

Upvotes: 0

Views: 104

Answers (2)

Fredou
Fredou

Reputation: 20100

this should be a good starting point for you

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person() { FirstName ="a", MiddleName = "b", LastName = "c" };

            List<string> result = new List<string>();

            string[] enums = Enum.GetNames(typeof(PersonProperties));

            foreach(string e in enums)
            {
                result.Add(p.GetType().GetProperty(e).GetValue(p, null).ToString());
            }

            int i = 0;
            foreach (string e in enums)
            {
                Console.WriteLine(string.Format("{0} : {1}", e, result[i++]));
            }

            Console.ReadKey(false);
        }
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
    }

    public enum PersonProperties
    {
        FirstName = 1,
        MiddleName = 2,
        LastName = 3
    }
}

Upvotes: 1

Tim S.
Tim S.

Reputation: 56536

You could do this directly using reflection:

public string GetPropertyByName(SectionsEnum s)
{
    var property = typeof(Person).GetProperty(s.ToString());
    return (string)property.GetValue(this);
}

Or maybe with a switch.

public string GetPropertyByName(SectionsEnum s)
{
    switch (s)
    {
        case SectionsEnum.FirstName:
            return this.FirstName;
        case SectionsEnum.MiddleName:
            return this.MiddleName;
        case SectionsEnum.LastName:
            return this.LastName;
        default:
            throw new Exception();
    }
}

But I'd ask if you wouldn't be better served by a wholly different approach, e.g. a list:

public IList<string> NameProperties
{
    get
    {
        return new[] { FirstName, MiddleName, LastName };
    }
}

Or instead of having SectionsEnum, use Funcs:

//was
SectionsEnum s = SectionsEnum.FirstName;
//instead
Func<Person, string> nameFunc = p => p.FirstName;
string name = nameFunc(myPerson);

Upvotes: 1

Related Questions