在翻看cSDN的帖子时看到这个帖子。我一想太可笑了。帖子如下标题:关于实例化的一个问题 http://community.csdn.net/Expert/topic/5719/5719785.xml?temp=.7946283这个帖子中思归的回贴是用反射(如果你的方法不是处于当前对象内,把this换成对应方法的对象引用):System.Reflection.MethodInfo mi = this.GetType().GetMethod(bb.Key);
mi.Invoke(this,null);
还有一位回的是下面的代码示例演示如何使用反射进行动态方法查找。注意,不能使用基类的 MethodInfo 对象来调用派生类中的重写方法,因为后期绑定无法解析重写方法。
using System;
using System.Reflection;
using System.Windows.Forms;public class A
{
    public virtual int method () {return 0;}
}
 
public class B
{
    public virtual int method () {return 1;}
}
 
class Mymethodinfo
{
    public static int Main()
    {
        Console.WriteLine ("\nReflection.MethodInfo");
        A MyA = new A();
        B MyB = new B();
 
        // Get the Type and MethodInfo.
        Type MyTypea = Type.GetType("A");
        MethodInfo Mymethodinfoa = MyTypea.GetMethod("method");
 
        Type MyTypeb = Type.GetType("B");
        MethodInfo Mymethodinfob = MyTypeb.GetMethod("method");
 
        // Get and display the Invoke method.
        Console.Write("\nFirst method - " + MyTypea.FullName +
            " returns " + Mymethodinfoa.Invoke(MyA, null));
        Console.Write("\nSecond method - " + MyTypeb.FullName +
            " returns " + Mymethodinfob.Invoke(MyB, null));
        return 0;
    }
}
我想笑的是,Invoke方法必须用实例名作为参数,可是已经有了实例就直接用吧,还用反话干什么啊,是不是费事的程序大家说说,这么用反射来实例化类是不是错了。

解决方案 »

  1.   

    @hbxtlhx(平民百姓-自已动手,丰衣足食)您对此有什么看法,我说的对不??
      

  2.   

    @hbxtlhx(平民百姓-自已动手,丰衣足食) 
    我发现,上面的代码是MSDN上的,真是晕了,既然有了实例,为什么还用反射来调用那个类的方法呢,这样作的真正意图是什么??hbxtlhx(平民百姓-自已动手,丰衣足食) ,您给说一下
      

  3.   

    上在代码中的 “下面的代码示例演示如何使用反射进行动态方法查找”,我觉得最搞笑了,难道就为了用反射调用方法,而无视已经实例化的类。(我认为正常人,都是直接用MyA.method的)
      

  4.   

    @hbxtlhx(平民百姓-自已动手,丰衣足食)您是第一个真看懂的,给分。
      

  5.   

    public abstract new System.Object Invoke ( System.Object obj , System.Reflection.BindingFlags invokeAttr , System.Reflection.Binder binder , object[] parameters , System.Globalization.CultureInfo culture )
        System.Reflection.MethodBase 的成员摘要:
     当在派生类中重写时,调用具有给定参数的反射的方法或构造函数。  参数:
    obj: 对其调用方法或构造函数的对象。如果方法或构造函数是静态的,则忽略此参数。 
     invokeAttr: 由 System.Reflection.BindingFlags 中的 0 个或多个位标志(如 DefaultBinding、NonPublic 等等)组合而成的位屏蔽。如果 binder 为 null,则将给此参数赋以值 BindingFlags.DefaultBinding;因此,传入的任何值都被忽略。 
     binder: 一个对象,它启用绑定、参数类型的强制、成员的调用以及通过反射进行 MemberInfo 对象的检索。如果 binder 为 null,则使用默认联编程序。 
     parameters:  调用的方法或构造函数的参数列表。这是一个对象数组,这些对象与要调用的方法或构造函数的参数具有相同的数量、顺序和类型。如果没有参数,则此应为 null。  如果此实例表示的方法或构造函数采用 ByRef 参数,那么使用此函数调用该方法或构造函数时,对于该参数不需要特殊的属性。如果数组中的对象未用值来显式初始化,则该对象将包含该对象类型的默认值。对于引用类型的元素,该值为 null。对于值类型的元素,该值为 0、0.0 或 false,具体取决于特定的元素类型。 
     culture: 用于控制类型强制的 CultureInfo 的实例。如果这为 null,则使用当前线程的 CultureInfo。(例如,这对于将表示 1000 的 String 转换为 Double 值是必需的,因为不同的区域性以不同的方式表示 1000。) 返回值:
     Object,包含调用的方法的返回值;对于构造函数则为重新初始化的对象;如果方法的返回类型是 void,则为 null。在调用方法或构造函数之前,Invoke 检查用户是否有访问权限并验证参数是否有效。
      

  6.   

    异常:
    System.Reflection.TargetException: obj 参数为 null 并且此方法不是静态的。  - 或 - obj 的类既不声明也不继承此方法。 
    System.ArgumentException: parameters 参数的类型与此实例所反射的方法或构造函数的签名不匹配。 
    System.Reflection.TargetParameterCountException: parameters 数组的参数数目不正确。 
    System.Reflection.TargetInvocationException: 调用的方法或构造函数引发异常。 
    System.MethodAccessException: 调用方没有调用此构造函数的权限。 
      

  7.   

    如果没有反射确实像那种功能就没有办法实现。不过反射这个概念确实不是新的了,在.net以前,就有过CallByName的用法。
    因为确实这种情况也常出现,所以支持这个功能就是现所当然了。当我们在软件开发的过程中有类型的要求而常规方法不能实现的时候,就是要动态了。比如我们可以不引用Excel而操作Excel导入导出文件,可以通过“插件”的方法来升级程序等其实都可以使用“反射”。如果没有这个功能。这些确实实现不了。
      

  8.   

    @octverve别误会,我没有说你回的可笑,我是说MSDN的文档出的例子可笑。@hbxtlhx我不是太能听懂您说的。现在,我正在找一个用反射来实例化类的例子。可是,还没有找到呢。
      

  9.   

    @xiahouwen(武眉博<活靶子.NET>) 
    听您那意思,用反射就能调用了??不会吧。请您给一个用反射来实例化类的例子
      

  10.   

    如下就是一个生成实例的例子:
    Type type = Type.GetType("namespace.className");
    object obj = Activator.CreateInstance(type);
    Console.WriteLine(obj.ToString());比如可以这样:
    Type type = Type.GetType("Application1.Form1");
    object obj = Activator.CreateInstance(type);
    Console.WriteLine(obj.ToString());
      

  11.   

    不对反,private a和protected 定义的方法也不能用反射来实现啊,您是说错了。实例不能调用,反射一样的。
      

  12.   

    @xiahouwen(武眉博<活靶子.NET>) 不知道是不是我会错您的意思了,private a和protected 定义的方法也不能用反射来实现。您肯定说错了。我刚试过。“当然MS不会在文档中 大声教你用反射去调用私有方法了。”,这么说您作到了调用私有方法??我个人,根本不相信您能作到,就是比尔说的,我也不相信,我只信事实。
      

  13.   

    @hbxtlhx(平民百姓-自已动手,丰衣足食)谢谢您的帮助,您是不是也不信有人能调用“私有方法”,说的太过了。让我又是一阵大笑。希望与你同乐~~~
      

  14.   

    @@keleshiba听您那意思,用反射就能调用了??不会吧。请您给一个用反射来实例化类的例子
    @hbxtlhx(平民百姓-自已动手,丰衣足食)谢谢您的帮助,您是不是也不信有人能调用“私有方法”,说的太过了。-------------------------------
    如下代码30秒前通过测试-------------------------------using System;
    using System.Reflection;
    using System.Collections.Generic;
    public class A
    {
        private  void method () {Console.WriteLine( "I am a private method in class A");}
    }
     
    public class B
    {
        public  void  method () {Console.WriteLine( "I am a public method in class B");}
    }
     
    public class MyClass
    {
    public static void Main()
    {
    RL();

    Console.WriteLine ("\nReflection.MethodInfo\n");
            A MyA = new A();
            B MyB = new B();
     
            // Get the Type and MethodInfo.
            Type t = typeof(A);
    MethodInfo mi1 = t.GetMethod("method", BindingFlags.NonPublic | BindingFlags.Instance);
    mi1.Invoke(MyA, null);

    Type tt = typeof(B);
    MethodInfo mi2 = tt.GetMethod("method");
    mi2.Invoke(MyB, null);
     
          

    RL();
    }

    #region Helper methods private static void WL(object text, params object[] args)
    {
    Console.WriteLine(text.ToString(), args);
    }

    private static void RL()
    {
    Console.ReadLine();
    }

    private static void Break() 
    {
    System.Diagnostics.Debugger.Break();
    } #endregion
    }
      

  15.   

    private void OutMethod(params System.Reflection.MethodInfo[] _methodinfos)
    { foreach (System.Reflection.MethodInfo _methodinfo in _methodinfos)
    {
    Response.Write("<hr>Reflect Type: <b>" + _methodinfo.ReflectedType +"</b><br>");
    Response.Write("Attributes: "+ _methodinfo.Attributes.ToString() + "<br>");

    Response.Write("Method Name: " + _methodinfo.Name +"<br>");
    Response.Write("Return Type: " + _methodinfo.ReturnType +"<br>");

    /// ...
    /// ...
    /// ... System.Reflection.ParameterInfo[] pis = _methodinfo.GetParameters();
    int parCount = 0;
    foreach (System.Reflection.ParameterInfo pi in pis)
    {
    Response.Write("Par"+ (++parCount) +": <i><b>"+ pi.Name + "</b> - " + pi.ParameterType.Name + "</i><br>");
    }
    }
    }
      

  16.   

    又看了半天,我终于明白Lz是说那个文章可笑,其实我也觉得那个例子不太适当。
    随便说一下,反射什么用:需要访问程序元数据的属性。
    检查和实例化程序集中的类型。
    在运行时构建新类型。使用 System.Reflection.Emit 中的类。
    执行后期绑定,访问在运行时创建的类型的方法。
    再一下,刚才楼上几位说的,我认为,反射不可能调用私有方法的。(不知道是不是xiahouwen(武眉博<活靶子.NET>)口误 )
      

  17.   

    @@keleshiba根本不相信您能作到,就是比尔说的,我也不相信,我只信事实。比尔没有说,但确实可以的 ,不知道你有没有做过在任务栏右下脚放置notifyIcon的程序
    MSN点了左键可以出菜单但.net内的只能在右键出菜单,要想左键出菜单,就要用反射调用ShowContextMenu方法了@@octverve
    再一下,刚才楼上几位说的,我认为,反射不可能调用私有方法的。(不知道是不是xiahouwen(武眉博<活靶子.NET>)口误 )你可以测试一下上面我贴的代码,我不相信我的环境有了问题,我这里能够用的,而且以前做的用到notifyIcon的程序左键菜单我就那么做的,一直运行良好。
      

  18.   

    @xiahouwen(武眉博<活靶子.NET>) 不好意思,刚试了您的代码,是可行了,长知识了,我错了~~,向您学习
      

  19.   

    PetShop4.0里为了支持多数据库动态加载类的实例不也用了反射?
    在DALFactory里
            public static PetShop.IDAL.IInventory CreateInventory() {
                string className = path + ".Inventory";
                //利用反射技术,动态加载指定类型
                return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
            }
      

  20.   

    @xiahouwen(武眉博<活靶子.NET>) 请问您说到的notifyIcon是什么??学习,向您学习
      

  21.   

    to xiahouwen(武眉博<活靶子.NET>) 长知识了,Thanks
      

  22.   

    技术问题的探讨,有理有据即可,是人都会犯错学习 from 武眉博<活靶子.NET>
      

  23.   

    @keleshiba
    请问您说到的notifyIcon是什么??学习,向您学习
    比如MSN或者SQLserver服务管理器 关闭按钮或者最小化点击后可以在任务栏出现图标,也可以用作某些服务程序,接受到信息后显示一个小泡泡,比如outlook2003提示有新邮件,
    并且图标上可以有上下文菜单,而MSN的图标可以用左键激出上下文菜单的,我们用.net内的notifyicon组件却只能实现到右键菜单,有时我们也需要左键菜单,而notifyicon的showcontextmenu方法却不是公开的,只有在左键点击内,曲线的使用反射调用此方法显示上下文菜单了。
      

  24.   

    因为以前通过反编译看到了编译好的类的一些私有方法,然而确不能调用成功,然后通过xiahouwen(武眉博<活靶子.NET>) 的代码确实也正确的调用了私有方法“Private”,现在就有点不太明白了。举个例子吧,如果大家手头上有反编译工具的话,可以查看一下大家都能看到的Form类的一个私有方法,比如如下的一个方法(.net2.0)System.Windows.Forms.Form类下有一个方法声明如下:
    private void CallShownEvent();那么我们确实通过如下的方法不能正确的执行:
    Type thisType = this.GetType();
    MethodInfo miThis = thisType.GetMethod("AdjustSystemMenu", BindingFlags.NonPublic | BindingFlags.Instance);
    if (miThis != null)
    {
    miThis.Invoke(this, null);
    }这我就不明白是怎么一回事了。不知道xiahouwen(武眉博<活靶子.NET>) 有没有对此的一些建议。期盼...
      

  25.   

    @hbxtlhxType thisType = this.GetType();---->Type thisType = typeof(Form);因为 this 指的是当前你继承Form的类的实例引用。 该类无法继承Form的私有方法
    那么它的type的GetMethod就无法正确返回一个MethodInfo 另 AdjustSystemMenu有重载 你需要指定一个type数组到GetMethod才能正确调用,如果没有参数使用0长度数组。eg:            Type thisType = typeof( Form );
                Type[ ] types = new Type[ 0 ];            BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod;            MethodInfo miThis = thisType.GetMethod( "AdjustSystemMenu" , bf , null , types , new ParameterModifier[ 0 ] );
                if ( miThis != null )
                {
                    miThis.Invoke( this , null );
                }
      

  26.   

    TO:xiahouwen(武眉博<活靶子.NET>) 哦,意思是说,不能通过反射在子类里直接调用基类的私有方法是吧。
    这个以前还真没有使用过。学习了,谢谢:)
      

  27.   

    反射是可以调用类中的私有方法的,例子如下,love类中有个Display是个私有方法,新建一个控制台应用程序,把下面的代码粘贴进去就可以运行了.using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;namespace ConsoleApplication1
    {
        class Love
        {        public int field1=0;        private string _name;        public Love()
            {        }        public string Name
            {            get
                {                return _name;            }            set
                {                _name = value;            }        }        public int GetInt(int a)
            {            return a;        }        private void Display(string str)
            {            Console.WriteLine(str);        }    }    /// <summary>    /// Class1 的摘要说明。    /// </summary>    class Class1
        {        /// <summary>        /// 应用程序的主入口点。        /// </summary>        [STAThread]        static void Main(string[] args)
            {            //            // TODO: 在此处添加代码以启动应用程序            //            Love love = new Love();            Type type = love.GetType();            Object obj = type.InvokeMember(null,                BindingFlags.DeclaredOnly |                BindingFlags.Public | BindingFlags.NonPublic |                BindingFlags.Instance | BindingFlags.CreateInstance, null, null, args);            //调用没有返回值的方法            type.InvokeMember("Display", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, obj, new object[] { "aldfjdlf" });            //调用有返回值的方法            int i = (int)type.InvokeMember("GetInt", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, obj, new object[] { 1 });            Console.WriteLine(i);            //设置属性值            type.InvokeMember("Name", BindingFlags.SetProperty, null, obj, new string[] { "abc" });            //获取属性值            string str = (string)type.InvokeMember("Name", BindingFlags.GetProperty, null, obj, null);            Console.WriteLine(str);            //设置字段值            type.InvokeMember("field1", BindingFlags.SetField, null, obj, new object[] { 444 });            //获取字段值            int f = (int)type.InvokeMember("field1", BindingFlags.GetField, null, obj, null);            Console.WriteLine(f);            Console.ReadLine();        }    }
    }
      

  28.   

    a 项目引用 b项目b项目里想访问 a 项目的话...反射吧..我目前只在这种没办法循环引用的情况下用了反射..