Click here to Skip to main content
15,891,951 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
Hello there,

I'm a bit stuck at my Settings-file management.
I'm fine with reading and writing but I'd like to clean up some code.

I'd really like to read a settings- item and convert it's value to the needed type.


Some example for a better overview:

The current state:
C#
 public class Pref
    {
        public Boolean ShowHiddenItems { get; set; }
    }
private void Form1_Load(object sender, EventArgs e)
        {
            Pref p = new Pref();

            p.ShowHiddenItems = (bool)ReadSubSetting(p.ShowHiddenItems, "show=", "show=true");

        }

private static object ReadSubSetting(object variable, String def, String line)
        {
            if (variable is bool)
            {
                if (line.StartsWith(def))
                {
                    line = line.Substring(def.Length,
                        line.Length -
                        def.Length);

                    bool bDummy;
                    Boolean.TryParse(line, out bDummy);

                    return bDummy;
                }
            }

            /* More conversations coming... */

            /* Some dummy return */
            return false;
        }


My goal:
C#
private void Form1_Load(object sender, EventArgs e)
        {
            Pref p = new Pref();

            p.ShowHiddenItems = ReadSubSetting(p.ShowHiddenItems, "show=", "show=true");

        }

But when trying this, the compiler tells me that he can not convert an object to a bool (which is okay) but the direct casting is not nice looking.

Anyway, is there a way to accomplish my goal this way or even a better way?
Posted
Comments
[no name] 27-Mar-14 10:57am    
You are probably getting that because ShowHiddenItems is defined as a Boolean type.

You could make the method accept a generic type, and do the casting inside the method, for example like this:

C#
private static T ReadSubSetting<T>(T variable, String def, String line)
{
   if (variable is bool)
   {
       if (line.StartsWith(def))
       {
           line = line.Substring(def.Length, line.Length - def.Length);
			   
            System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
            return (T)converter.ConvertFrom(line);
        }
   }

   /* More conversations coming... */

   /* Some dummy return */
   return default(T);
}


And then you can call it as following:
C#
Pref p = new Pref();
p.ShowHiddenItems = ReadSubSetting(p.ShowHiddenItems, "show=", "show=true");


This is assuming the type of the variable is the same as the return type of the method.
 
Share this answer
 
v2
Comments
zokker13 27-Mar-14 12:17pm    
Thank you very much!
This fits my needs completely!
Maarten Kools 27-Mar-14 12:21pm    
You're welcome! Keep in mind that this solution only works for primitive types, as Keith Barrow mentioned in his answer.
BillWoodruff 27-Mar-14 13:17pm    
+5 Very nice !
You are going to run into problems with this strategy - ReadSubSetting returns object, but you are setting this to bool.



A generic parser can be made to work like this:


C#
static void Form1_Load(object sender, EventArgs e)
{
    Pref p = new Pref();
    p.ShowHiddenItems = ReadSubSetting<bool>("true");
}

public static T ReadSubSetting<t>(string value)
{
     return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
}


You can use the above as starting points. If you need to pre-process according to the type, you can use a construct like if(typeof(T)) == typeof(bool))...
Note only works with primative types[^], but you can write a similar method for non-primatives using casting. You might also have problems with strings with my method but you are starting with strings, so no matter.
 
Share this answer
 
v2
Comments
BillWoodruff 27-Mar-14 13:18pm    
+5 Excellent !
Keith Barrow 28-Mar-14 6:09am    
Thanks!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900