如何通过反射调用类中的<泛型>方法
来源:互联网 发布:北京朝阳教育网络视频 编辑:程序博客网 时间:2024/05/29 15:50
定义的接口:
namespace IProgramShut{ public interface IShut { /// <summary> /// 操作名称 /// </summary> string OperatorName { get; } /// <summary> /// 操作方法 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="t"></param> /// <returns></returns> TResult Operator<T, TResult>(T t); }}
派生自接口的派生类:
namespace ProgramShutDown{ public class ProgramShutDown :IShut { /// <summary> /// 显示“关机”字样 /// </summary> public string OperatorName { get { return "关机"; } } /// <summary> /// 关机操作 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="t"></param> /// <returns></returns> public TResult Operator<T,TResult>(T t) { this.ShutDown(t.ToString()); return default(TResult); } /// <summary> /// 执行关机 /// </summary> /// <param name="second"></param> public void ShutDown(string second) { Process process = new Process(); try { process.StartInfo.FileName = "cmd.exe"; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardInput = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.CreateNoWindow = true; process.Start(); process.StandardInput.WriteLine("shutdown -s -f -t " + second); process.StandardInput.WriteLine("exit"); } catch (Exception ex) { } finally { process.Close(); process.Dispose(); process = null; } } }}
具体的调用方法:
Type t = tsi.Tag as Type; //1、获取指定方法名称的泛型方法 MethodInfo mi = t.GetMethod("Operator"); //2、创建一个对应泛型类型的非泛型反射方法 MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { typeof(int), typeof(int) }); object o = Activator.CreateInstance(t); mi2.Invoke(o, new object[] { 3000 });
其中tsi是一个ToolStripItem对象,
我把通过反射获取到的需要被调用的类的类型存在了ToolStripItem.Tag中了,
MethodInfo mi =t.GetMethod("Operator")通过方法名称获取到泛型方法的版本,
然后在获取到的泛型方法MethodInfo mi的基础上,
通过mi的MakeGenericMethod(new Type[] { typeof(int), typeof(int) })方法,创建一个非泛型版本,
其中
new Type[] { typeof(int), typeof(int)}是用来替换泛型类型 T,TResult的具体类型,
其中
泛型方法在接口中的声明如下:
TResult Operator<T, TResult>(T t);
MethodInfo 类中的 MakeGenericMethod方法在NET中定义如下
// // 摘要: // 用类型数组的元素替代当前泛型方法定义的类型参数,并返回表示结果构造方法的 System.Reflection.MethodInfo 对象。 // // 参数: // typeArguments: // 要替换当前泛型方法定义的类型参数的类型数组。 // // 返回结果: // 一个 System.Reflection.MethodInfo 对象,表示通过将当前泛型方法定义的类型参数替换为 typeArguments 的元素生成的构造方法。 // // 异常: // System.InvalidOperationException: // 当前 System.Reflection.MethodInfo 不表示泛型方法定义。 也就是说,System.Reflection.MethodInfo.IsGenericMethodDefinition // 返回 false。 // // System.ArgumentNullException: // typeArguments 为 null。 - 或 - typeArguments 的所有元素均为 null。 // // System.ArgumentException: // typeArguments 中元素的数目与当前泛型方法定义的类型参数的数目不同。 - 或 - typeArguments 的某个元素不满足为当前泛型方法定义的相应类型参数指定的约束。 // // System.NotSupportedException: // 不支持此方法。 public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments);
第一次尝试的时候是通过mi.Invoke直接调用的爆出了异常:
无法绑定到目标方法,因其签名或安全透明度与委托类型的签名或安全透明度不兼容。
后来查资料再是尝试,找到了另外的调用方式。做个记录。
再说一句:
在这个例子中,想要调用的方法刚好是从接口中继承来的,public类型的方法,
在通过反射调用泛型方法的时候已经获取到了对应类型的实例对象,
原本可以直接通过实例对象调用对应的方法,
但是不排除将来在实际使用的时候想要调用的是private方法,
或者是派生类中特有的定义的方法,这个例子只是凑巧了。
另外做个标记:
通过反射获取泛型类型的具体类型的方法是通过:
Type类的MakeGenericType方法来获取
该方法在NET中的定义如下
// // 摘要: // 替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 System.Type 对象。 // // 参数: // typeArguments: // 将代替当前泛型类型的类型参数的类型数组。 // // 返回结果: // System.Type 表示的构造类型通过以下方式形成:用 typeArguments 的元素取代当前泛型类型的类型参数。 // // 异常: // System.InvalidOperationException: // 当前类型不表示泛型类型定义。 即,System.Type.IsGenericTypeDefinition 返回 false。 // // System.ArgumentNullException: // typeArguments 为 null。 - 或 - typeArguments 的所有元素均为 null。 // // System.ArgumentException: // typeArguments 中元素的个数不等于当前泛型类型定义中类型参数的个数。 - 或 - typeArguments 的所有元素都不满足为当前泛型类型的对应类型参数指定的约束。 // - 或 - typeArguments包含元素,它是一个指针类型 (System.Type.IsPointer返回true),by-ref 类型 // (System.Type.IsByRef返回true),或 System.Void。 // // System.NotSupportedException: // 基类不支持所调用的方法。 派生类必须提供实现。 public virtual Type MakeGenericType(params Type[] typeArguments);
Type t = tsi.Tag as Type; t.MakeGenericType(new object[]{typeof(int),typeof(string),..,..,..}) ;
0 0
- 如何通过反射调用类中的<泛型>方法
- 如何通过反射来调用类方法
- 通过反射调用类中的方法
- 通过反射调用类中的方法
- 通过反射调用其他类中的方法
- 如何通过反射调用方法?
- 如何通过反射调用对象的方法?
- 通过JAVA的反射调用类中的公有私有方法
- 通过反射调用Dll中的方法
- 反射深入 通过反射中的Consrtuctor类调用有参构造方法 普通方法Method
- java如何使用反射调用类中的方法
- 通过反射调用类内部的方法
- 通过反射调用类里面的方法
- JSP中如何通过JSP调用类(.java)中的方法
- 通过反射调用动态连接库中的方法
- 通过Java反射调用方法
- 通过Java反射调用方法
- 通过Java反射调用方法
- 内存查看命令之 - free
- 2.12 带平滑线但无数据标签的散点图
- 第一题
- Stack 含义
- HTML paragraph
- 如何通过反射调用类中的<泛型>方法
- iOS中block实现的探究
- 函数模板
- git 创建远程仓库
- 一套Oracle SQL练习题及答案
- 黑马程序员----Java基础之面向对象(最终篇)
- 2.13带平滑线且带数据标签的散点图
- android adb
- 深入详解Oracle data change notification