动态地将类属性和值从一个类映射到另一个类

时间:2015-02-16 05:49:52

标签: c# class dynamic

我有一个班级名称Invoice,但这个班级是我无法控制的 因为它来自我们保存发票的另一家公司API

public class InvoiceOutput
{
    public string InvoiceNum {get; set;}
    public string TotalAmount {get; set;}
    public string Date {get; set;}
    public string Address{get; set;}

    public List<InvoiceRows> {get; set;}

    public Add() 
    { 
          //invoice Add functionality
    }
    public bool Save() 
    { 
           //invoice Save functionality
    }


//This is my own Invoice, a copy from all writable properties of InvoiceOutput
public class InvoiceInput
{
    public string InvoiceNum {get; set;}
    public string TotalAmount {get; set;}
    public string Date {get; set;}
    public string Address{get; set;}

    public List<InvoiceRows> {get; set;}
}

现在我有一个xml被反序列化为InvoiceInput()类 但是xml文件是动态的,它只能包含。

<?xml version="1.0" encoding="utf-8" ?>
<Invoices>
  <Invoice>
    <InvoiceNum>0001</InvoiceNum>
    <TotalAmount>5000</TotalAmount>
  </Invoice> 
  <Invoice>
    <InvoiceNum>0002</InvoiceNum>
    <TotalAmount>5000</TotalAmount>
  </Invoice> 
</Invoices>

所以在这种情况下,我只想分配在InvoiceInput()中找到的值,我将其从xml文件反序列化为类列表。 所以我现在把我的反序列化类作为

InvoiceInput[0].InvoiceNum =0001
InvoiceInput[0].TotalAmount=5000

InvoiceInput[1].InvoiceNum =0002
InvoiceInput[1].TotalAmount=8000

我现在怎么能这样做: 假设我把它放在for循环中。 请记住,我的xml是动态的,所以它取决于那里的属性 所以它在这里分配。

for(int i=0;i<InvoiceOutput.Count; i++)
{
InvoiceOutput.Add();
InvoiceOutput.InvoiceNum  = InvoiceInput[i].InvoiceNum;
InvoiceOutput.TotalAmount = InvoiceInput[i].TotalAmount;
InvoiceOutput.Save();
}

2 个答案:

答案 0 :(得分:1)

您可以使用AutoMapper。 例如,使用:

//初始化一次

Mapper.CreateMap<InvoiceInput, InvoiceOutput>();
Mapper.CreateMap<InvoiceOutput, InvoiceInput>();

//使用

InvoiceInput invoiceInput = Mapper.Map<InvoiceInput>(invoiceOutput);

答案 1 :(得分:0)

我假设您要将所有属性的值从类InvoiceOutput对象复制到InvoiceInput对象。 然后尝试基于反射的方式,

    private static object CloneObject(object o)
    {
        Type t = o.GetType();
        PropertyInfo[] properties = t.GetProperties();

        object p = new InvoiceInput();

        foreach (PropertyInfo pi in properties)
        {
            p.GetType().GetProperty(pi.Name).SetValue(p, pi.GetValue(o, null),null);
        }

        return p;
    }

这里我假设两个类的属性名称相同。

Take a look her for more info.

然后您可以将其用作

  InvoiceInput b = (InvoiceInput)CloneObject(outp);

如果您要经常使用它,那么您可以尝试将其写为Extension method。然后你可以像这样克隆所有对象,

  inputObject.CloneOutputObject(ouputObject);

<强>更新

您可以使用Convert.ChangeType() - 它允许您使用任何IConvertible类型的运行时信息来更改表示格式。但是,并非所有转换都是可能的,如果您想支持非IConvertible类型的转换,您可能需要编写特殊情况逻辑。

      p.GetType().GetProperty(pi.Name).SetValue(p, Convert.ChangeType(pi.GetValue(o, null),YourTypeToConvertTo)),null);

获取目标属性类型,您可以执行此类操作

      PropertyInfo newp = typeof(InvoiceInput).GetProperties().where(x=>x.Name == pi.Name).FirstOrDefault();

然后设置值

      p.GetType().GetProperty(pi.Name).SetValue(p, Convert.ChangeType(pi.GetValue(o, null),newp.PropertyType)),null);