2014-01-05 37 views
1

我有陣列object[,]與從Excel(整數,雙精度,日期)的值,我有類:轉換[,]列出在C#<Class>

class Foo1 
{ 
    public int A {get; set;} 
    public Bar B {get; set;} 
    public List<Baz> C {get; set;} 
    public double D {get; set;} 
} 

我需要將數據從數組轉換爲類字段中的值。

我有不同的Foo類與其他數組的整數,列表等。 數組的大小[40,70]或[100,144](示例)。

一些代碼:

var data[,] = { {1.1, 2.2, 3.3, ...}, {5.5, 6.6, 7.7 ...} } 
var dest = new List<Foo1>(); 

而且我有dest[0]項目映射:

row | col | destination 
----------------------- 
0 | 0 | dest[0].A 
0 | 1 | dest[0].B.SomeField 
0 | 2 | dest[0].C.first_item 
0 | 3 | dest[0].C.second_item 
0 | 4 | dest[0].D 

dest[1]項目開始第1行中

我想結果List<Foo1>

dest[0].A = 1.1 
dest[0].B.some_field = 2.2 
dest[0].C[0].some_field = 3.3 
dest[0].C[1].some_field = 4.4 
.... 
dest[1].A = 5.5 
dest[1].B.some_field = 6.6 

如何儘可能快地做到這一點,沒有數百萬的if,foreach

+1

你的問題不是很清楚,甚至沒有表現出解決問題的努力。你可能想要改進它,然後它會關閉...... – Noctis

+0

我不知道你在做什麼。你能否以一種不需要我們成爲領域專家的方式來解釋這一點? –

+0

您能否更清楚地闡明問題?另外,請舉一些完整的例子,並強調一點,在哪裏卡住。一些給定的投入和所需的產出將不勝感激。 –

回答

1

下面是一個簡單的例子,它使用表達式樹來做你想做的事情。它可以很容易地推廣到你在你的問題描述的確切情況:

class X 
    { 
     public string Y { get; set; } 
    } 

    class Foo1 
    { 
     public int A { get; set; } 
     public X B { get; set; } 
    } 

    public static void Main() 
    { 
     var instanceParameter = Expression.Parameter(typeof(Foo1)); 

     Dictionary<int, Expression> map = new Dictionary<int, Expression>() 
     { { 0, Expression.Property(
        instanceParameter, 
        "A") }, 
      { 1, Expression.Property(
        Expression.Property(instanceParameter, "B"), 
        "Y") } }; 
     //more properties can be defined easily 

     object[,] data = new object[4, 2]; 
     data[0, 0] = 1; 
     data[0, 1] = "asdf"; 
     data[1, 0] = 2; 
     data[1, 1] = "yyy"; 
     data[2, 0] = -1; 
     data[2, 1] = "xxx"; 
     data[3, 0] = 3; 
     data[3, 1] = "good luck!"; 

     List<Foo1> result = new List<Foo1>(); 
     for (int row = 0; row < data.GetLength(0); ++row) 
     { 
      var foo = new Foo1() { B = new X() }; 

      for (int col = 0; col < data.GetLength(1); ++col) 
      { 
       Expression 
        .Lambda<Action<Foo1>>(
         Expression.Assign(
          map[col], 
          Expression.Constant(data[row, col])), 
         instanceParameter) 
        .Compile()(foo); 
      } 

      result.Add(foo); 
     } 
    } 

我就不是一般的建議這一點 - 它是不可讀的,難以維護。任何類型的錯誤將很難診斷。然而,它按要求完全自動化。

通常你應該只使用某種序列化。如果你不能(你不能影響你接收的數據的類型,例如從一些API),那麼通常每個對象應該知道如何從給定的結構中讀取它的屬性。即:

class Foo1 
{ 
    public int A {get; set;} 
    public Bar B {get; set;} 
    public List<Baz> C {get; set;} 
    public double D {get; set;} 

    public void Decode(object[,] data, int rowNumber) 
    { 
     this.A = (int)data[rowNumber, 0]; 
     //this.B = new Bar(); perhaps 
     this.B.Decode(data, rowNumber); 
     // etc. 
    } 
} 

同樣,如果你已經有很多這樣的類結構相似的,不能做任何事情或你應該使用的表達方式的一些其他情況下被強制。

+0

如果不是您的解決方案,因爲它不被推薦,還有什麼其他的解決方法? – Tomasito

+0

@Tomasito我已經添加了更多常見方法的描述。 – BartoszKP

+0

我不知道哪個版本會更快? – Tomasito