【问题标题】:Dictionary<string,object> to object mapperDictionary<string,object> 到对象映射器
【发布时间】:2011-06-17 22:53:02
【问题描述】:

是否有任何对象-对象映射器可以映射字典(或其他名称-值集合)中的属性?

假设我有课

public class SomeClass
{
    public string Text { get; set; }
    public Address HomeAddress { get; set; }
    public List<int> Numbers { get; set; }
}
public class Address
{
    public string Street { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }    
}

我想做的是

var values = new Dictionary<string,object>();
values.Add("Text","Foo");
values.Add("HomeAddress.Street","Some street 123");
values.Add("HomeAddress.PostalCode","12345");
values.Add("HomeAddress.City","Some city");
values.Add("Numbers[0]",123);
values.Add("Numbers[1]",234);
values.Add("Numbers[2]",345);

SomeClass some = aMapperTool.CreateFromDictionary<SomeClass>(values);

这基本上就像 ASP.NET MVC 中的 DefaultModelBinder,它需要大量上下文和元数据相关的东西,因此不太方便。

【问题讨论】:

标签: c# dictionary object-object-mapping


【解决方案1】:

您可以利用 ComponentModel 功能(这已在 stackoverflow 的其他地方解决

how to set nullable type via reflection code ( c#)?

using System.ComponentModel;   

public void FillMeUp(Dictionary<string, string> inputValues){

        PropertyInfo[] classProperties  = this.GetType().GetProperties();

       var properties = TypeDescriptor.GetProperties(this);

       foreach (PropertyDescriptor property in properties)
       {
           if (inputValues.ContainsKey(property.Name))
           {
               var value = inputValues[property.Name];
               property.SetValue(this, 
                                 property.Converter.ConvertFromInvariantString(value));
           }
       }

【讨论】:

    【解决方案2】:

    你不会为此绕过反射或表达式树。

    使用反射,大致如下:

    1. 创建T的对象
    2. 遍历details 中的键,如果需要,从中构造实际的属性名称(HomeAddress.Street -> HomeAdress,或Numbers[0] -> Number)。根据属性的类型(如果找到.,则需要先构造子对象,如果找到[,则需要初始化IEnumerable)。
    3. 在构造任何子结构后,构造父对象。

    虽然这是一种可能的解决方案,但我的脑海中有一个问题:“为什么?”

    【讨论】:

    • 因为最好将任何 poco 对象存储到单个数据库表或文本文件中,而不需要丑陋的 xml,并且很好地支持搜索“where name='foo' and value='bar'”跨度>
    • 我建议您使用带有自定义包装器的 sqlite 来保存/加载 POCO。对这样的任务使用反射是可怕的,并且会对您的应用程序的性能产生巨大的负面影响,特别是如果您经常访问“数据库”。
    猜你喜欢
    • 2012-12-20
    • 2017-05-21
    • 2015-10-27
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 2016-07-08
    • 1970-01-01
    相关资源
    最近更新 更多