Krell
Krell

Reputation: 55

Adding a number to variable names in C#

My question is sort of like the one found here: How do I name variables dynamically in C#? However its a bit different so I'm wondering if its possible.

I'm trying to read in a bunch of strings from a .settings file. I have them all named Time1, Time2,Time3 etc... I want the User to be able to add more Times to the file so there could be Time100 or more. I have a Size in the settings file that will keep track of the amount of Time Variables. I want to write something that will read in all of the Time strings. I think it would be silly to pre-fill the .settings file with 100 Time Variables so I know they are there and then manually read in each one.
So I'm wondering if there is a way where I can read in Timei or Time+i where I is an integer that I can put in a loop that will find them all. (note that the data is string not time, its just going to be converted to days of the week) Such as: (Days is from ApplicationSettingsBase [aka file add new Settings1.settings]

    public static int AvDaysIndex = Days.Default.Size; //This holds the number of items in Days
    public static DayOfWeek[] AvailableDays = new DayOfWeek[AvDaysIndex]; //This is where I wants to read in all the variables Aka Time1 Time2 Times3 


    public ReadInDays() //Reads in from the .settings File
    {
        if(AvDaysIndex>0) // Makes sure there is something in Days to read
        {
              int I=0;
              //I can Manually do the following
               AvailableDays[I++] = Days.Default.Time1;
               AvailableDays[I++] = Days.Default.Time2;
               AvailableDays[I++] = Days.Default.Time3; //etc...


             //Is there a way to do something like this
            for (int i = 0; i < AvDaysIndex; i++) //reads in each time
            { 
                AvailableDays[i] = Days.Default.Time +i;//where I would be added to the variable name to find it?

               //Or something like
               AvailableDays[i] = Days.Default.Time(I.tostring())
            }
        }
    }

Hopefully all that at least makes it clear what I'm trying to do.

Edit - I'm starting to think my issue is actually with the .settings file. and that if I just read values in from another file type where the values don't have names I can easily read them in even though there is a variable number of elements in the file.

Solution -

            for (int i = 0; i < Index; i++)
            {
                AvailableDays[i] = getFromFile(_Days.Default.Properties["Time" + (i+1).ToString()].DefaultValue.ToString());
                AvailableTimes[i] = Convert.ToDateTime(_Times.Default.Properties["Time" + (i + 1).ToString()].DefaultValue);  
            }  

It was all in figuring out how to read in from the .settings file and instead of reading it in directly aka Days.Default.Time1; I had to to do a generic lookup from Days.Default.Properties and then I could create a dynamic name and find it. You guys probably were trying to tell me how to do this, I just didn't understand.

Thanks again to all those that helped.

Upvotes: 2

Views: 10419

Answers (4)

RJ Lohan
RJ Lohan

Reputation: 6527

I think you could better resolve your problem by implementing your configuration using a ConfigurationElementCollection. Then the 'names' of the configuration elements are irrelevant. You enumerate a collection of values and use those directly.

See here for an example; How to implement a ConfigurationSection with a ConfigurationElementCollection.

Upvotes: 0

user2453734
user2453734

Reputation:

As already mentioned a hashtable or a dictionary would probably serve you best. If you go the dictionary route you can create a string/int indexer on the class and you would be able to alter your code slightly:

http://msdn.microsoft.com/en-us/library/2549tw02%28v=vs.80%29.aspx - Example of creating indexer on a class:

Example Indexer Class:

public class Default
{
    private Dictionary<int, DayOfWeek> _values = new Dictionary<int,DayOfWeek>();

    public DayOfWeek this[int index]
    {
        get
        {
            if (_values.ContainsKey(index))
                return _values[index];
            else
                return null;
        }
        set
        {
            _values[index] = value;
        }
    }
}

Original:

AvailableDays[i] = Days.Default.Time(I.tostring())

Would become:

AvailableDays[i] = Days.Default.Time[I];

Reflection is always an option too and i have an example below that is in a Windows Console Application:

public class Default
{
    public int Time1 { get; set; }
    public int Time2 { get; set; }
    public int Time3 { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Default d = new Default();
        Type t = d.GetType();

        foreach (var info in t.GetProperties())
        {
            //SET VALUE
            info.SetValue(d, 1);
        }

        foreach (var info in t.GetProperties())
        {
            //GET VALUE
            Console.WriteLine("Property: {0}", info.Name);
            Console.WriteLine("Value: {0}", info.GetValue(d));
        }

        //OR JUST ONE PROPERTY
        Console.WriteLine("Time1 Property Value: {0}", t.GetProperty("Time1").GetValue(d));

        Console.ReadLine();//PAUSE THE CONSOLE AFTER PROCESSING
    }
}

In your example using reflection:

Days.Default.GetType().GetProperty("Time" + I.ToString()).GetValue(Days.Default) as DayOfWeek;

Upvotes: 2

Ali
Ali

Reputation: 1409

Another option could be to use Reflection. And getting the values from the enum on the fly.

See the link: How to Get Enum Values with Reflection in C#

However, using a Dictionary<string, DayOfWeek> will give you better performance and more readable code.

Upvotes: 2

TGH
TGH

Reputation: 39248

I would use a hashtable/dictionary to store the Days.Default.TimeX variations

hashtable["Time1"]...hashtable["TimeN"]

Upvotes: 7

Related Questions