如何将namevaluecollection自动化为强类型类?

时间:2010-02-25 22:40:44

标签: c#

我将应用程序的配置详细信息存储在如下表中:

SettingName                   SettingValue
--------------------          ---------------------
PostsPerPage                  10   
EmailErrors                   True
AdminEmailAddress             admin@admin.com

我的dataaccess类说返回表中存储的设置的namevaluecollection / keyvaluepair。

将namevaluecollection / keyvaluepair映射到强类型类的最佳方法是什么,如下面那个具有与SettingName Column中相同的属性的类。

public class Settings
{
    public int PostsPerPage{get;set;}
    public bool EmailErrors{get;set;}
    public string AdminEmailAddress{get;set;}
}

5 个答案:

答案 0 :(得分:6)

如果你的项目中有Newtonsoft Json库,那么这是另一个快捷方式 - 你可以将它用作翻译机制。不确定它是否具有出色的性能,但它非常简洁明了......

假设"形式"是你的" NameValueCollection"对象...

// convert to a string/string dictionary and remove anynulls that may have been passed in as a string "null"
var formDictionary = form.AllKeys
                     .Where(p => form[p] != "null")
                     .ToDictionary(p => p, p => form[p]);
string json = JsonConvert.SerializeObject(formDictionary);
var myObject = JsonConvert.DeserializeObject<MyClass>(json);

答案 1 :(得分:4)

使用反射。在伪代码中:

Settings mySettingsClass = new Settings();
foreach (KeyValuePair<string, object> kvp in mySettings) 
{
    PropertyInfo pi = mySettingsClass.GetType().GetProperty(kvp.key, BindingFlags.Public | BindingFlags.Instance);
    if (pi != null) 
    {
        pi.SetValue(mySettingsClass, kvp.Value, null);
    }
}

当然,如果您从dataReader中读取它,那么您可以采用稍微不同的方法并避免使用反射(因为DataReader的结构和目标对象的结构是已知的)。在这种情况下使用反射速度较慢,但​​是通常将数据从一个项目映射到另一个项目的好方法 - 基本上您获取源属性,查看目标对象上是否存在目标属性,然后分配值(如果存在)。

答案 2 :(得分:4)

添加这个答案(帖子很老我知道) - 不得不解决@strgster的答案 - 这是最有希望的。

NameValueCollection nvc = HttpContext.Current.Request.Form;
Settings mySettingsClass = new Settings();
foreach (string kvp in nvc.AllKeys)
{
    PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance);
    if (pi != null)
    {
         pi.SetValue(model, nvc[kvp], null);
    }
}

基本上唯一的区别是@slugster使用的是KeyValuePair,而不是NameValueCollection

答案 3 :(得分:1)

使用代码生成生成您的“设置”类。我做到了这一点,而且效果很好。这是我采取的方法:

  1. 在您自己设计的XML文件中定义您的设置。它至少需要定义设置名称和类型。但是如果您愿意,可以添加其他内容:帮助字符串,默认值,验证谓词等。
  2. 使用t4读入XML文件并生成Settings类。 (t4是Visual Studio内置的代码生成器。)
  3. 在遇到静态类型检查限制的情况下,代码生成通常很有用。代码生成的一个好处是代码是静态类型的,因此您可以进行编译时类型检查,这当然是静态类型的好处之一。

答案 4 :(得分:0)

使用System.Reflection命名空间:

http://www.dotnetspider.com/resources/19232-Set-Property-value-dynamically-using-Reflection.aspx

使用对象的GetType()获取类型或动态执行,使用GetProperties从类型获取所有属性或使用GetProperty获取单个属性,并使用字典中的值调用SetValue。

这是最简单的方法。可能有某种对象映射器也可以这样做。

HTH。