c#用反射原理递归遍历复杂实体对象

c#用反射原理递归遍历复杂实体对象[转载]

之前在网上看到的都是遍历那种比较简单的实体对象,但是如果有实体嵌套,甚至是包含有List<XXInfo>这种属性的时候就没有办法处理了。通过递归遍历的方式可以完成对复杂实体对象的所有属性的遍历,可以取值和赋值。

下面是关键部分的代码,有什么不对的地方路过的大大一定要指点哈。

using System.Reflection;

public System.Text.StringBuilder strB = new System.Text.StringBuilder();
    public void GetInfoPropertys(object objInfo)
    {
        if (objInfo == null) return;
        Type tInfo = objInfo.GetType();
        PropertyInfo[] pInfos = tInfo.GetProperties();
        if (tInfo.IsGenericType)
        {
            System.Collections.ICollection Ilist = objInfo as System.Collections.ICollection;
            if (Ilist != null)
            {
                strB.AppendFormat("集合子属性{0}<br/>", Ilist.Count);
                foreach (object obj in Ilist)
                {
                    GetInfoPropertys(obj);
                }
            }
            else
            {
                strB.Append("泛型集合为空<br/>");
            }
            return;
        }
        foreach (PropertyInfo pTemp in pInfos)
        {
            string Pname = pTemp.Name;
            string pTypeName = pTemp.PropertyType.Name;
            object Pvalue = pTemp.GetValue(objInfo, null);
            if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))
            {
                string value = (Pvalue == null ? "为空" : Pvalue.ToString());
                strB.AppendFormat("属性名:{0},属性类型:{1},属性值:{2}<br/>", Pname, pTypeName, value);
            }
            else
            {
                string value = Pvalue == null ? "为空" : Pvalue.ToString();
                strB.AppendFormat("<br/><b>子类</b>,属性名:{0},属性类型:{1},属性值:{2}<br/>", Pname, pTypeName, value);
                strB.Append("----------------------------------------------<br/>");
                GetInfoPropertys(Pvalue);

            }

        }
    }

 

 

 

利用反射实现表格式Excel文档的导出:

上次客户提出了要将数据导出到类似上图的固定格式的Excel文档中,当然真实的表格不是上面那样的,而且表格的格式有十多种,最后采用的解决办法就是利用C#的反射。大概的思路是这样的,为每种导出的表格样式都做一个xml的配置文件,然后记录每个需要复制的文本框的坐标,以及这个值在实体类中的名称,针对上面的那种表格格式,xml配置文件是这样的:

<?xml version="1.0" encoding="utf-8"?>
<XML TableName="table1.xml" OtherInfo="">

  <Field Fname="NAME" PropertyName="NAME" Desc="姓名">
    <x>4</x>
    <y>3</y>
  </Field>
  <Field Fname="SEX" PropertyName="SEX" Desc="性别">
    <x>10</x>
    <y>3</y>
  </Field>
  <Field Fname="BIRTHDAY" PropertyName="BIRTHDAY" Desc="出生年月">
    <x>4</x>
    <y>4</y>
  </Field>
  <Field Fname="Zz" PropertyName="Zz" Desc="政治面貌">
    <x>10</x>
    <y>4</y>
  </Field>
  <Field Fname="HunYin" PropertyName="HunYin" Desc="婚姻状况">
    <x>4</x>
    <y>5</y>
  </Field>
  <Field Fname="Tel" PropertyName="Tel" Desc="联系电话">
    <x>10</x>
    <y>5</y>
  </Field>
  <Field Fname="WorkHistory" PropertyName="WorkHistory" Desc="工作经历">
    <x>13</x>
    <y>1</y>
  </Field>

  <!--Field Fname="SaleGuid"  PropertyName="SaleList.SaleGuid" Desc="销售记录编号">
    <x></x>
    <y></y>
  </Field-->
  <Field Fname="ProductGuid"  PropertyName="SaleList.ProductGuid" Desc="货物编号">
    <x>1</x>
    <y>8</y>
  </Field>
  <Field Fname="ProductName"  PropertyName="SaleList.ProductName" Desc="产品编号">
    <x>3</x>
    <y>8</y>
  </Field>
  <Field Fname="ProductJiage"  PropertyName="SaleList.ProductJiage" Desc="售价">
    <x>5</x>
    <y>8</y>
  </Field>
  <Field Fname="SaleDate"  PropertyName="SaleList.SaleDate" Desc="出售日期">
    <x>7</x>
    <y>8</y>
  </Field>
</XML>

然后从数据库中获取数据存入到实体类中,用反射遍历实体类的所有属性,如果xml中得PropertyName节点的值和当前属性的属性名相等,那么就可以通过xml提供的坐标给Excel表格赋值了。这样做的一个好处是,可以实现不同表格的通用赋值,即使翻页显示也能应对(比如上面的销售记录每页只能显示4条,而程序中是构造的10条销售记录,只能通过分页显示完),不用为每种格式都去写一种实现,即使表格的样式有所变动也不用改程序,只需更改一下xml就好了。

语言组织和表达的能力不行,还是直接上码:

using System;
using System.Collections.Generic;
using System.Web;
using System.Reflection;
using System.Xml;
/// <summary>
///Excel导出
/// </summary>
public class ExcelExport
{

    #region 变量
    public List<FiledInfo> FInfoList = new List<FiledInfo>();//xml属性、坐标列表
    //public System.Text.StringBuilder strB = new System.Text.StringBuilder();
    ExcelOperator excel = null;//Excel操作
    int sheetIndex = 0;//excel工作薄索引
    #endregion
    public ExcelExport()
    {
        getNodeFromXml();
    }
    /// <summary>
    /// 模拟从数据库获取数据
    /// </summary>
    /// <returns></returns>
    public employee GetInfo()
    {
        employee e = new employee();
        e.NAME = "路人甲";
        e.SEX = true;
        e.HunYin = false;
        e.Tel = "15986752131";
        e.Zz = "团员";
        e.WorkHistory = "暂无";
        for (int i = 0; i < 10; i++)
        {
            SaleInfo s = new SaleInfo();
            s.ProductGuid = "产品编号" + i;
            s.ProductName = "产品名称" + i;
            s.ProductJiage = 10.23M * i;
            s.SaleDate = DateTime.Now.AddDays(i);
            e.SaleList.Add(s);
        }
        return e;
    }

    //public string GetProperties()
    //{
    //    employee emp = GetInfo();
    //    GetProperty(emp, "");
    //    return strB.ToString();
    //}
    //private void GetProperty(object obj, string parentProName)
    //{
    //    if (obj == null) return;
    //    Type t = obj.GetType();
    //    string strParentProName = (string.IsNullOrEmpty(parentProName) ? "" : parentProName.TrimEnd('.') + ".");
    //    if (t.IsGenericType)
    //    {
    //        System.Collections.ICollection ic = obj as System.Collections.ICollection;
    //        foreach (object objTemp in ic)
    //        {
    //            strB.Append("---------------------<br/>");
    //            GetProperty(objTemp, strParentProName);
    //        }
    //    }
    //    else
    //    {
    //        foreach (PropertyInfo pTemp in t.GetProperties())
    //        {
    //            string name = pTemp.Name;
    //            string typeName = pTemp.PropertyType.FullName;
    //            object value = pTemp.GetValue(obj, null);
    //            if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))
    //            {
    //                strB.AppendFormat("属性名:{0},类型名称:{1},属性值:{2}<br/>", strParentProName + name, typeName, value);
    //            }
    //            else
    //            {
    //                GetProperty(value, name);
    //                strB.AppendFormat("属性名:{0},类型名称:{1},属性值:{2}<br/>", name, typeName, value);

    //            }
    //        }
    //    }
    //}
    /// <summary>
    /// 属性赋值
    /// </summary>
    private void SetPropertyValues(object obj, string parentProName, int index)
    {
        if (obj == null) return;
        Type t = obj.GetType();
        string strParentProName = (string.IsNullOrEmpty(parentProName) ? "" : parentProName.TrimEnd('.') + ".");
        if (t.IsGenericType)
        {
            System.Collections.IList ic = obj as System.Collections.IList;
            int ICIndex = 0;
            foreach (object objTemp in ic)
            {
                //strB.Append("---------------------<br/>");
                SetPropertyValues(objTemp, strParentProName, ICIndex);
                ICIndex++;
            }
        }
        else
        {
            foreach (PropertyInfo pTemp in t.GetProperties())
            {
                string name = pTemp.Name;
                string typeName = pTemp.PropertyType.FullName;
                object value = pTemp.GetValue(obj, null);
                if (pTemp.PropertyType.IsValueType || pTemp.PropertyType.Name.StartsWith("String"))
                {
                    FiledInfo finfoResult = FInfoList.Find(delegate(FiledInfo finfo) { return finfo.PropertyName == strParentProName + name; });
                    if (finfoResult != null)
                    {
                        //strB.AppendFormat("属性名:{0},属性值:{1},坐标:x={2},y={3}<br/>", strParentProName + name, value,finfoResult.X,finfoResult.Y);
                        int x = Convert.ToInt32(finfoResult.X) + index;
                        int y = Convert.ToInt32(finfoResult.Y);
                        excel.SetCellValue(sheetIndex, x, y, value.ToString());
                    }
                }
                else
                {
                    SetPropertyValues(value, name, 0);
                }
            }
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public employee SetPropertyValue()
    {
        if (excel == null)
        {
            excel = new ExcelOperator(@"D:\程序开发\我写的东东\webLX\Excel\model\yuangong.xls");
        }
        employee emp = GetInfo();
        List<employee> list = FormatEmplyeeObj(emp);
        for (int i = 0; i < list.Count;i++ )
        {
            if (i != 0)
            {
                excel.CreateNewSheetByCopy("销售记录" + i.ToString());
            }
        }
        foreach (employee empTemp in list)
        {
            sheetIndex++;
            SetPropertyValues(empTemp, "", 0);
        }
        excel.Close(true);
        return emp;
    }
    /// <summary>
    /// 设置值
    /// </summary>
    private void SetValue()
    {
        employee e = new employee();
        Type t = e.GetType();

    }

    private void getNodeFromXml()
    {
        FInfoList.Clear();
        string strXmlPath = @"D:\程序开发\我写的东东\webLX\Excel\modelXML\table1.xml";
        XmlDocument xml = new XmlDocument();
        xml.Load(strXmlPath);
        XmlNodeList nodelist = xml.GetElementsByTagName("Field");
        foreach (XmlNode node in nodelist)
        {
            FiledInfo finfo = new FiledInfo();
            finfo.PropertyName = node.Attributes["PropertyName"].Value;
            finfo.X = node.ChildNodes[1].InnerText;
            finfo.Y = node.ChildNodes[0].InnerText;
            FInfoList.Add(finfo);
        }
    }
    /// <summary>
    /// 格式化员工对象,便于翻页显示
    /// </summary>
    public List<employee> FormatEmplyeeObj(employee emp)
    {
        List<employee> list = new List<employee>();
        if (emp != null)
        {
            if (emp.SaleList.Count > 4)//销售记录每页显示4行
            {
                for (int i = 0; i < Math.Ceiling(Convert.ToDouble(emp.SaleList.Count) / 4); i++)
                {
                    employee infoTemp = new employee();
                    CloneEntityObject(emp, infoTemp);
                    if ((i + 1) * 4 > emp.SaleList.Count)
                    {
                        infoTemp.SaleList = infoTemp.SaleList.GetRange(i * 4, emp.SaleList.Count-i*4);//销售记录每页显示四行
                    }
                    else
                    {
                        infoTemp.SaleList = infoTemp.SaleList.GetRange(i * 4, 4);//销售记录每页显示四行
                    }
                    list.Add(infoTemp);
                }
            }
        }
        return list;
    }
    /// <summary>
    /// 实体对象拷贝
    /// </summary>
    /// <param name="srcObj"></param>
    /// <param name="desObj"></param>
    public void CloneEntityObject(object srcObj, object desObj)
    {
        if (srcObj.Equals(desObj))
        {
            return;
        }
        if (srcObj.GetType() != desObj.GetType())
        {
            return;
        }
        System.Reflection.PropertyInfo[] info = srcObj.GetType().GetProperties();
        foreach (System.Reflection.PropertyInfo property in info)
        {
            desObj.GetType().GetProperty(property.Name).SetValue(desObj,
            srcObj.GetType().GetProperty(property.Name).GetValue(srcObj, null), null);
        }
    }

}

另外Excel的操作类在之前的文章中有,这里就不再贴了。

转载于:https://www.cnblogs.com/AngryXiaopeng/p/3283857.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值