在翻看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方法必须用实例名作为参数,可是已经有了实例就直接用吧,还用反话干什么啊,是不是费事的程序大家说说,这么用反射来实例化类是不是错了。
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方法必须用实例名作为参数,可是已经有了实例就直接用吧,还用反话干什么啊,是不是费事的程序大家说说,这么用反射来实例化类是不是错了。
解决方案 »
- 实现自动注册功能
- 我做登陆页面遇到的问题
- 大数据量下datagrid导入到excel并下载到客户端
- 关于dw 与vs2003 中的ASP.NET 结合的问题。
- 有关DataTable对象问题~
- 散分了。。顶者有分。。。。。一个很简单,但很实用的问题。。。。
- 关于引用office owc的问题
- 关于获取浏览器地址的问题,必须要高手进入了,上次没有解决。
- 求一框架top.aspx,Left.aspx,right.aspx,它能自适应屏幕大小,谁能给我aspx文件呀?[email protected]
- 求教高手一个数据库结合XML存储数据的问题
- Response.WriteFile(fileName.xml)的问题?
- 大侠求救啊,关键时候搞不定了。。。。怎么向ajax框架内的服务器控件赋值啊
我发现,上面的代码是MSDN上的,真是晕了,既然有了实例,为什么还用反射来调用那个类的方法呢,这样作的真正意图是什么??hbxtlhx(平民百姓-自已动手,丰衣足食) ,您给说一下
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 检查用户是否有访问权限并验证参数是否有效。
System.Reflection.TargetException: obj 参数为 null 并且此方法不是静态的。 - 或 - obj 的类既不声明也不继承此方法。
System.ArgumentException: parameters 参数的类型与此实例所反射的方法或构造函数的签名不匹配。
System.Reflection.TargetParameterCountException: parameters 数组的参数数目不正确。
System.Reflection.TargetInvocationException: 调用的方法或构造函数引发异常。
System.MethodAccessException: 调用方没有调用此构造函数的权限。
因为确实这种情况也常出现,所以支持这个功能就是现所当然了。当我们在软件开发的过程中有类型的要求而常规方法不能实现的时候,就是要动态了。比如我们可以不引用Excel而操作Excel导入导出文件,可以通过“插件”的方法来升级程序等其实都可以使用“反射”。如果没有这个功能。这些确实实现不了。
听您那意思,用反射就能调用了??不会吧。请您给一个用反射来实例化类的例子
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());
@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
}
{ 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>");
}
}
}
随便说一下,反射什么用:需要访问程序元数据的属性。
检查和实例化程序集中的类型。
在运行时构建新类型。使用 System.Reflection.Emit 中的类。
执行后期绑定,访问在运行时创建的类型的方法。
再一下,刚才楼上几位说的,我认为,反射不可能调用私有方法的。(不知道是不是xiahouwen(武眉博<活靶子.NET>)口误 )
MSN点了左键可以出菜单但.net内的只能在右键出菜单,要想左键出菜单,就要用反射调用ShowContextMenu方法了@@octverve
再一下,刚才楼上几位说的,我认为,反射不可能调用私有方法的。(不知道是不是xiahouwen(武眉博<活靶子.NET>)口误 )你可以测试一下上面我贴的代码,我不相信我的环境有了问题,我这里能够用的,而且以前做的用到notifyIcon的程序左键菜单我就那么做的,一直运行良好。
在DALFactory里
public static PetShop.IDAL.IInventory CreateInventory() {
string className = path + ".Inventory";
//利用反射技术,动态加载指定类型
return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
}
请问您说到的notifyIcon是什么??学习,向您学习
比如MSN或者SQLserver服务管理器 关闭按钮或者最小化点击后可以在任务栏出现图标,也可以用作某些服务程序,接受到信息后显示一个小泡泡,比如outlook2003提示有新邮件,
并且图标上可以有上下文菜单,而MSN的图标可以用左键激出上下文菜单的,我们用.net内的notifyicon组件却只能实现到右键菜单,有时我们也需要左键菜单,而notifyicon的showcontextmenu方法却不是公开的,只有在左键点击内,曲线的使用反射调用此方法显示上下文菜单了。
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>) 有没有对此的一些建议。期盼...
那么它的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 );
}
这个以前还真没有使用过。学习了,谢谢:)
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(); } }
}