2016-06-14 81 views
0

在這種情況下我有一個包含與此命名約定一些字符串屬性的對象FooFoo.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)?

+0

這是可能的,你將有你有許多懸而未決的要求,才能使用雲南財貿爲 –

+1

。如果列表的字符串多於Foo的屬性,該怎麼辦?如果有更多的Foo屬性比字符串?反射的屬性不保證順序,字符串2可以設置Bar3值嗎?我建議你不要這樣做,建立一個[Adapter](https://en.wikipedia.org/wiki/Adapter_pattern)來橋接遺留代碼。 – Crowcoder

回答

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; 
    } 
} 
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; 
    } 
0

我的意思是,你可以使用反射得到所有的屬性:

PropertyInfo[] properties = type.GetProperties(); 

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

但這保證順序,這樣你將不得不對它們進行排序。

只因爲你可以,並不意味着你應該。你應該問自己:「我爲什麼要這樣做?」和「是否有更簡單/更易維護的解決方案?」

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; } 
} 
相關問題