C#的动态对象的属性实现比较简单,如果要实现动态语言那种动态方法就比较困难,因为对于dynamic对象,扩展方法,匿名方法都是不能用直接的,这里还是利用对象和委托来模拟这种动态方法的实现,看起来有点JavaScript的对象味道:

1)定义一个委托,参数个数可变,参数都是object类型:这里的委托多有个dynamic参数,代表调用这个委托的动态对象本身.

  1. public delegate object MyDelegate(dynamic Sender, params object[] PMs);

2)定义一个委托转载对象,因为dynamic对象不能直接用匿名方法,这里用对象去承载:

  1. public class DelegateObj
  2. {
  3. private MyDelegate _delegate;
  4.  
  5. public MyDelegate CallMethod
  6. {
  7. get { return _delegate; }
  8. }
  9. private DelegateObj(MyDelegate D)
  10. {
  11. _delegate = D;
  12. }
  13. /// <summary>
  14. /// 构造委托对象,让它看起来有点javascript定义的味道.
  15. /// </summary>
  16. /// <param name="D"></param>
  17. /// <returns></returns>
  18. public static DelegateObj Function(MyDelegate D)
  19. {
  20. return new DelegateObj(D);
  21. }
  22. }

3) 定义一个动态对象:

  1. public class DynObj : DynamicObject
  2. {
  3. //保存对象动态定义的属性值
  4. private Dictionary<string, object> _values;
  5. public DynObj()
  6. {
  7. _values = new Dictionary<string, object>();
  8. }
  9. /// <summary>
  10. /// 获取属性值
  11. /// </summary>
  12. /// <param name="propertyName"></param>
  13. /// <returns></returns>
  14. public object GetPropertyValue(string propertyName)
  15. {
  16. if (_values.ContainsKey(propertyName) == true)
  17. {
  18. return _values[propertyName];
  19. }
  20. return null;
  21. }
  22. /// <summary>
  23. /// 设置属性值
  24. /// </summary>
  25. /// <param name="propertyName"></param>
  26. /// <param name="value"></param>
  27. public void SetPropertyValue(string propertyName,object value)
  28. {
  29. if (_values.ContainsKey(propertyName) == true)
  30. {
  31. _values[propertyName] = value;
  32. }
  33. else
  34. {
  35. _values.Add(propertyName, value);
  36. }
  37. }
  38. /// <summary>
  39. /// 实现动态对象属性成员访问的方法,得到返回指定属性的值
  40. /// </summary>
  41. /// <param name="binder"></param>
  42. /// <param name="result"></param>
  43. /// <returns></returns>
  44. public override bool TryGetMember(GetMemberBinder binder, out object result)
  45. {
  46. result = GetPropertyValue(binder.Name);
  47. return result == null ? false : true;
  48. }
  49. /// <summary>
  50. /// 实现动态对象属性值设置的方法。
  51. /// </summary>
  52. /// <param name="binder"></param>
  53. /// <param name="value"></param>
  54. /// <returns></returns>
  55. public override bool TrySetMember(SetMemberBinder binder, object value)
  56. {
  57. SetPropertyValue(binder.Name, value);
  58. return true;
  59. }
  60. /// <summary>
  61. /// 动态对象动态方法调用时执行的实际代码
  62. /// </summary>
  63. /// <param name="binder"></param>
  64. /// <param name="args"></param>
  65. /// <param name="result"></param>
  66. /// <returns></returns>
  67. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
  68. {
  69. var theDelegateObj = GetPropertyValue(binder.Name) as DelegateObj;
  70. if (theDelegateObj == null || theDelegateObj.CallMethod == null)
  71. {
  72. result = null;
  73. return false;
  74. }
  75. result = theDelegateObj.CallMethod(this,args);
  76. return true;
  77. }
  78. public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
  79. {
  80. return base.TryInvoke(binder, args, out result);
  81. }
  82. }

测试代码:

  1. dynamic theObj = new DynObj();
  2. theObj.aaa = "this is a test";//动态属性
  3. //动态方法,这里不能没法定义参数,调用的时候可以是任意多参数,具体参数类型和含义就只能自己去小心处理了.
  4. theObj.show = DelegateObj.Function((s, pms) =>
  5. {
  6. if (pms != null && pms.Length > )
  7. {
  8. MessageBox.Show(pms[].ToString() + ":" + s.aaa);
  9. }
  10. else
  11. {
  12. MessageBox.Show(s.aaa);
  13. }
  14. return null;
  15. }
  16. );
  17. theObj.show("hello");

C#动态对象(dynamic)示例(实现方法和属性的动态)的更多相关文章

  1. jQuery源码06-jQuery = function(){};给JQ对象,添加一些方法和属性,extend : JQ的继承方法,jQuery.extend()

    /*! * Includes Sizzle.js 选择器,独立的库 * http://sizzlejs.com/ */ (function( window, undefined ) { //" ...

  2. 利用反射动态从程序集dll执行方法和属性

    程序结构: //获取程序集 Assembly asb = Assembly.LoadFrom(path);//path为程序集的物理路径 //获取程序集下面的Student类 Type documen ...

  3. jquery的2.0.3版本源码系列(3):96行-283行,给JQ对象,添加一些方法和属性

    jquery是面向对象的程序,面向对象就离不开方法和属性. 方法的简化 jQuery.fn=jQuery.prototype={ jquery: 版本 constructor: 修正指向问题 init ...

  4. Js:DOM对象操作常用的方法和属性

  5. python 使用dir() help() 查看一个对象所有拥有的方法和属性

    可以使用python 的内置方法 dir() 或者help() 查看 某个对象所拥有的方法和属性, 二者间的区别是: dir() : 只是得到方法或者属性的名称 help():不但可以得到对象的方法和 ...

  6. 使用Object类为实例定义方法和属性

    1.1 可以使用 Object 类直接定义个实例,并且为该对象赋属性和方法,例如: var person_1 = { nickName:"xiaowu", age:28, show ...

  7. Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置

    Asp.Net SignalR 使用记录   工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...

  8. C# 匿名对象(匿名类型)、var、动态类型 dynamic

    本文是要写的下篇<C#反射及优化用法>的前奏,不能算是下一篇文章的基础的基础吧,有兴趣的朋友可以关注一下. 随着C#的发展,该语音内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑. ...

  9. C# 匿名对象(匿名类型)、var、动态类型 dynamic——实用之:过滤类属性、字段实用dynamic

    例子 返回一个LIst<oject>类型 而oject含有 30个字段 而我只需要两个字段.这里实用dynamic 和 linq. 上代码: 注意select new {} 为匿名类型,这 ...

随机推荐

  1. linux内核中socket的创建过程源码分析(详细分析)

    1三个相关数据结构. 关于socket的创建,首先需要分析socket这个结构体,这是整个的核心. 104 struct socket { 105         socket_state       ...

  2. 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动

    引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...

  3. P1821 [USACO07FEB]银牛派对Silver Cow Party

    题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the b ...

  4. 开启路由转发 - route add -net 0.0.0.0 netmask 0.0.0.0 gateway 192.168.0.131 window tracert 追踪路由

    1.登录方式内网访问172.28.101.0/19网段的方法:在192.168.1.0/24网段的上网机器上,或在自己的操作机上加个192.168.1.0网段的ip,注意不要跟别人设置的冲突了,并添加 ...

  5. 例子:照片的OCR识别

    来自ng的ml-003中 18_XVIII._Application_Example-_Photo_OCR 这是ng2013年在coursera上最后的一课了.这一系列的几个视频还是相比前面有些难懂, ...

  6. 多模匹配算法之Aho-Corasick

    除剔除那些含有敏感词的文本,由于有大量的敏感词,所以通过简单的正则表达式和字符串查找的方式效率太低,每次都有遍历一次字符串.而AC算法的核心思想就是避免不必要的回溯使搜索一直沿着向前的方向,最大可能的 ...

  7. 使用参数化查询防止SQL注入漏洞(转)

    SQL注入的原理 以往在Web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询: string sql * FROM [User] WHERE UserName ...

  8. 浅谈Spring中的事务回滚

        使用Spring管理事务过程中,碰到过一些坑,因此也稍微总结一下,方便后续查阅. 1.代码中事务控制的3种方式 编程式事务:就是直接在代码里手动开启事务,手动提交,手动回滚.优点就是可以灵活控 ...

  9. Scala学习(一)练习

    Scala基础学习&l练习 1. 在Scala REPL中键人3.,然后按Tab键.有哪些方法可以被应用 在Scala REPL中需要按3. 然后按Tab才会提示. 直接按3加Tab是没有提示 ...

  10. CS50.4

    1, PDF,portable document format 便携式文档格式 2, 关于文本编辑器(文字编辑器)和文档编辑器(文字处理器),前者可用来写程序的源代码?名字挺难分辨的. *3, “-o ...