• DNN学习笔记代码学习:CBO 荣


    using System;
    using System.Data;
    using System.Web.Caching;
    using System.Reflection;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Text;
    using System.IO;
    using System.Collections;
    using Microsoft.VisualBasic;

    namespace WebApplication1
    {
     /// <summary>
     /// 根据类型关键字取得相应的对象。
     /// 为什么没有用DataTable或DataSet来填充对象的方法。
     /// </summary>
     public class CBO
     {
      public CBO()
      {
       //
       // TODO: 在此处添加构造函数逻辑
       //
      }

      /// <summary>
      /// 返回存储某类型的所有属性的集合。
      /// </summary>
      /// <param name="objType">类型(类、接口、枚举等)</param>
      /// <returns>属性集合</returns>
      public static ArrayList GetPropertyInfo(Type objType)
      {
       // 存储属性的集合,并试图从缓存中查找关于objType类型的属性,以期填充类型。
       ArrayList objProperties = (ArrayList)DataCache.GetCache(objType.FullName);

       // 如果属性集合为空
       if (objProperties == null)
       {
        // 初始化集合
        objProperties = new ArrayList();

        // PropertyInfo:发现属性的特性并提供对属性元数据的访问。
        // GetProperties:返回当前Type的所有公共属性。
        foreach (PropertyInfo objProperty in objType.GetProperties())
        {
         // 用属性填充集合
         objProperties.Add(objProperty);
        }
       }

       // 返回类型集合
       return objProperties;
      }

      /// <summary>
      /// 返回dr属性字段索引的数组。
      /// </summary>
      /// <param name="objProperties">属性数组[存储着dr的列字段名称的属性]</param>
      /// <param name="dr"></param>
      /// <returns>字段索引的数组</returns>
      public static int[] GetOrdinals(ArrayList objProperties, IDataReader dr)
      {
       // 形成对应属性集合的整合数组
       int[] arrOrdinals = new int[objProperties.Count];

       if (dr != null)
       {
        int count = objProperties.Count;

        // 遍历每一个属性
        for (int intProperty = 0; intProperty < count; intProperty++)
        {
         arrOrdinals[intProperty] = -1;
         try
         {
          // 设置该属性对应dr中的索引号 , 如果没有,设置为-1
          PropertyInfo propertyInfo = (PropertyInfo)objProperties[intProperty];

          // GetOrdinal:返回命名字段的索引。
          // propertyInfo.Name:获取此成员的名称。
          // 该行试图返回字段名称为propertyInfo.Name的DataReader的列索引
          arrOrdinals[intProperty] = dr.GetOrdinal(propertyInfo.Name);
         }
         catch
         {
         }
        }
       }

       // 返回命名字段索引的数组
       return arrOrdinals;
      }

      /// <summary>
      /// 给objType类型的对象属性逐个赋值并返回。
      /// </summary>
      /// <param name="objType">对象类型</param>
      /// <param name="dr">存储记录的DataReader</param>
      /// <param name="objProperties">属性集合</param>
      /// <param name="arrOrdinals">索引集合</param>
      /// <returns>objType类型对象</returns>
      private static object CreateObject(Type objType, IDataReader dr, ArrayList objProperties, int[] arrOrdinals)
      {
       // 在这儿声明属性对象,估计是为了性能考虑
       PropertyInfo objPropertyInfo;
       object objValue;
       Type objPropertyType = null;

       // 创建objType类型的对象
       object objObject = Activator.CreateInstance(objType);

       int count = objProperties.Count;
       for (int intProperty = 0; intProperty < count; intProperty++)
       {
        // 取得第intProperty个属性
        objPropertyInfo = (PropertyInfo)objProperties[intProperty];

        // 如果该属性允许写入
        if (objPropertyInfo.CanWrite)
        {
         // 将objValue设置为空  根据objPropertyInfo.PropertyType值来取得空值
         objValue = Null.SetNull(objPropertyInfo);

         // 如果索引大于-1
         if (arrOrdinals[intProperty] != -1)
         {
          // 判断dr的第arrOrdinals[intProperty]格元素是空
          if (Information.IsDBNull(dr.GetValue(arrOrdinals[intProperty])))
          {
           // 将给定对象的属性值设置为给定值[即相应的空值]
           objPropertyInfo.SetValue(objObject, objValue, null);
          }
           // 如果不是空
          else
          {
           try
           {
            // 将给定对象的属性值设置为给定值
            objPropertyInfo.SetValue(objObject, dr.GetValue(arrOrdinals[intProperty]), null);
           }
           catch
           {
            // 如果设置不成功
            try
            {
             // 取得相应数据类型
             objPropertyType = objPropertyInfo.PropertyType;

             // BaseType:获取当前 System.Type 直接从中继承的类型
             // 如果类型是枚举
             if (objPropertyType.BaseType.Equals(typeof(System.Enum)))
             {
              //  判断dr的第arrOrdinals[intProperty]格元素是不是数字
              if (Information.IsNumeric(dr.GetValue(arrOrdinals[intProperty])))
              {
               // 将给定对象的属性值设置为给定值 即第Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty])个枚举值
               ((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType, Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty]))), null);
              }
              else
              {
               // 将给定对象的属性值设置为给定值
               ((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType,dr.GetValue(arrOrdinals[intProperty])), null);
              }
             }
              // 如果不是枚举类型
             else
             {
              objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
             }
            }
            catch
            {
             // 将给定对象的属性值设置为给定值
             objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
            }
           }
          }
         }
        }
       }

       // 返回objObject对象
       return objObject;
      }

      /// <summary>
      /// 用dr填充一个objType对象,并返回。
      /// </summary>
      /// <param name="dr">存储对象数据的DataReader</param>
      /// <param name="objType">对象类型</param>
      /// <returns>objType对象</returns>
      public static object FillObject(IDataReader dr, Type objType)
      {
       return FillObject(dr, objType, true);
      }

      /// <summary>
      /// 用dr填充一个objType对象,并返回。
      /// </summary>
      /// <param name="dr">存储对象数据的DataReader</param>
      /// <param name="objType">对象类型</param>
      /// <param name="ManageDataReader"></param>
      /// <returns>objType对象</returns>
      public static object FillObject(IDataReader dr, Type objType, bool ManageDataReader)
      {
       object objFillObject;
       int intProperty;

       // GetPropertyInfo:返回存储某类型的所有属性的集合。
       // 取得属性集合
       ArrayList objProperties = GetPropertyInfo(objType);

       // GetOrdinals:返回dr属性字段索引的数组。
       // 返回索引数组
       int[] arrOrdinals = GetOrdinals(objProperties, dr);

       bool Continue = true;

       // 要不要继续,如果dr不到最后,继续
       if (ManageDataReader)
       {
        Continue = false;

        if (dr.Read())
        {
         Continue = true;
        }
       }

       if (Continue)
       {
        // CreateObject:给objType类型的对象逐个赋值并返回。
        objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
       }
       else
       {
        objFillObject = null;
       }

       if (ManageDataReader)
       {
        if (dr != null)
        {
         dr.Close();
        }
       }

       // 返回对象
       return objFillObject;
      }

      /// <summary>
      /// 用dr填充一个objType对象数组,并返回。
      /// </summary>
      /// <param name="dr">存储对象数据的DataReader</param>
      /// <param name="objType">对象类型</param>
      /// <returns>对象数组</returns>
      public static ArrayList FillConllection(IDataReader dr, Type objType)
      {
       // 一个集合
       ArrayList objFillCollection = new ArrayList();
       object objFillObject;

       // GetPropertyInfo:返回存储某类型的所有属性的集合。
       // 取得objType类/接口的属性集合
       ArrayList objProperties = GetPropertyInfo(objType);

       // GetOrdinals:返回dr属性字段索引的数组。
       // 返回索引数组
       int[] arrOrdinals = GetOrdinals(objProperties, dr);

       // 生成多个objType对象
       while(dr.Read())
       {
        objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
        objFillCollection.Add(objFillObject);
       }

       if (dr != null)
       {
        dr.Close();
       }

       // 返回对象数组
       return objFillCollection;
      }

      /// <summary>
      /// 用dr填充一个IList,并返回。
      /// </summary>
      /// <param name="dr">存储对象数据的DataReader</param>
      /// <param name="objType">对象类型</param>
      /// <param name="objToFill">IList</param>
      /// <returns>IList</returns>
      public static IList FillCollection(IDataReader dr, Type objType, IList objToFill)
      {
       object objFillObject;
       int intProperty;

       // GetPropertyInfo:返回存储某类型的所有属性的集合。
       // 取得objType类/接口的属性集合
       ArrayList objProperties = GetPropertyInfo(objType);

       // GetOrdinals:返回dr属性字段索引的数组。
       // 返回索引数组
       int[] arrOrdinals = GetOrdinals(objProperties, dr);

       // 生成多个objType对象
       while (dr.Read())
       {
        objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
        objToFill.Add(objFillObject);
       }

       if (dr != null)
       {
        dr.Close();
       }

       // 返回IList
       return objToFill;
      }


      /// <summary>
      /// 给objType类型的对象赋初始值[空值]。
      /// </summary>
      /// <param name="objObject">赋值对象</param>
      /// <param name="objType">对象类型</param>
      /// <returns>赋初始值的对象</returns>
      public static object InitializeObject(object objObject, Type objType)
      {
       PropertyInfo objPropertyInfo;
       object objValue;

       // GetPropertyInfo:返回存储某类型的所有属性的集合。
       // 取得objType类/接口的属性集合
       ArrayList objProperties = GetPropertyInfo(objType);

       // 依次赋值
       for (int intProperty = 0; intProperty < objProperties.Count; intProperty++)
       {
        // 取得第intProperty个属性
        objPropertyInfo = (PropertyInfo)objProperties[intProperty];

        // 如果该属性允许写入
        if (objPropertyInfo.CanWrite)
        {
         // 将objValue设置为空  根据objPropertyInfo.PropertyType值
         objValue = Null.SetNull(objPropertyInfo);

         // 将给定对象的属性值设置为给定值
         objPropertyInfo.SetValue(objObject, objValue, null);
        }
       }

       // 返回对象
       return objObject;
      }

      public static XmlDocument Serialize(object objObject)
      {
       //  将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。System.Xml.Serialization.XmlSerializer 使您得以控制如何将对象编码到 XML 中。
       XmlSerializer objXmlSerializer = new XmlSerializer(objObject.GetType());
       StringBuilder objStringBuilder = new StringBuilder();

       // 表示可以编写一个有序字符系列的编写器。
       TextWriter objTextWriter = new StringWriter(objStringBuilder);

       // 使用指定的 System.Xml.XmlWriter 序列化指定的 System.Object 并将 XML 文档写入文件,从而引用指定的命名空间。
       objXmlSerializer.Serialize(objTextWriter, objObject);

       // 实现从字符串进行读取的 System.IO.TextReader。 
       StringReader objStringReader = new StringReader(objTextWriter.ToString());

       DataSet objDataSet = new DataSet();

       // 将数据读入到DataSet中
       objDataSet.ReadXml(objStringReader);

       XmlDocument xmlSerializedObject = new XmlDocument();

       // LoadXml:从指定的字符串加载 XML 文档。
       // GetXml:返回存储在 System.Data.DataSet 中的数据的 XML 表示形式
       // 加载DataSet中的数据
       xmlSerializedObject.LoadXml(objDataSet.GetXml());

       return xmlSerializedObject;
      }

      public static object CloneObject(object ObjectToClone)
      {
       try
       {
        // 创建一个与ObjectToClone类型相同的对象
        object newObject = Reflection.CreateObject(ObjectToClone.GetType().AssemblyQualifiedName, ObjectToClone.GetType().AssemblyQualifiedName);

        // 取得newObject对象类型的属性集合
        ArrayList props = GetPropertyInfo(newObject.GetType());

        // 取得ObjectToClone对象类型的属性集合
        ArrayList cloneArr = GetPropertyInfo(ObjectToClone.GetType());

        // 取得属性的数量
        int count = cloneArr.Count;

        for (int i = 0; i < count; i++)
        {
         // 取得第i个属性对象
         PropertyInfo p = (PropertyInfo)cloneArr[i];

         // GetInterface:当在派生类中重写时,搜索指定接口,指定是否要执行区分大小写的搜索。 
         Type ICloneType = p.PropertyType.GetInterface("ICloneable", true);

         // 如果属性可以写入
         if (((PropertyInfo)props[i]).CanWrite)
         {
          // 如果类型不为空
          if (ICloneType != null)
          {
           ICloneable IClone = (ICloneable)p.GetValue(ObjectToClone, null);
           ((PropertyInfo)props[i]).SetValue(newObject, IClone.Clone(), null);
          }
          else
          {
           ((PropertyInfo)props[i]).SetValue(newObject, p.GetValue(ObjectToClone, null), null);
          }

          Type IEnumerableType = p.PropertyType.GetInterface("IEnumerable", true);

          if (IEnumerableType != null)
          {
           IEnumerable IEnum = (IEnumerable)p.GetValue(ObjectToClone, null);
           Type IListType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IList", true);
           Type IDicType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IDictionary", true);

           int j = 0;

           if (IListType != null)
           {
            IList list = (IList)((PropertyInfo)props[i]).GetValue(newObject, null);
            foreach (object obj in IEnum)
            {
             ICloneType = obj.GetType().GetInterface("ICloneable", true);

             if (ICloneType != null)
             {
              ICloneable tmpClone = (ICloneable)obj;
              list[j] = tmpClone.Clone();
              j += 1;
             }
            }
           }
           else
           {
            if (IDicType != null)
            {
             IDictionary dic = (IDictionary)((PropertyInfo)props[i]).GetValue(newObject, null);
             j = 0;

             foreach(DictionaryEntry de in IEnum)
             {
              ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
              if (ICloneType != null)
              {
               ICloneable tmpClone = (ICloneable)de.Value;
              }
              j += 1;
             }
            }
           }
          }
          else
          {
          }
         }
        }

        return newObject;
       }
       catch (Exception exc)
       {
        Reflection.LogException(exc);
        return null;
       }
      }
     }
    }

  • 相关阅读:
    Hello World!
    Nginx加权轮询算法
    git常用命令
    linux命令
    sql 表值函数与标量值函数
    数据查询和操纵时连接的打开状态
    插入一条和上一条数据关联的数据
    C# 输出24小时格式时间
    c#中用sql存储过程
    AndroidManifest.xml文件解析
  • 原文地址:https://www.cnblogs.com/admin11/p/193298.html
Copyright © 2020-2023  润新知