反射的另一种功能

说到反射嘛,估计各位不陌生,尽管很多人不知道到底是什么,当然也有人将其看作是“反编译” ,有点像吧,但不能说是反编译,虽然有个“反”字,但没有“编译”。

所以,我给反射下了 这样一个概述,准确与否,也不清楚:

反射可以动态获取程序集信息,或程序集中的类型信息 ,以方便动态调用。

动态调用的好处是节约资源,通常情况下,我们添加程序集引用会在项目 的引用中加入,这意味着只要应用程序运行了,这些程序集就会被加载,不管你是否需要调用。对于调 用较少的程序集,如果考虑在调用时才加载,调用完了就释放,这样会在一定程度上节约内存占用,当 然这不是优化代码的唯一方法,其实代码优化是没有固定规则的,综合而灵活去运用各种技巧都可以优 化代码和提高性能。

反射重点在于“动态”二字上,我忽然想到了数据绑定,于是我想到一些 东西,平时我们做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
足部反射区的功能图解、反射和人脑的高级功能、脑功能反射治疗仪、双向反射分布功能、设计的另一种叫法,以便于您获取更多的相关知识。

时间: 2024-12-21 23:41:52

反射的另一种功能的相关文章

CMS智能建站系统必备五种功能浅析

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 现在有很多免费的cms建站系统,有功能比较强大的,也有功能很一般的,有的是个人开发的cms系统,也有团队开发的cms系统,对于功能众多的cms系统往往会令很多新手站长不知道从何选择,如果功能太多,自己又不容易掌握,功能太少,容易掌握了吧却又不具备SEO优化的优势,实在是不知道如何取舍,下面我们就来介绍cms建站系统必备的五个功能,当你发现你选

安卓 开源-请问网上开源的安卓项目,像SlidingMenu,怎么用其中一种功能?

问题描述 请问网上开源的安卓项目,像SlidingMenu,怎么用其中一种功能? 请问网上开源的安卓项目,像SlidingMenu,怎么用其中一种功能?全部导入太大了,还有如果我还想用其他开源的功能怎么办?望大神帮助,谢谢 解决方案 额,这个不怎么好分隔吧,里面的源代码之间都是有联系的,slidingMenu本身也不是很大,凑合用吧

架构,改善程序复用性的设计~第三讲 实现一种功能的代码只能出现在一处(续)

原文:架构,改善程序复用性的设计~第三讲 实现一种功能的代码只能出现在一处(续) 在写完架构,改善程序复用性的设计~第三讲 实现一种功能的代码只能出现在一处 ,这篇文章后,得到了园友的反馈,说这种简单的业务逻辑还可以,但业务比较复杂时,根据就没法用这种方法. 针对这个问题,我觉得有必要再写一个续集了,呵呵! 上回说的主要核心内容是将公用的部分从一个方法中提取出来,生成一个新的方法,这个重构中叫做"提取到方法",另外一个核心内容就是方法的"单一职责",即一个方法干一件

PHP开发网站常用的21种功能的代码汇总

PHP 是目前使用最广泛的基于 Web 的编程语言,驱动着数以百万计的网站,其中也包括如 Facebook 等一些大型站点.这里收集了 21 段实用便捷的 PHP 代码摘录,对每种类型的 PHP 开发者都会有所帮助. 1. 可阅读随机字符串 此代码将创建一个可阅读的字符串,使其更接近词典中的单词,实用且具有密码验证功能. /***************@length - length of random string (must be a multiple of 2)*************

AngularJS 让人爱不释手的八种功能_AngularJS

八种AngularJS让人爱不释手的功能分享给大家,供大家参考,具体内容如下 第一 迭代输出之ng-repeat标签 ng-repeat让table ul ol等标签和js里的数组完美结合 <ul> <li ng-repeat="person in persons"> {{person.name}} is {{person.age}} years old. </li> </ul> 你甚至可以指定输出的顺序: <li ng-repea

PHP入门需要掌握的几种功能代码

经典循环例子 <HTML> <HEAD> <TITLE>经典循环例子</TITLE> </HEAD> <BODY> <?     for($counter = 1; $counter <= 6; $counter++)        //循环6次     {         print("<B>counter is $counter</B><BR>n");    //

Win7系统中键盘ESC键的4种功能介绍

  ESC键的简介: 电脑键盘上的Esc键诞生于1960年,位于电脑键盘的左上方,英文单词escape的缩写.escape翻译成中文为逃脱, 逃跑,漏出, 泄漏之意.对于一般用户而言,ESC键并不常用,但是借助ESC键却能实现不少快捷操作. ESC的功能: 1.停止作用 在浏览器中浏览网页,不小心点错了一个网页,按ESC键就可以停止打开网页. 2.清除网页填写的数据 在一个网站上注册时,会让你填写资料,不小心很多数字都填错了,按ESC键可清除所有的框内数据;而打字时,打错了也可以按ESC键来清除

可以通过基类实现的几种功能。vs2008 .net 2.0

    我很懒,很不喜欢写重复的代码,一行重复的都不想写,所以当同一段代码要写第二遍的时候,我就会去想避免的方法.OO的特性之一 -- 继承 -- 可以帮很大的忙.     这里只说UI部分,先看一个类的图.(我也不知道应该叫做什么图) (TestList .TestForm是网页.aspx ,上面的都是类 .cs )     一般的软件(比如OA.CRM等)都是需要先登录,需要有一定的权限才能够访问,那么每个页面都需要验证一下是否已经登陆了,或者登录是否超时,以及是否有访问页面的权限,在具特点

如何通过反射实现动态功能模块加载

原文:如何通过反射实现动态功能模块加载 程序集包含模块,而模块包含类型,类型又包含成员.反射则提供了封装程序集.模块和类型的对象.您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型.然后,可以调用类型的方法或访问其字段和属性. 下面我们将介绍如何通过不使用反射的方式和使用反射的方式加载功能模块.实现效果:   1.        WinForm 主程序 主程序我们使用Winform程序,VS2008 工具C#语言开发.包括工具栏.状态栏及TabControl控件.我