AngelicCore
AngelicCore

Reputation: 1453

Access object properties by dynamically generating their names from somewhere else(enum)

I am trying to do some optimization on my code. I have an enum:

enum Months { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }

and the following code with an object of a ready made class:

oi.Jan = Math.Round(Convert.ToDecimal(adjAllocation[0]), 2).ToString();
oi.Feb = Math.Round(Convert.ToDecimal(adjAllocation[1]), 2).ToString();
oi.Mar = Math.Round(Convert.ToDecimal(adjAllocation[2]), 2).ToString();
oi.Apr = Math.Round(Convert.ToDecimal(adjAllocation[3]), 2).ToString();
oi.May = Math.Round(Convert.ToDecimal(adjAllocation[4]), 2).ToString();
oi.Jun = Math.Round(Convert.ToDecimal(adjAllocation[5]), 2).ToString();
oi.Jul = Math.Round(Convert.ToDecimal(adjAllocation[6]), 2).ToString();
oi.Aug = Math.Round(Convert.ToDecimal(adjAllocation[7]), 2).ToString();
oi.Sep = Math.Round(Convert.ToDecimal(adjAllocation[8]), 2).ToString();
oi.Oct = Math.Round(Convert.ToDecimal(adjAllocation[9]), 2).ToString();
oi.Nov = Math.Round(Convert.ToDecimal(adjAllocation[10]), 2).ToString();
oi.Dec = Math.Round(Convert.ToDecimal(adjAllocation[11]), 2).ToString();

I'm trying to something do like this(pseudo code):

oi.[Months[i]] = Math.Round(Convert.ToDecimal(adjAllocation[0]), 2).ToString();

I can't just put an array in the class I am making an object from. I need the properties to be strings for the ready made class I am calling.

Upvotes: 1

Views: 95

Answers (2)

Ken Kin
Ken Kin

Reputation: 4693

It's not optimization but an attempt of simplification. Reflection can do this, but seems not simplified at all:

public enum Months {
    Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
}

public partial class SomeClass {
    public String Jan { get; set; }
    public String Feb { get; set; }
    public String Mar { get; set; }
    public String Apr { get; set; }
    public String May { get; set; }
    public String Jun { get; set; }
    public String Jul { get; set; }
    public String Aug { get; set; }
    public String Sep { get; set; }
    public String Oct { get; set; }
    public String Nov { get; set; }
    public String Dec { get; set; }

    public SomeClass(IConvertible[] array) {
        var count=(
            from Months month in Enum.GetValues(typeof(Months))
            let index=(int)month
            where index<array.Length
            select
                typeof(SomeClass).InvokeMember(
                    Enum.GetName(typeof(Months), month),
                    BindingFlags.SetProperty|BindingFlags.Instance|BindingFlags.Public,
                    default(Binder), this,
                    new object[] { Math.Round(array[index].ToDecimal(null), 2).ToString() }
                    )
            ).Count();
    }
}

If the array adjAllocation can be converted to decimal, then it would be an array of IConvertible. So pass it to the constructor of SomeClass, you are done.

Upvotes: 1

bash.d
bash.d

Reputation: 13207

There is System.Enum-class which provides auxilliary methods to support working with enums.
For example, there is Enum.GetName-method to access a specific value. From MSDN:

using System;

public class GetNameTest {
    enum Colors { Red, Green, Blue, Yellow };
    enum Styles { Plaid, Striped, Tartan, Corduroy };

    public static void Main() {

        Console.WriteLine("The 4th value of the Colors Enum is {0}", Enum.GetName(typeof(Colors), 3));
    Console.WriteLine("The 4th value of the Styles Enum is {0}", Enum.Get.   Name(typeof(Styles), 3));
    }
}
// The example displays the following output: 
//       The 4th value of the Colors Enum is Yellow 
//       The 4th value of the Styles Enum is Corduroy

Upvotes: 1

Related Questions