昨天编程遇到一个问题两个类字段都是二十多个,其中有十多个是相同的,需要将一个类的字段赋值给另外一个类,开始的自己想手动的一个个去赋值,后来想来一下C#基础知识,用PropertyInfo就可以解决类似的问题,博客园写博客需要内容详实,我还是慢慢的C#属性从头写起,先看下属性的定义吧:

属性定义:它提供灵活的机制来读取、编写或计算某个私有字段的值。 可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。 这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。属性通常可以分为常规属性和自动属性。两者之间还是有一点区别的,最开始编程对着两个全无概念。

常规属性

常规属性以前做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++)
{
              //判断User的属性是不是的Person中
if (userPro[i].Name == personPro[j].Name && userPro[i].PropertyType == personPro[j].PropertyType)
{
Object value=personPro[j].GetValue(person, null);
  //将Person中属性的值赋值给User
                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#中属性PropertyInfo的使用的更多相关文章

  1. VB类模块中属性的参数——VBA中Range对象的Value属性和Value2属性的一点区别

    在VB中,属性是可以有参数的,而VBA中属性使用参数非常常见.比如最常用的:Worksheet.Range("A1:A10")  VB的语法,使用参数的不一定是方法,也有可能是属性 ...

  2. [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  3. 为什么Nhibernate中属性和方法必须Virtual的

    如果你曾经用过NHibernate 2.0或者更高的版本,那您一定碰到过下面的错误:NHibernate.InvalidProxyTypeException: The following types ...

  4. [Tips]ASP.NET MVC 发布到服务器后Model中属性相关的Attribute失效

    Asp.net MVC4 开发的项目,发布到真实环境环境后Model中的一个属性设置的了Attribute,但是这些Attribute都失效. 经过对比和坚持代码发现控制长度的Attribute使用错 ...

  5. 坑爹的vector iterators incompatible错误(VS中属性页-->C/C++-->代码生成-->>运行库)

    之前一直被这个错误折磨着,就是不知道问题在那,后来找了很多资料,大概都是说这是因为多个线程同时操作vector的问题(参考这里).可是我这里的代码并没有问题,因为同样的代码在别的解决方案中已经成功运行 ...

  6. <mate>标签中属性/值的各个意思

    <mate>标签中属性/值的各个意思 HTML 4 name 属性 1.<mate name="author" content="" /> ...

  7. Flex的 Event中属性currentTarget与target的区别

    Flex的 Event中属性currentTarget与target的区别 1.区别 (1)currentTarget是事件的处理对象(event processor) (2)target是事件的调用 ...

  8. 【JVM虚拟机】(7)---深入理解Class中-属性集合

    #[JVM虚拟机](7)---深入理解Class中-属性集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机](6)- ...

  9. C# 求链表 list 中 属性的 最大值 最小值

    获取链表List中对象属性最大值最小值(Max,Min)的方法: 1.创建一个类,类中有一个属性A /// <summary> /// 用于测试属性的类 /// </summary& ...

随机推荐

  1. 【*】Redis常见问题汇总

    1.什么是Redis? Redis是一个开源.高性能.基于键值对的缓存与存储系统. 2.Redis相比memcached有哪些优势? 劣势:Redis是单线程,Memcached是多线程,在多核服务器 ...

  2. 微信小程序official-account组件开发

    今天微信公众平台发了一条消息 扫码打开小程序新增公众号关注组件 官方apihttps://developers.weixin.qq.com/miniprogram/dev/component/offi ...

  3. CF632D Longest Subsequence

    D. Longest Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. [漏洞复现] CVE-2017-11882 通杀所有Office版本

    此漏洞是由Office软件里面的 [公式编辑器] 造成的,由于编辑器进程没有对名称长度进行校验,导致缓冲区溢出,攻击者通过构造特殊的字符,可以实现任意代码执行. 举个例子,如果黑客利用这个漏洞,构造带 ...

  5. [Luogu5161]WD与数列(后缀数组/后缀自动机+线段树合并)

    https://blog.csdn.net/WAautomaton/article/details/85057257 解法一:后缀数组 显然将原数组差分后答案就是所有不相交不相邻重复子串个数+n*(n ...

  6. OD基本汇编指令

    jmp ;无条件跳转 指哪飞哪 一些杂志中说的直飞光明顶,指的就是它了~ 光明顶一般指爆破地址根据条件跳转的指令:JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转   JNZ ;不为 ...

  7. 模板 快速询问GCD

    快速询问两个数的GCD 我觉得只有智障会卡这个玩意儿-- const int maxn = 1e6; const int Sqrt_N = 1e3; int pre[maxn + 1] , decom ...

  8. C# 推送模板

    C#推送模板.安卓个推.消息推送 http://docs.getui.com/server/csharp/template/

  9. YS报警权限验证安全设计

    1.总体流程图:   备注: 1. 使用加时间戳的方式优点是可以不用对报警请求进行加密,也可以防止信令重放,缺点是每次都要去DAS获取新的签名.

  10. C++ 模板的编译 以及 类模板内部的实例化

    在C++中.编译器在看到模板的定义的时候.并不马上产生代码,仅仅有在看到用到模板时,比方调用了模板函数 或者 定义了类模板的 对象的时候.编译器才产生特定类型的代码. 一般而言,在调用函数的时候,仅仅 ...