白话讲反射技术 --- 适合初学者入门引导

这篇文章就不讲废话了,反射感觉就像“动态调用”一样的意思,反射跟接口结合在一起用的情况比较多见,若接口到底是什么也没看明白,云里雾里的,反射你先别折腾了,浪费生命意义不大,折腾也是属于瞎搞了,还是踏实的把接口仔细学学,多做几个例子巩固一下。
  还没明白接口,先仔细看看接口的定义、语法等,然后我推荐你看看上篇文章 不懂接口、反射、委托、设计模式足足写了5年的代码 -- 写给初学者(谈美女生成器不谈代码生成器)
  使用反射有几个误区:反射的性能慢?其实未必反射的性能是慢的,说不定有些场合,反射的性能是更快更高效的,不用它的优点,用了他的弱点,那就无法达到高效的目的了,文章的结尾也说说我的观点。
  我在日常开发中反射常用的几个环节,其实架构师架构系统反射等用得多,程序员日常开发里,其实不懂也没啥大不了的。
  1。两个类,需要互相调用了,不能直接进行互相引用了,那不是死循环了?例如我这里2个包里的窗体之间,需要互相调用,就用了反射技术,直接动态的从dll 包里把相应的窗体呼叫出来,当然我也不想用反射但是不用不行了,没有其他更好的解决方法了,我不是为了玩技术用技术,而是实际开发中遇到问题了不用不行了,才用反射技术。

互相引用的例如下面的示意图:
 

程序参考如下:例如按钮按下时,调用了另一个动态库里窗体,当然你也可以把这些放在配制文件里,这样就不是硬编码了,但是我也了懒得搞了,这些命名是很少会发生变化了,配置文件太多了,用户看着眼花,自己也容易眼花,而且都起个合适的英文名称,也需要一些水平,就不瞎折腾了。


其中用到调用反射的程序参考如下:

Code
  1 //------------------------------------------------------------
  2 // All Rights Reserved , Copyright (C) 2009 , Jirisoft , Ltd.
  3 //------------------------------------------------------------
  4
  5 using System;
  6 using System.Collections;
  7 using System.Text;
  8 using System.Data;
  9 using System.Reflection;
 10 using System.Windows.Forms;
 11
 12 namespace DotNet.Common.UILayer.Utilities
 13 {
 14     using DotNet.Common.IService;
 15
 16     /// <summary>
 17     /// CacheManager
 18     /// Assembly 缓存服务
 19     ///
 20     /// 修改纪录
 21     ///
 22     ///        2008.06.05 版本:1.0 JiRiGaLa 创建。
 23     ///       
 24     /// 版本:1.0
 25     ///
 26     /// <author>
 27     ///        <name>JiRiGaLa</name>
 28     ///        <date>2008.06.05</date>
 29     /// </author>
 30     /// </summary>
 31     public class CacheManager
 32     {
 33         private CacheManager()
 34         {
 35         }
 36
 37         private Hashtable ObjectCacheStore = new Hashtable();
 38
 39         private static CacheManager instance = null;
 40         private static Object locker = new Object();
 41
 42         public static CacheManager Instance
 43         {
 44             get
 45             {
 46                 if (instance == null)
 47                 {
 48                     lock (locker)
 49                     {
 50                         if (instance == null)
 51                         {
 52                             instance = new CacheManager();
 53                         }
 54                     }
 55                 }
 56                 return instance;
 57             }
 58         }
 59
 60         /// <summary>
 61         /// 获得一个窗体
 62         /// </summary>
 63         /// <param name="assemblyName"></param>
 64         /// <param name="formName">窗体名</param>
 65         /// <returns>窗体</returns>
 66         public Form GetForm(String assemblyName, String formName)
 67         {
 68             Type type = this.GetType(assemblyName, formName);
 69             return (Form)Activator.CreateInstance(type);
 70         }
 71
 72         public Type GetType(String assemblyName, String name)
 73         {
 74             Assembly assembly = this.Load(assemblyName);
 75             Type type = assembly.GetType(assemblyName + "." + name, true, false);
 76             return type;
 77         }
 78
 79         /// <summary>
 80         /// 加载 Assembly
 81         /// </summary>
 82         /// <param name="assemblyName">命名空间</param>
 83         /// <returns>Assembly</returns>
 84         public Assembly Load(String assemblyName)
 85         {
 86             Assembly assembly = null;
 87             if (this.ObjectCacheStore.ContainsKey(assemblyName))
 88             {
 89                 assembly = (Assembly)this.ObjectCacheStore[assemblyName];
 90             }
 91             else
 92             {
 93                 assembly = Assembly.Load(assemblyName);
 94                 this.ObjectCacheStore.Add(assemblyName, assembly);
 95             }
 96             return assembly;
 97         }
 98
 99         public void Add(String key, Object storeObject)
100         {
101             if (!this.ObjectCacheStore.ContainsKey(key))
102             {
103                 this.ObjectCacheStore.Add(key, storeObject);
104             }
105         }
106
107         public Object Retrieve(String key)
108         {
109             return this.ObjectCacheStore[key];
110         }
111     }
112 }

这里用了一个单实例,就是已经加载过的不要反复 奸奸杀杀、杀杀奸奸了总感觉那样显得没水平没层次,这样做也未必是高效的,但是心里会舒坦很多。我们在开发大型软件项目时经常会遇到,系统很庞大了有几百M的代码了,主程序启动时,总不能把这些都引用了吧?全部加载在内存里?那程序的启动速度,不知道会不会慢如老牛推车了?这时候也会用一些反射技术等,用到哪个窗体,就动态加载哪个那个窗体,总感觉比较清爽一些。

2。我只写一份商业逻辑,但是希望能跑在多种数据库上,我配套每种数据库的商业逻辑部分都相应的写一份,那我的工作量是加倍的,每个包都要进行测试、维护、升级、改进、调试、优化,世界超级大国美国也只能同时进行2个局部战争,你能同时谈3-4个女朋友,那我真服了有本事啊,一般会没多久就会穿帮了,维护几个数据库访问方法倒是不会工作量很大,相对来讲是有限的。

例如我的程序里,都是这么写的:
  
配置文件里,明确指出,我需要用什么数据库,什么连接串等:


我的数据库访问工厂里,按配置读取相应的数据库连接类、实例化相应的类。


  这些用到的反射、系统架构时调试通过了,别人也根本没兴趣研究了,也不需要所有的人都折腾反射,偶尔需要用时,照葫芦画瓢就可以了,先copy然后past,然后修改几个名称什么的,然后run,运行正常了,就懒得管了,不行就dbug。
  我们公司没几个人用到反射,公司里估计就2个人,其中一个也是用DNT的现成的,我这个是自己折腾出来的。实际工作中需要了,就用用,或者想学技术,就自己弄弄,没必要为了显示你技术都少厉害非牵扯个反射出来。

我最讨厌的,用反射的方式有:
   or mapping 什么的,一个类里的属性,方法通过循环读取出来,然后一个类的保存,读取,能自动实现什么的,若有10000个对象的,每个对象有50个属性,那得循环多少次?不是循环死人啊?还有就是 .net 的类型与数据库类型的转换匹配,null 的匹配等空日期的匹配转换,多种数据库类型的转换,我看了这样的代码,就恶心想吐,为了提高性能还需要延迟加载什么的搞得死去活来,我们不是搞研究玩技术的,把项目又快又好又简单的做好,客户满意,能及时拿到项目款就可以了,杀鸡用刀就可以了,别还先打一会儿太极,再品茶啥的,赶紧杀鸡啊,我看着都心急。
   后来事实证明,代码生成器还是蛮好用的,不是靠反射循环搞定问题,而是通过机器来产生代码,这个的确比较好,我也喜欢。我也曾经用过很多乱八七糟的技术,现在懒得玩,懒得学习了,跟着微软屁股后面跑微软哪个成熟了,我就玩那个,平时关注一下发展动向,不是微软的能不用就不用了,我不想折腾了。
  单个技术,都是非常好的,但是组织到一起就容易乱套了,不伦不类,而且把性能优化到最好需要更高的水平了。

  例如,我们每个人心目中都有个完美的女人,让你把这个美女画出来吧,你往往会画出来个魔鬼下人,自己也不敢相信,居然画出了这么个东西来,别人画得很可能比你的好看多了,但是当时就不信不服,总觉得自己能画出更漂亮更美的,可惜啊,我们能都是眼高手低的更多。
  我们经常看到这个美女眼睛漂亮,那个美女鼻子漂亮,那个美女嘴唇漂亮,那我们把这些最美丽的零件都拿过来,再重新组装一个美女出来,你会发现,又出来了一个魔鬼,甚至是更恶魔,哈哈。不是把所有的好的东西拿过来就能拼装出完美的架构来了。

   写代码,架构软件系统也是同样的道理,追求实实在在、赚钱速度快、上手快就可以了,我们心目中永远会有天仙妹妹、神仙姐姐,有时候需要我们更务实,需要学会放弃,有时候放弃也是进步。


 
希望中间的小牛,能给你带来无穷的快乐,我每次看到就会笑一笑。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值