说到反射嘛,估计各位不陌生,尽管很多人不知道到底是什么,当然也有人将其看作是“反编译” ,有点像吧,但不能说是反编译,虽然有个“反”字,但没有“编译”。
所以,我给反射下了 这样一个概述,准确与否,也不清楚:
反射可以动态获取程序集信息,或程序集中的类型信息 ,以方便动态调用。
动态调用的好处是节约资源,通常情况下,我们添加程序集引用会在项目 的引用中加入,这意味着只要应用程序运行了,这些程序集就会被加载,不管你是否需要调用。对于调 用较少的程序集,如果考虑在调用时才加载,调用完了就释放,这样会在一定程度上节约内存占用,当 然这不是优化代码的唯一方法,其实代码优化是没有固定规则的,综合而灵活去运用各种技巧都可以优 化代码和提高性能。
反射重点在于“动态”二字上,我忽然想到了数据绑定,于是我想到一些 东西,平时我们做UI与数据的绑定时,多数情况下是已知数据项目类型有哪些公共属性,进而绑定到对 象的某个公共属性上。那么试想一下,假如我们事先不知道来自数据源的对象是什么结构,也不清楚它 有哪些公共属性,这样数据绑定起来是不是会有麻烦呢?
这显然是有麻烦的,而且,常规的思 路是很难解决的,那么这时候我们是不是想到了反射呢?不管来自数据源的是什么样的对象类型,我只 要通过反射将它的所有公共属性都找出来,然后再取出对应属性的值,再动态生成UI界面。若能如此, 是不是很爽呢?
我这个人有个缺点,就是一旦想到什么鬼点子,就会迫不及待地试试,故二话 不说,马上扔掉手头上的东西,打开电脑,启动VS,就试着Coding起来了,这一Code还真没白费力气, 总算Code出我的预期效果。
以下是我的大致思路:
首先,编写一个类,提供操作,可以 将任意类型对象的列表转换成WPF中的UI元素,接着再把转换出来的UI元素列表当作数据源,赋给 ListBox的ItemsSource属性,完成绑定。
这样做的好处就是,不管来自数据源的对象列表中的 类有几个公共属性,只要能把它反射出来就行了。
下面是该转换类的代码。
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.ComponentModel.DataAnnotations; namespace MyApp { public class ObjectsConvertToUIFrmws { public IList<FrameworkElement> BuildUIList(IList objs) { List<FrameworkElement> uiList = new List<FrameworkElement>(); foreach (var obj in objs) { FrameworkElement fe = BuildUICore(obj); uiList.Add(fe); } return uiList; } private PropertyInfo[] GetPropertiesFromObj(object o) { return o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); } private Panel BuildUICore(object obj) { if (obj == null) return null; PropertyInfo[] pis = GetPropertiesFromObj(obj); Grid gridRoot = new Grid(); // 有多少个属性就加入多少行,每行显示一个 gridRoot.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); gridRoot.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); for (int i = 0; i < pis.Length; i++) { gridRoot.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); } for (int n = 0; n < pis.Length;n++ ) { var attrs = pis[n].GetCustomAttributes(typeof(DisplayAttribute)).ToArray(); // 获取属性的值 object vl = pis[n].GetValue(obj); if (vl is Color) { // 如果字段表示颜色,则设置为容器的背景色 Color bgColor = (Color)vl; gridRoot.Background = new SolidColorBrush(bgColor); } else { TextBlock tbDisplayName = new TextBlock(); if (attrs != null && attrs.Count() > 0) { DisplayAttribute dispattr = attrs[0] as DisplayAttribute; tbDisplayName.Text = dispattr.Name; } else { tbDisplayName.Text = "未知字段"; } gridRoot.Children.Add(tbDisplayName); Grid.SetRow(tbDisplayName, n); Grid.SetColumn(tbDisplayName, 0); TextBlock tbValue = new TextBlock(); // 如果属性类型为日期时间,则转换字符串格式 if (vl is DateTime) { tbValue.Text = ((DateTime)vl).ToString("yyyy-MM-dd HH:mm:ss"); } else if (vl is double) { // 如果是双精度类型,则要保留三位小数 tbValue.Text = ((double)vl).ToString("N3"); } else { tbValue.Text = vl.ToString(); } gridRoot.Children.Add(tbValue); Grid.SetRow(tbValue, n); Grid.SetColumn(tbValue, 1); } } return gridRoot; } } }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索反射
, 属性
, 类型
, using
, 数据源
, system
动态加载grid
足部反射区的功能图解、反射和人脑的高级功能、脑功能反射治疗仪、双向反射分布功能、设计的另一种叫法,以便于您获取更多的相关知识。