如何将可变长度列表映射到对象属性?

时间:2016-06-14 18:01:53

标签: c# string properties mapping iteration

在这种情况下,我有一个对象Foo,其中包含一些具有此命名约定的字符串属性:Foo.Bar1Foo.Bar2等...

我想使用未知长度的字符串列表映射到每个Bar (n)属性:

public class Mapper()
{      
  public Foo MapToFoo(List<string> list)
  {
    var Foo = new Foo();
    foreach (var item in list)
    {
      //? Here is some psudo-code/logic of what I am trying to achieve:
      //Bar*X* = item
      //X++
    }
    return Foo;
  }
}

public class Foo
{
  public string Bar1 { get; set; }
  public string Bar2 { get; set; }
  public string Bar3 { get; set; }
}

我知道我可以添加public List<string> Bars并删除Bar1Bar2Bar3。虽然这可能是首选解决方案,但在我的特定情况下,它需要对紧密耦合的遗留项目进行大量更改。

有办法做到这一点吗?如果是这样,那么映射永远不会寻找不存在的 BarX (在这种情况下是Bar4)?

4 个答案:

答案 0 :(得分:0)

由于您无法使用Bars之类的内容,因此您可能需要使用反射,如下所示:

public class Mapper
{
    public Foo MapToFoo(List<string> list)
    {
        var Foo = new Foo();
        var props = typeof(Foo).GetProperties()
                               .Where(pi => pi.Name.StartsWith("Bar"))
                               .OrderBy(pi => pi.Name).ToList();

        for (int i = 0; i < Math.Min(list.Count, props.Count); i++)
            props[i].SetValue(Foo, list[i]);

        return Foo;
    }
}

但也许使用Dictionary<string, string>作为属性名称和值更合适:

var mapper = new Mapper();

var values = new Dictionary<string, String>();
values["Bar1"] = "A";
values["Bar2"] = "B";
values["Bar3"] = "C";

var foo = mapper.MapToFoo(values);

...
public class Mapper
{
    public Foo MapToFoo(Dictionary<string, string> values)
    {
        var Foo = new Foo();
        foreach (var item in values)
        {
            var prop = typeof(Foo).GetProperty(item.Key);

            if (prop != null)
                prop.SetValue(Foo, item.Value);
        }

        return Foo;
    }
}

答案 1 :(得分:0)

您可以使用反射来实现相同的目标。假设您的属性名为Bar1,Bar2,Bar3 ......等等,您可以执行以下操作。

    public Foo MapToFoo(List<string> list)
    {
        var Foo = new Foo();
        var propertyName = "Bar";
        int index = 1;
        foreach (var item in list)
        {
            var property = Foo.GetType().GetProperty(string.Format("{0}{1}", propertyName, index));
            if(property != null)
            {
                property.SetValue(Foo, item);
            }
            index++;
        }
        return Foo;
    }

答案 2 :(得分:0)

我的意思是你可以使用反射获得所有属性:

PropertyInfo[] properties = type.GetProperties();

foreach (PropertyInfo property in properties)
{
   //Store the values in an sort them
}

这样做 NOT 保证订单,因此您必须对它们进行排序。

只因为你可以,并不意味着你应该这样做。你应该问问自己&#34;我为什么这样做?&#34;和#34;是否有更简单/更易维护的解决方案?&#34;

答案 3 :(得分:0)

您可以使用反射:

public class Mapper()
{      
  public Foo MapToFoo(List<string> list)
  { 
      Foo f = new Foo();
      var bars =  f.GetType().GetProperties();
      int i=0;
      foreach (var item in list)
      {
            bars[i++].SetValue(f, item);
            if(i==bars.Length)
                break;
      }
      return f;
   }
}

public class Foo
{
  public string Bar1 { get; set; }
  public string Bar2 { get; set; }
  public string Bar3 { get; set; }
}
相关问题