///如未特別說明,本人所發表的技術文章都為原創, 任何人引用都請包含本聲明
///作者: csdn網名alias88,郵件:[email protected],qq:63343 ,歡迎加我
    /// <summary>
    ///依導航路徑調用對象成員方法,或返回對象其子、孫屬性或字段成員.
///例子: 
///獲得表的第二列的名稱
///getmember(datatable1.gettype(),"columns.item.name",datatable1,1)     
///執行表的select方法,并返回可能的datarow數組
///getmember(datatable1.gettype(),"select",datatable1,"客戶編號 = 'c0001')
///取活動表單的名稱,靜態成員不需傳入obj
///getmember(typeof("system.windows.forms.form"),"activeform.name",null,null) 
    /// </summary>
    /// <param name="type">獲得此類型的子孫成員</param>
    /// <param name="memberpath">子孫成員的路徑描述,以點作為分隔符</param>
    /// <param name="obj">如果成員是靜態類型,則為null</param>
    /// <param name="args">參數,注意此參數只能為memberpath最后一個成員使用</param>
    /// <returns></returns>
    public static object getmember(type type,string memberpath,object obj,object[] args)
    {
      if (memberpath==null || memberpath.trim ()=="")
        throw new argumentexception ("缺少必需的參數","memberpath");
      if (type==null )
        throw new argumentexception ("缺少必需的參數","type");
 
      type _objecttype=type;
      object _object=obj;
 
      object[] paras=null;
      string[] strmember=memberpath.split ('.');
      for (int i=0; i<strmember.length  ;i++)
      {
        string membername=strmember[i];
        if (i>=strmember.length-1 )
          paras=args;
          
        _object = _objecttype.invokemember(membername, 
          bindingflags.public | bindingflags.nonpublic | 
          bindingflags.instance | bindingflags.static |
          bindingflags.getfield |  bindingflags.getproperty |
          bindingflags.invokemethod | bindingflags.ignorecase ,
          type.defaultbinder,  _object, paras);
 
        if (_object!=null)
          _objecttype=_object.gettype ();
        else if (i<strmember.length-1)
          throw new argumentnullexception(membername);
      }
      return _object;
    }