• C#中属性PropertyInfo的使用


    常规属性

     常规属性以前做Winform的时候经常使用,现在开始使用EF,基本上都是使用自动属性,看下常规属性的完成构成:

    1.私有字段,一般设置为私有,通过属性来赋值保证起安全性:

    private string _age;

    2.get访问器,负责读取数据,其中可以进行自己的逻辑判断和数据验证,以return或者throw结束:

    get
     {
         //年龄返回值判断
         return _age> 0 ? _age: 0;
     }

    3.set访问器,负责给属性赋值,类似于一个返回类型为void的方法,可以包含逻辑处理,例如可以根据默认的值通过计算后返回结果。

    自动属性

       上面简单的说了一下常规属性,当属性访问器中不需要其他逻辑时,可以使用自动属性,不过需要注意一点的就是声明自动属性时,编译器将创建一个私有的匿名后备字段,该字段只能通过属性的 get 和 set 访问器进行访问。

    public int Id { get; set; }

    自动属性没有太多可以可以说的东西,简单的对比一下常规属性和自动属性之间的区别吧:

            1.自动实现的属性必须同时声明 get 和 set 访问器。创建 readonly 自动实现属性时,需要将set 访问器设置为private 。

            2自动实现的属性上可以使用特性,不能用在支持后备字段上。 如果属性的后备字段上使用特性,则应该只创建常规属性。
            3.自动实现属性get,和set中不能包含特殊的逻辑处理。与字段类似,但不同于字段。与字段不同,属性不作为变量来分类,不能将属性作为 ref参数或 out参数传递。

    属性PropertyInfo的使用

     上面大概简单的说了一下属性和自动属性之间的区别,现在可以回归到文中最开始的时候的那个问题:

    1.案例1,如果两个类中有大部分的字段相同,需要将其中一个类的字段赋值给另外一个类:

    定义Person类:

    public class Person {
           public Person(int id,string name,string address)
           {
               this.Id = id;
               this.Name = name;
               this.Address = address;
           }
           public int Id { get; set; }
           public string Name { get; set; }
           public string Address { get; set; }
       }

    定义User类

    public class User {
           public int Id { get; set; }
           public string Name { get; set; }
           public string Group { get; set; }
    }

    转换方法:

    public static User ConvertObject(User user,Person person)
           {
               PropertyInfo[] userPro = user.GetType().GetProperties();
               PropertyInfo[] personPro = person.GetType().GetProperties();
               if (userPro.Length>0&&personPro.Length>0)
               {
                   for (int i = 0; i < userPro.Length; i++)
                   {
                       for (int j = 0; j < personPro.Length; j++)
                       {<br>              //判断User的属性是不是的Person中
                           if (userPro[i].Name == personPro[j].Name && userPro[i].PropertyType == personPro[j].PropertyType)
                           {
                               Object value=personPro[j].GetValue(person, null);
                              //将Person中属性的值赋值给User<br>                  userPro[i].SetValue(user,value , null);
                           }
                       }
                   }
               }
               return user;
    }

    方法的调用:

    static void Main(string[] args)
          {
              Person person = new Person(1,"FlyElephant","北京");
              User user = new User();
              user.Id = 20;
              user = ConvertObject(user, person);
              Console.WriteLine("Id:" + user.Id + "Name:" + user.Name + "角色:" + user.Group);
              System.Console.Read();
          }

    2.之前在做Winform的时候就经常回使用到SqlHelper,现在也有很多公司是这么使用的,当时很多东西感觉就是重复性的操作,一度以为编程只是复制粘贴,下面这段代码大家应该很常见:

    List<Person> list = new List<Person>();
    SqlDataReader sdr = new SqlDataReader();
    while (sdr.Read())
    {
        Person person = new Person();
        person.Name = sdr.GetString(0);
        //....下面类似
        list.Add(person);
    }

    开始写的时候觉得是锻炼了,写的多了就觉得无聊了,其实完全可以换一种方式来实现上面的代码:

    public static List<T> ConvertData<T>(SqlDataReader sdr)
         {
             List<T> list = new List<T>();
             Type type = typeof(T);
             PropertyInfo[] properties = type.GetProperties();
             while (sdr.Read())
             {
                 T model = Activator.CreateInstance<T>();
                 for (int i = 0; i < properties.Length; i++)
                 {
                     for (int j = 0; j < sdr.FieldCount; j++)
                     {
                         //判断属性的名称和字段的名称是否相同
                         if (properties[i].Name == sdr.GetName(j))
                         {
                             Object value =sdr[j];
                             //将字段的值赋值给User中的属性
                             properties[i].SetValue(model, value, null);
                         }
                     }
                 }
                 list.Add(model);
             }
             return list;
         }
    List<User> list = new List<User>();
    SqlDataReader sdr = cmd.ExecuteReader();
    list = ConvertData<User>(sdr);

    3.案例三,ajax页面传递值可以使用get方式,或者post方式的传递JSON格式数据转换

     简单的转换一个get传递的字符串Name=xx&Age=xx,后台直接用一个字典去模拟了:

    Dictionary<string, object> dic = new Dictionary<string, object>();
    dic.Add("Id",100);
    dic.Add("Name", "keso");
    dic.Add("Group", "程序员");

    转换字典方法:

    public static T ConvertDic<T>(Dictionary<string, object> dic)
          {
              T model = Activator.CreateInstance<T>();
              PropertyInfo[] modelPro = model.GetType().GetProperties();
              if (modelPro.Length > 0 && dic.Count() > 0)
              {
                  for (int i = 0; i < modelPro.Length; i++)
                  {
                      if (dic.ContainsKey(modelPro[i].Name))
                      {
                          modelPro[i].SetValue(model, dic[modelPro[i].Name], null);
                      }
                  }
              }
              return model;
          }

    最后的调用:

    User user = ConvertDic<User>(dic);
  • 相关阅读:
    吴裕雄--天生自然C++语言学习笔记:C++ 存储类
    吴裕雄--天生自然C++语言学习笔记:C++ 修饰符类型
    吴裕雄--天生自然C++语言学习笔记:C++ 常量
    吴裕雄--天生自然C++语言学习笔记:C++ 变量作用域
    吴裕雄--天生自然C++语言学习笔记:C++ 变量类型
    吴裕雄--天生自然C++语言学习笔记:C++ 数据类型
    吴裕雄--天生自然C++语言学习笔记:C++ 注释
    吴裕雄--天生自然C++语言学习笔记:C++ 基本语法
    SPOJ375Query on a tree I(树剖+线段树)(询问边)
    HDU5768Lucky7(中国剩余定理+容斥定理)(区间个数统计)
  • 原文地址:https://www.cnblogs.com/xubao/p/13985313.html
Copyright © 2020-2023  润新知