当前位置: 移动技术网 > IT编程>开发语言>c# > C#动态对象(dynamic)详解(实现方法和属性的动态)

C#动态对象(dynamic)详解(实现方法和属性的动态)

2019年07月18日  | 移动技术网IT编程  | 我要评论

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

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

public delegate object mydelegate(dynamic sender, params object[] pms);

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

public class delegateobj
  {
    private mydelegate _delegate;

    public mydelegate callmethod
    {
      get { return _delegate; }
    }
    private delegateobj(mydelegate d)
    {
      _delegate = d;
    }
    /// <summary>
    /// 构造委托对象,让它看起来有点javascript定义的味道.
    /// </summary>
    /// <param name="d"></param>
    /// <returns></returns>
    public static delegateobj function(mydelegate d)
    {
      return new delegateobj(d);
    }
  }

3) 定义一个动态对象:

public class dynobj : dynamicobject
  {
    //保存对象动态定义的属性值
    private dictionary<string, object> _values;
    public dynobj()
    {
      _values = new dictionary<string, object>();
    }
    /// <summary>
    /// 获取属性值
    /// </summary>
    /// <param name="propertyname"></param>
    /// <returns></returns>
    public object getpropertyvalue(string propertyname)
    {
      if (_values.containskey(propertyname) == true)
      {
        return _values[propertyname];
      }
      return null;
    }
    /// <summary>
    /// 设置属性值
    /// </summary>
    /// <param name="propertyname"></param>
    /// <param name="value"></param>
    public void setpropertyvalue(string propertyname,object value)
    {
      if (_values.containskey(propertyname) == true)
      {
        _values[propertyname] = value;
      }
      else
      {
        _values.add(propertyname, value);
      }
    }
    /// <summary>
    /// 实现动态对象属性成员访问的方法,得到返回指定属性的值
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool trygetmember(getmemberbinder binder, out object result)
    {
      result = getpropertyvalue(binder.name);
      return result == null ? false : true;
    }
    /// <summary>
    /// 实现动态对象属性值设置的方法。
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool trysetmember(setmemberbinder binder, object value)
    {
      setpropertyvalue(binder.name, value);
      return true;
    }
    /// <summary>
    /// 动态对象动态方法调用时执行的实际代码
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool tryinvokemember(invokememberbinder binder, object[] args, out object result)
    {
      var thedelegateobj = getpropertyvalue(binder.name) as delegateobj;
      if (thedelegateobj == null || thedelegateobj.callmethod == null)
      {
        result = null;
        return false;
      }
      result = thedelegateobj.callmethod(this,args);
      return true;
    }
    public override bool tryinvoke(invokebinder binder, object[] args, out object result)
    {
      return base.tryinvoke(binder, args, out result);
    }
  }

应用测试代码:

dynamic theobj = new dynobj();
      theobj.aaa = "this is a test";//动态属性
      //动态方法,这里不能没法定义参数,调用的时候可以是任意多参数,具体参数类型和含义就只能自己去小心处理了.
      theobj.show = delegateobj.function((s, pms) =>
      {
        if (pms != null && pms.length > 0)
        {
          messagebox.show(pms[0].tostring() + ":" + s.aaa);
        }
        else
        {
          messagebox.show(s.aaa);
        }
        return null;
      }
      );
      
theobj.show("hello");

虽然看起来上面有点js定义对象方法的味道,但由于c#是静态语言,提供的动态模拟机制还是有限的,看起来是动态,但所有的值存放和方法都需要自己写代码去处理.

上面代码在vs2010,windows 2008 server,框架4.0 上测试ok.

以上这篇c#动态对象(dynamic)详解(实现方法和属性的动态)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网