2014-01-05 41 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