有没有办法将这个方法变成通用的,这样我就可以返回字符串、布尔值、整数或双精度浮点数了?目前,它返回一个字符串,但如果它能够找到 "true" 或 "false" 作为配置值,我希望例如返回布尔值。
public static string ConfigSetting(string settingName)
{
return ConfigurationManager.AppSettings[settingName];
}
有没有办法将这个方法变成通用的,这样我就可以返回字符串、布尔值、整数或双精度浮点数了?目前,它返回一个字符串,但如果它能够找到 "true" 或 "false" 作为配置值,我希望例如返回布尔值。
public static string ConfigSetting(string settingName)
{
return ConfigurationManager.AppSettings[settingName];
}
public static T ConfigSetting<T>(string settingName)
{
return /* code to convert the setting to T... */
}
但是调用方必须指定他们所期望的类型。你可以潜在地使用Convert.ChangeType
,假设所有相关类型都得到支持:
public static T ConfigSetting<T>(string settingName)
{
object value = ConfigurationManager.AppSettings[settingName];
return (T) Convert.ChangeType(value, typeof(T));
}
我并不完全相信这一切都是一个好主意,你知道的...
ConfigSettingString
、 ConfigSettingBool
等)的优点在于方法体会更短、更清晰、更专注。 - phoogConvert.ChangeType()
方法:public static T ConfigSetting<T>(string settingName)
{
return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T));
}
有许多方法可以做到这一点(按优先级列出,特定于原帖的问题)
Option 1: Straight approach - Create multiple functions for each type you expect rather than having one generic function.
public static bool ConfigSettingInt(string settingName)
{
return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]);
}
Option 2: When you don't want to use fancy methods of conversion - Cast the value to object and then to generic type.
public static T ConfigSetting<T>(string settingName)
{
return (T)(object)ConfigurationManager.AppSettings[settingName];
}
Note - This will throw an error if the cast is not valid(your case). I would not recommend doing this if you are not sure about the type casting, rather go for option 3.
Option 3: Generic with type safety - Create a generic function to handle type conversion.
public static T ConvertValue<T,U>(U value) where U : IConvertible
{
return (T)Convert.ChangeType(value, typeof(T));
}
Note - T is the expected type, note the where constraint here(type of U must be IConvertible to save us from the errors)
U
中要将第三个选项定义成通用类型?这样做没有意义,而且使方法的调用更加困难。只需接受 IConvertible
即可。我认为考虑到它不能回答被问的问题,这个问题不值得包括第二个选项。你可能还需要重命名第一个选项中的方法... - Jon Skeet public static T values<T>()
{
Random random = new Random();
int number = random.Next(1, 4);
return (T)Convert.ChangeType(number, typeof(T));
}
return (T)Convert.ChangeType(number, typeof(T));
恰恰是我所缺少的 - 干杯! - Greg Trevellick public static T some_function<T>(T output_object /*declare as Output object*/)
{
return output_object;
}
请尝试以下代码:
public T? GetParsedOrDefaultValue<T>(string valueToParse) where T : struct, IComparable
{
if(string.EmptyOrNull(valueToParse))return null;
try
{
// return parsed value
return (T) Convert.ChangeType(valueToParse, typeof(T));
}
catch(Exception)
{
//default as null value
return null;
}
return null;
}
private static T[] prepareArray<T>(T[] arrayToCopy, T value)
{
Array.Copy(arrayToCopy, 1, arrayToCopy, 0, arrayToCopy.Length - 1);
arrayToCopy[arrayToCopy.Length - 1] = value;
return (T[])arrayToCopy;
}
dynamic
关键字,C#可以为你完成这个操作。虽然这样会有性能成本,但对于读取配置文件来说,性能成本几乎可以忽略不计。 - phoog