gpt4 book ai didi

c# - 如何使用字符串/对象对的集合来实现类,以便可以使用泛型方法返回对象?

转载 作者:行者123 更新时间:2023-11-30 22:46:34 26 4
gpt4 key购买 nike

文件中的值被读取为字符串,可以是 double 、字符串或整数,甚至可能是列表。示例文件:

DatabaseName=SomeBaseClasses=11;12;13IntValue=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;
}
}

附言。其他问题是可选设置的默认值。在单独的字典中将它们传递给 LoadConfig 并不优雅,但这是另一个问题......

最佳答案

我能想到的唯一方法是使用 Dictionary<String,Object>然后转换 Object到适当的类型。

您的根本问题是如何动态指定类型: Dynamically specify the type in C#

事实证明,C# 中的类型转换(实际上是拆箱)的开销非常小: C# performance analysis- how to count CPU cycles?


更新:
以下是您如何进行转换:

Dictionary<String,Object> parameters = new Dictionary<String,Object>();

// cast a string
parameters.Add("DatabaseName", "SomeBase");

// cast a list
parameters.Add("Classes", new List<int> { int.Parse("11"), int.Parse("12"), int.Parse("13") });

// cast an integer
parameters.Add("IntValue", int.Parse("3"));

// cast a double
parameters.Add("DoubleValue", Double.Parse("4.0"));

然后,当您想要使用这些值时,只需进行拆箱即可:

int intValue = (int)parameters["IntValue"];
Double doubleValue = (Double)parameters["DoubleValue"];
List<int> classes = (List<int>)parameters["Classes"];
// etc...

正如我之前提到的:在进行性能测试后,我发现拆箱具有疏忽的开销,因此您应该不会看到任何明显的性能问题。


更新 2.0:

我猜您想自动转换类型,而不必在将其添加到 _settings 时显式指定它字典。如果您的字典的值为 Object,它应该可以工作:

Type t = typeof(double);
Object val = Convert.ChangeType("2.0", t);
// you still need to unbox the value to use it
double actual = (double)val;

所以你的例子应该有效:

_settings[kVPair.Key] = Convert.ChangeType(value, type);

您只需要在使用时使用正确的类型拆箱即可。

关于c# - 如何使用字符串/对象对的集合来实现类,以便可以使用泛型方法返回对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2585439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com