The values in a file are read as string and can be double, string or int or maybe even lists. An example file:
DatabaseName=SomeBase Classes=11;12;13 IntValue=3 //this is required! DoubleValue=4.0
I was thinking something like this:
class ConfigValues
{
private static SomeObject _utiObject;
private static string _cfgFileName = "\\SomeSettings.cfg";
private static Dictionary<string, Type> _settingNamesAndTypes =
new Dictionary<string, Type>();
private static Dictionary<string, object> _settings = new Dictionary<string, object>();
private static string _directory = string.Empty;
const string _impossibleDefaultValue = "987ABC654DEF321GHI";
public static T GetConfigValue<T>(string cfgName)
{
object value;
if (_settings.TryGetValue(cfgName, out value))
return (T)value;
else
return default(T);
}
public static bool LoadConfig(Dictionary<string, Type> reqSettings,
Dictionary<string, Type> optSettings,
Dictionary<string, object> optDefaultValues, out string errorMsg)
{
errorMsg = string.Empty;
try
{
_utiObject = new SomeObject(new string[] { "-c", CfgFileNameAndPath });
}
catch (Exception e)
{
errorMsg = string.Format("Unable to read {0}. Exception: {1}",
CfgFileNameAndPath, e.Message);
return false;
}
foreach (KeyValuePair<string, Type> kVPair in reqSettings)
{
if (!ReadCheckAndStore(kVPair, null, out errorMsg))
return false;
_settingNamesAndTypes.Add(kVPair.Key, kVPair.Value);
}
foreach (KeyValuePair<string, Type> kVPair in optSettings)
{
if (!ReadCheckAndStore(kVPair, optDefaultValues[kVPair.Key], out errorMsg))
return false;
_settingNamesAndTypes.Add(kVPair.Key, kVPair.Value);
}
return true;
}
private static bool ReadCheckAndStore(KeyValuePair<string, Type> kVPair, object defaultValue, out string errorMsg)
{
errorMsg = string.Empty;
string usedDefaultValue, value = string.Empty;
/* required setting */
if (defaultValue == null)
usedDefaultValue = _impossibleDefaultValue;
else
usedDefaultValue = defaultValue.ToString();
//all string parameters below
_utiObject.GetConfigValue(kVPair.Key, usedDefaultValue, ref value);
if (_impossibleDefaultValue == value)
{
errorMsg = string.Format("Required configuration setting {0} was not" +
"found in {1}", kVPair.Key, CfgFileNameAndPath);
return false;
}
Type type = kVPair.Value;
_settings[kVPair.Key] = Convert.ChangeType(value, type);
return true;
}
}
PS. Additional issue is default values for optional settings. It’s not elegant to pass them to LoadConfig in separate Dictionary, but that is an other issue…
The only way I can think of doing this is to have
Dictionary<String,Object>and then cast theObjectto the appropriate type.Your underlying problem is how to dynamically specify the type:
Dynamically specify the type in C#
Turns out that type casting (actually unboxing) in C# has very little overhead:
C# performance analysis- how to count CPU cycles?
Update:
Here is how you do the casting:
Then when you want to use the values you just do the unboxing:
As I mentioned before: after doing performance testing I found that unboxing has negligent overhead so you should not see any noticeable performance issues.
Update 2.0:
I’m guessing you want to automatically convert the type without having to explicitly specify it when you’re adding it into the
_settingsdictionary. It should work if your dictionary’s value is anObject:So your example should work:
You just need to unbox the value with the correct type when you’re going to use it.