好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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)详解(实现方法和属性的动态)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

dy("nrwz");

查看更多关于C#动态对象(dynamic)详解(实现方法和属性的动态)的详细内容...

  阅读:154次