首页 新闻 会员 周边

c#使用反射技术动态执行方法时如何取引用类型参数的值?

0
悬赏园豆:100 [已关闭问题]

本人想通过反射技术动态加载dll来执行方法并取引用类型参数的值。下面是我的代码:

MYService.dll中存在函数GetDataTable  原型:

public int GetDataTable(string SQLCommand, ref DataTable Result);

本人想通过反射动态加载MYService.dll,来执行GetDataTable 并获取 DataTable Result 中的ref 返回的值,但我每次执行都返回了空对象?是否应该用指针去做,还是有别的方法?请各位大大指点迷津!!跪谢!

贴完整代码如下:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System.Data;
using System.Text;
using System.Data.SqlClient;

namespace TEST

    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {

            
            Program.INITAPP();

        }

        private static  void INITAPP()
        {
      
            DataTable dt = new DataTable();

            object[] paramArray = new object[] { "select * from xxxx",dt }; //传递的参数
   

        

            Type[] paramTypes = new Type[2];
            paramTypes[0] = Type.GetType("System.String");
            paramTypes[1] = Type.GetType("System.Data.DataTable&,System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");


            try
            {

                Assembly assm = Assembly.LoadFrom(Application.StartupPath + @"\MYService.dll");
                Type objType = assm.GetType("com.MYService.TableService",true);
                object objInstance = Activator.CreateInstance(objType, true);
              
                MethodInfo mi = objType.GetMethod(
                    "GetDataTable",
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                    null,
                    paramTypes,
                    null
                    );
                //返回空对象
               
               // MethodInfo mi = objType.GetMethod("GetDataTable",paramTypes);


                if (mi != null)
                {
         
           
                    object result = mi.Invoke(objInstance,paramArray);
                    DataTable rs = (DataTable)paramArray[1];//需要取回的结果,但现在老为空,不知道啥原因
                    
                }

                
            }
            catch (Exception e)
            {

                MessageBox.Show(e.Message+"\n\n"+e.StackTrace);
            }
 
        }


    }
}

Not Coder Neither Developer的主页 Not Coder Neither Developer | 初学一级 | 园豆:20
提问于:2010-06-23 14:53
< >
分享
其他回答(5)
0

http://msmvps.com/blogs/peterritchie/archive/2008/04/29/overcoming-problems-with-methodinfo-invoke-of-methods-with-by-reference-value-type-arguments.aspx

上面文章好像说用值类型做ref 会有问题,但你这个是应用类型,很奇怪,那个评论里面有人说可以用委托来做,你试试吧。

eaglet | 园豆:17139 (专家六级) | 2010-06-23 15:37
不是看的很明白,谢谢
0

关注这个问题,之前还真没处理过这种情况;

winzheng | 园豆:8797 (大侠五级) | 2010-06-23 17:09
0

关注,晚点研究一下看能不能帮得上楼主.

 

paramTypes[1] = Type.GetType("System.Data.DataTable&,System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");


里面怎么多了个&符号?

实际上这行不用这么写,直接paramTypes[1] = typeof(DataTable)就行了

搞错了,&是表示ref


object result = mi.Invoke(objInstance,paramArray);

还有就是楼主能单步到这行代码吗?如果进不去,说明你的mi都没有取到对应的方法.

按照楼主的代码写了些测试代码,可以取得ref的数据.不知道楼主是不是在取mi的时候出了问题,还是说mi.invoke可以执行,但table仍然取不到?那会不会是sql语句的问题或是指定的查询本来就没有取到数据.

I,Robot | 园豆:9783 (大侠五级) | 2010-06-23 17:57
哥们,谢谢你的帮助 里面怎么多了个&符号? 就是表示这个数据是ref的 另外paramTypes[1] = typeof(DataTable) 取得的mi是空的 mi = {Int64 DoGetDataTable(System.String, System.Data.DataTable ByRef)} 参考 http://csharpfeeds.com/post/1724/Csharp_Reflection_Part_5.aspx http://topic.csdn.net/t/20040110/16/2652469.html
paramTypes[1] = typeof(DataTable) 这样mi对象是空的 sql和数据没有问题
0

像普通一样调用就行了,有问题欢迎来群交流:51021155

钧梓昊逑 | 园豆:945 (小虾三级) | 2010-06-23 19:58
业务需要动态去调用
0

这段代码应该没有问题啊,在MYService.dll中找过原因没?

哈欠懒农 | 园豆:455 (菜鸟二级) | 2010-06-23 20:37
在MYService.dll中应该没有问题,直接调用是可以的
0

最好的办法是把int GetDataTable(string SQLCommand, ref DataTable Result);抽象成个接口I

让你要动态加载的那个程序集实现这个接口I.

然后再I objInstance = (I)Activator.CreateInstance(objType, true);

这样性能没有损失,又方便.

Robird | 园豆:158 (初学一级) | 2010-07-07 20:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册