[英]Convert from object[,] to List<Class> in C#
我有数组object[,]
,其值来自Excel(整数,双精度数,日期),并且具有类:
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
如何在没有上百万foreach
if
, foreach
情况下尽可能快地做到这一点。
这是一个简单的示例,可以使用表达式树来完成您想要的事情。 可以很容易地将其概括为您在问题中描述的确切情况:
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.
}
}
同样,如果您已经有很多类似结构的类,并且对此无能为力,或者由于某些其他情况而被迫使用,则应使用表达式方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.