tags:

views:

483

answers:

8

I have a string user setting and want to select a particular variable with the same name during the startup of my C# Windows app.

e.g.

I have a user setting (string) called UserSelectedInt, which is currently set to 'MyTwo'. (Please note that my variables are actually a lot more complex types than integers, I've just used them as examples.)

public static int MyOne = 12345;
public static int MyTwo = 54321;
public static int MyThree = 33333;

public int myInt = SelectMyVariableUsing(MyApp.Settings.Default.UserSelectedInt)

The user may have selected 'MyTwo' last time they closed the app, so that is the variable I want to select during startup. I hope I'm making sense.

Please can some let me know how would I achieve this?

Thanks

+22  A: 

Use a Dictionary<string, int>. That allows you to assign an integer value to a number of strings. If the string is user input, you need to check that it is valid before trying to retrieve the corresponding integer.

Brian Rasmussen
Alot better awnser than mine :)
Fredrik Leijon
http://stackoverflow.com/questions/301371/why-dictionary-is-preferred-over-hashtable-in-c for further reading.
Mr. Smith
Easy,juste have to think of it ^^
Polo
Thanks - it worked, but if I had 1000 variables I wouldn't really want to type out 1000 dictionary lines. I guess I'm just looking for a one-liner - or is that being way too optimistic?!
JamesW
You would probably need to use reflection in that case
James
Can you please give me an example?
JamesW
Since I've only got 3 variables and not 1000, I'm going to use this Dictionary method - guess I was just trying to be a bit too elegant and efficient in my code.
JamesW
I will post an example for you anyway
James
I you had a 1000 variable I would probably store them in a file and load them in a dictionary to get the key/value feature.
Brian Rasmussen
A: 

Should be possible with Reflection

Fredrik Leijon
A: 

You could also use a Hashtable.

However, from the looks of it all your really wanting to do is store the value the user last selected hence I would probably just save it in the UserSettings as a string and then on load I would just parse the value.

James
Don't use a Hashtable if you have access to `Dictionary<TKey, TValue>` (.NET 2.0+)
Thorarin
Yeah just saying it is also possible with this type of structure.
James
A: 

I hope I am reading this right, but essentially, I feel you want to remember the value user selected last time. Since the application will be shutdown in the meantime, you are going to have to store it somewhere. Maybe in a file.

Tanmay
+2  A: 

Sounds like you are trying to implement the provider pattern. You may find using this is a better mechanism for you to use, especially as you say it is more complex than using ints.

In your code you would reference the particular provider using your MyApp.Settings.Default.UserSelectedInt setting.

I would say architecturally this would be a better mechanism than some of the other suggested answers.

RichardOD
+2  A: 

The simplest way is probably to just use GetField.

Using your example just change the last line to:

var selectedField = MyApp.Settings.Default.UserSelectedInt
public int myInt = (int) GetType().GetField(selectedField).GetValue(this);

If the field or class is static the syntax should be:

var selectedField = MyApp.Settings.Default.UserSelectedInt
public int myInt = (int)typeof(YourClass).GetField(selectedField).GetValue(null);

See http://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.getvalue.aspx for more details.

Martin Hornagold
I can't get this to compile - I am using C# in VS 2008 (.NET 3.5) - is this code for a different version?It tells me 'An object reference is required for the non-static field, method, or property 'object.GetType()'
JamesW
This is using reflection. You need to replace (int) with your variable.
James
Yeah I'm doing that - no joy I'm afraid. I'm inside a static class and therefore can't use 'this' either. Could that be affecting things?
JamesW
It must be done against an instance variable.
James
Ah right... I'm going to go with the Dictionary method for now then
JamesW
You can still use reflection with static fields, have updated answer to reflect this. HTHWould echo what others have said about design though. Not that familiar with provider pattern but it might be a better way to go
Martin Hornagold
I've tried the updated code and now get 'Object reference not set to an instance of an object'...
JamesW
+2  A: 
// enumerate your list of property names (perhaps from a file)
var settings = new List<string>(); 
settings.Add("MyOne"); 
settings.Add("MyTwo"); 
settings.Add("MyThree");

var settingMap = new Dictionary<string, int>(); 
int value = 0; 
foreach (var name in settings) 
{
    try
    {
        // try to parse the setting as an integer
        if (Int32.TryParse((string)Properties.Settings.Default[name], out value))
        {
            // add map property name to value if successful
            settingMap.Add(name, value);
        }
        else
        {
            // alert if we were unable to parse the setting
            Console.WriteLine(String.Format("The settings property \"{0}\" is not a valid type!", name));
        }
     }
     catch (SettingsPropertyNotFoundException ex)
     {
         // alert if the setting name could not be found
         Console.WriteLine(ex.Message);
     }
}

However, if you get to the stage where your variable list is HUGE then I would maybe look at actually accessing the properties file directly via some form of XML parsing.

James
Thanks James - much appreciated
JamesW
A: 

Too me it sounds more like you should use an enumeration in stead of static variables, consider the following example:

    public enum MyVars
    {
        MyOne = 12345, MyTwo = 54321, MyThree = 33333 
    }
    static void Main(string[] args)
    {
        Console.WriteLine(String.Format("Name:{0}, Val={1}", MyVars.MyOne.ToString(), (int)MyVars.MyOne ));
        Console.ReadKey();
    }

, it will output "Name:MyOne, Val=12345", with enumerations you can easily pick out the name of the variable.

Inge Henriksen