• 反射实现Model修改前后的内容对比


    在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责。

    首先我们要创建一个User类

     1     public class User
     2     {
     3         private string name;
     4         public string Name
     5         {
     6             get { return name; }
     7             set { name = value; }
     8         }
     9         private string age;
    10         public string Age
    11         {
    12             get { return age; }
    13             set { age = value; }
    14         }
    15         private string sex;
    16         public string Sex
    17         {
    18             get { return sex; }
    19             set { sex = value; }
    20         }
    21     }

    然后在Main函数中声明并初始化一个User对象

    1             User userA = new User()
    2             {
    3                 Name = "李四",
    4                 Age = "25",
    5                 Sex = "",
    6             };

    因为要对比对象编辑前后的内容,所以需要备份一下这个UserA,我们来个深拷贝

    1 User userB = DeepCopyByXml<User>(userA);
     1         /// <summary>
     2         /// 深拷贝
     3         /// </summary>
     4         /// <typeparam name="T"></typeparam>
     5         /// <param name="obj"></param>
     6         /// <returns></returns>
     7         public static T DeepCopyByXml<T>(T obj) where T : class
     8         {
     9             object retval;
    10             using (MemoryStream ms = new MemoryStream())
    11             {
    12                 XmlSerializer xml = new XmlSerializer(typeof(T));
    13                 xml.Serialize(ms, obj);
    14                 ms.Seek(0, SeekOrigin.Begin);
    15                 retval = xml.Deserialize(ms);
    16                 ms.Close();
    17             }
    18             return (T)retval;
    19         }
    

    接下来的工作是修改UserA的属性,然后和UserB对比,利用反射来实现该功能

            /// <summary>
            /// Model对比
            /// </summary>
            /// <typeparam Name="T"></typeparam>
            /// <param Name="oldModel"></param>
            /// <param Name="newModel"></param>
            private static void CompareModel<T>(T oldModel, T newModel) where T : class
            {
                string changeStr = string.Empty;
                PropertyInfo[] properties = oldModel.GetType().GetProperties();
                Console.WriteLine("--------用户信息修改汇总--------");
                foreach (System.Reflection.PropertyInfo item in properties)
                {string name = item.Name;
                    object oldValue = item.GetValue(oldModel);
                    object newValue = item.GetValue(newModel);
                    if (!oldValue.Equals(newValue))
                    {
                        Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");
                    }
                }
            }

     从运行结果来看我们已经获取到了修改的内容,美中不足的是“Name”和“Age”,如何以中文显示属性名,接下来将利用C#的特性来实现

    新建一个自定义的特性类TableAttribute

        /*     
        参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
        参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
        参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。
         */
        [AttributeUsage(AttributeTargets.Class |
        AttributeTargets.Field |
        AttributeTargets.Property,
              AllowMultiple = false,
              Inherited = false)]
        public class TableAttribute : System.Attribute
        {
            private string fieldName;
            private string tableName;
            /// <summary>
            /// 表名
            /// </summary>
            public string TableName
            {
                get { return tableName; }
                set { tableName = value; }
            }
            /// <summary>
            /// 字段名
            /// </summary>
            public string FieldName
            {
                get { return fieldName; }
                set { fieldName = value; }
            }
        }

    接着修改User类,加上自定义的特性TableAttribute

        /// <summary>
        /// 用户信息实体类
        /// </summary>
        [TableAttribute(TableName = "用户信息")]
        public class User
        {
            private string name;
            [TableAttribute(FieldName = "姓名")]
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            private string age;
            [TableAttribute(FieldName = "年龄")]
            public string Age
            {
                get { return age; }
                set { age = value; }
            }
            private string sex;
            [TableAttribute(FieldName = "性别")]
            public string Sex
            {
                get { return sex; }
                set { sex = value; }
            }
        }

    最后修改一下CompareModel这个方法

     1         /// <summary>
     2         /// Model对比
     3         /// </summary>
     4         /// <typeparam Name="T"></typeparam>
     5         /// <param Name="oldModel"></param>
     6         /// <param Name="newModel"></param>
     7         private static void CompareModel<T>(T oldModel, T newModel) where T : class
     8         {
     9             string changeStr = string.Empty;
    10             PropertyInfo[] properties = oldModel.GetType().GetProperties();
    11             Console.WriteLine("--------用户信息修改汇总--------");
    12             foreach (System.Reflection.PropertyInfo item in properties)
    13             {
    14                 TableAttribute tableAttribute = item.GetCustomAttribute<TableAttribute>();
    15                 string name = item.Name;
    16                 if (tableAttribute != null)
    17                     name = tableAttribute.FieldName;
    18                 object oldValue = item.GetValue(oldModel);
    19                 object newValue = item.GetValue(newModel);
    20                 if (!oldValue.Equals(newValue))
    21                 {
    22                     Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");
    23                 }
    24             }
    25         }

    我们看一下运行结果

     完整demo下载:https://files.cnblogs.com/files/LikeHeart/ExampleReflection.zip

    (完)

  • 相关阅读:
    详解CSS中:nth-child的用法
    网站哀悼变灰代码集合 兼容所有浏览器的CSS变暗代码
    简单CSS3实现炫酷读者墙
    CSS常用浮出层的写法
    五种方法让CSS实现垂直居中
    网页前端开发:微博CSS3适用细节初探
    CSS代码实例:用CSS代码写出的各种形状图形
    10个CSS简写及优化技巧
    25个站长必备的SEO优化工具
    40个让你的网站屌到爆的jQuery插件
  • 原文地址:https://www.cnblogs.com/LikeHeart/p/8905997.html
Copyright © 2020-2023  润新知