繁体   English   中英

从object [,]转换为List <Class> 在C#中

[英]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 ifforeach情况下尽可能快地做到这一点。

这是一个简单的示例,可以使用表达式树来完成您想要的事情。 可以很容易地将其概括为您在问题中描述的确切情况:

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM