c#反射调用方法示例

获取方法的相关信息的两种形式

反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象;

在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表;该方法的两种形式:

MethodInfo [] GetMethods()

MethodInfo [] GetMethods(BindingFlags bindingflas)  :它的参数带有一些限制 BindingFlags  是一个枚举

枚举成员 [DeclaredOnly,Instance ,Public]   枚举成员的功能使用  在编译器中使用"."符号后自己认真观察 【相信你很快能够理解】

ParameterInfo[]  GetParameters() 方法返回一个方法的参数列表

下面用到的类 MyClass ,为了方便阅读,我把它折叠了!


代码如下:

class MyClass
    {
        int x;
        int y;
        public MyClass(int i, int j)
        {
            this.x = i;
            this.y = j;
        }
        public int Sum()
        {
            return x + y;
        }
        public bool IsBetween(int i)
        {
            if (x < i && i < y)
            {
                return true;
            }
            return false;
        }
        public void Set(int a, int b)
        {
            x = a;
            y = b;
        }
        public void Set(double a, double b)
        {
            x = (int)a;
            y = (int)b;
        }
        public void Show()
        {
            Console.WriteLine("x: " + x + "  y:  " + y);
        }
    }

MyClass

Main:


代码如下:

Type t = typeof(MyClass);//获得一个表示MyClass类的Type对象
            Console.WriteLine("获取当前成员的名称" + t.Name);
            Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            Console.WriteLine("支持的方法");
            #region 第一种形式
            //MethodInfo[] mi = t.GetMethods();//显示Class类中被支持的方法
            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            //方法GetMethods() 把 MyClass 的基类 object方法都显示出来了
            //下面我们说说  GetMethods() 的另外一种形式,有限制的显示
            #endregion
            #region 第二种形式
            MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
            #endregion
            foreach (MethodInfo m in mi)
            {
                //返回后打印出MyClass类中成员的类型(方法的返回值类型)极其方法名称
                Console.Write("  " + m.ReturnType.Name + "  " + m.Name + " (");//ReturnType获取此方法的返回类型
                ParameterInfo[] pi = m.GetParameters();//获得方法的参数
                for (int i = 0; i < pi.Length; i++)
                {
                    Console.Write(pi[i].ParameterType.Name + "   " + pi[i].Name);//ParameterType 获取该参数的Type(类型)
                    if (i+1<pi.Length)
                    {
                        Console.Write(", ");
                    }

}
                Console.WriteLine(")");
                Console.WriteLine();
            }

Console.ReadKey();

使用反射调用方法

上面 讨论了怎么获取一个类型所支持的方法,然而为我们获取对方法的调用做了充分的准备!

MethodInfo类中的Invoke() 方法提供了该技能!

它的一种形式:  object Invoke(object  obj,object [] paramenters)

obj 是一个对象引用,将调用它所指向的对象上的方法,对于static方法,obj必须为null。

所有需要传递给方法的参数都必须在parameters数组中指定。如果方法不需要参数,则paramenters必须为null

基类MethodBase的 Invoke()方法返回被调用方法的返回值

请看下面的事例:

MyClass类Set()方法有所改变:


代码如下:

public void Set(int a, int b)
        {
Console.WriteLine("Set(int,int)");
x = a;
y = b;
Show();
        }
        public void Set(double a, double b)
        {
Console.WriteLine("Set(double,double)");
x = (int)a;
y = (int)b;
Show();
        }

代码如下:

Type t = typeof(MyClass);
MyClass reflectOb = new MyClass(10, 20);
int val;
Console.WriteLine("Invoke methods in " + t.Name);//调用MyClass类的方法
Console.WriteLine();
MethodInfo[] mi = t.GetMethods();

foreach (MethodInfo m in mi)//调用每个方法
{
    //获得方法参数
    ParameterInfo[] pi = m.GetParameters();
    if (m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].ParameterType==typeof(int))
    {
        //     指定 System.String.Compare(System.String,System.String) 和 System.String.Equals(System.Object)
        //     方法的某些重载要使用的区域、大小写和排序规则。
        //StringComparison.Ordinal   使用序号排序规则比较字符串
        object[] obj = new object[2];
        obj[0] = 9;
        obj[1] = 18;
        m.Invoke(reflectOb, obj);
    }
    else if (m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].ParameterType==typeof(double))
    {
        object[] obj = new object[2];
        obj[0] = 1.12;
        obj[1] = 23.4;
        m.Invoke(reflectOb, obj);
    }
    else if (m.Name.Equals("Sum",StringComparison.Ordinal))
    {
        val = (int)m.Invoke(reflectOb, null);
        Console.WriteLine("Sum is : " + val);
    }
    else if (m.Name.Equals("IsBetween", StringComparison.Ordinal))
    {
        object[] obj = new object[1];
        obj[0] = 14;
        if ((bool)m.Invoke(reflectOb, obj))
        {
Console.WriteLine("14 is between x and y");
        }
    }
    else if (m.Name.Equals("Show",StringComparison.Ordinal))
    {
        m.Invoke(reflectOb,null);
    }
}

Main

(0)

相关推荐

  • C#反射实例学习及注意内容

    C#反射的入门学习首先要明白C#反射提供了封装程序集.模块和类型的对象等等.那么这样可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. MSDN描述: 反射通常具有以下用途: 使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例. 使用 Module 发现以下信息:包含模块的程序集以及模块中的类等.您还可以获取在模块上定义的所有全

  • C#中Property和Attribute的区别实例详解

    本文实例分析了C#中Property和Attribute的区别.分享给大家供大家参考.具体分析如下: 在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性.属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性. Attribute才是本文的主角,把它称为属性我觉得很恰当.属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述.而Attribute就是干这事的.它允许你将信息与你定义的C#类型相关联

  • C#基础学习系列之Attribute和反射详解

    前言 本文主要给大家介绍了关于C#基础之Attribute和反射的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Attribute(特性) Attribute是C#的一种语言特性,用于为各种实体(class,field,property)附加一些说明性信息, 并且可以在运行时环境中检索这些信息(通过反射). 所有的Attribute必须继承自Attribute类,按照约定,特性类的名称带有 Attribute 后缀.使用特性时可以包含或省略此后缀. Attribut

  • 关于C#基础知识回顾--反射(一)

    反射(reflection)是一种允许用户获得类型信息的C#特性.术语"反射"源自于它的工作方式:Type对象映射它所代表的底层对象.对Type对象进行查询可以获得(反射)与类型相关的信息.反射是一种功能强大的机制,它允许学习和使用只在运行时才能知道的类型功能. 这些是官方定义,其实说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!反射的核心是System.Type.System.Type包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型信息.一旦得到

  • C#泛型和反射实例解析

    C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了. 由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这也就造成了很多时候不像js那样方便使用,不够灵话. 因此就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型.如下例所示: public T abc<T>(T word) { return word; return default(T); //关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦 } ab

  • C#反射的一些应用

    对于反射贫道也是很陌生的,所以趁现在有时间就把反射看了一下,记下笔记!!!反射的定义:反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.  1,导入using System.Reflection;  2,Asse

  • C#中的程序集和反射介绍

    什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件). 4.在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括

  • C#属性(Attribute)用法实例解析

    属性(Attribute)是C#程序设计中非常重要的一个技术,应用范围广泛,用法灵活多变.本文就以实例形式分析了C#中属性的应用.具体入戏: 一.运用范围 程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute [AttributeUsage(AttributeTargets.All)] public class TestAttribute : Attribute { } [TestAttribute]//结构

  • c#反射调用方法示例

    获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表:该方法的两种形式: MethodInfo [] GetMethods() MethodInfo [] GetMethods(BindingFlags bindingflas)  :它的参数带有一些限制 BindingFlags  是一个枚举 枚举成员 [DeclaredOnly,Inst

  • Java使用反射调用方法示例

    本文实例讲述了Java使用反射调用方法.分享给大家供大家参考,具体如下: 一 代码 import java.util.*; import java.io.*; import java.lang.reflect.*; public class ExtendedObjectPoolFactory { // 定义一个对象池,前面是对象名,后面是实际对象 private Map<String, Object> objectPool = new HashMap<>(); private Pr

  • C#高效反射调用方法类实例详解

    C#高效反射调用方法类 1.创建一个业务类(HomeService),在类下创建3个方法 2.正常方式调用类的方法 3.反射方式调用类的方法 4.调用代码 5.调用结果 6.Service类方法代码 内容扩展: 1.正常方式调用类的方法 /// <summary> /// 正常调用类的方法(parm1) /// </summary> /// <returns></returns> public string GetNormalMethod_2() { Hom

  • java反射调用方法NoSuchMethodException的解决方案

    目录 java反射调用方法NoSuchMethodException NoSuchMethodException问题总结 1.编译异常,这个很容易发现并解决 2.编译正常,运行报错 java反射调用方法NoSuchMethodException 1.方法定义成 public类型. 2.getMethod传参要正确 比如调用定义的:public void   show(Object obj) 要这样调用   clazz.getMethod("show",Object.class);而不是

  • smarty中js的调用方法示例

    本文实例讲述了smarty中js的调用方法,分享给大家供大家参考.具体方法分析如下: 一.问题: 有时候,在smarty中,包含js的时候,整个页面就不会显示,而程序员往往在页面中找错误,程序页面,模板页面检查了多次都没有错误,就很郁闷了. 二.解决办法: 把模板页面中的js代码拷贝出来放在新建的js文件中,然后在包含到模板页面里面,如: 复制代码 代码如下: {popup_init src="css/commen.js"} 这样一来,问题就解决了. 希望本文所述对大家的PHP程序设计

  • C#接口在派生类和外部类中的调用方法示例

    本文实例讲述了C#接口在派生类和外部类中的调用方法.分享给大家供大家参考,具体如下: C#的接口通过interface关键字进行创建,在接口中可以包含属性,方法等成员变量.接口的派生类可以对接口中的方法进行实现.一个类可以继承多个接口对这些接口中的方法进行实现,一个接口也可以派生多个类接口中的方法可以由这些类中的一个或多个进行实现.在接口的派生类中可以直接调用接口中的方法. 在派生类中调用举例: //接口 public interface IPersonalService { //接口中的方法

  • Asp.Net Core使用SignalR进行服务间调用方法示例

    网上查询过很多关于ASP.NET core使用SignalR的简单例子,但是大部分都是简易聊天功能,今天心血来潮就搞了个使用SignalR进行服务间调用的简单DEMO. 至于SignalR是什么我就不多说了,微软官方文档也不少. 第一步新建项目 所有VS开发第一步都是新建一个解决方案哈,这里我就不多介绍如何新建项目啦~~ 开发环境,VS2017,.NET CORE 2.1 新建两个asp.net core项目 如此简单的操作大家都懂的 注入SignalR 在被调用的服务端的Startup.cs中

  • 在C++中反射调用.NET的方法(二)

    反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C++与.NET程序集之间传递复杂对象. 先看看.NET程序集的一个返回对象的方法: public IUserInfo GetUserByID(int userId) { IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>(); user

  • java通过反射创建对象并调用方法

    这篇文章主要介绍了java通过反射创建对象并调用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.用户类 package com.lf.entity; import com.lf.annotation.SetProperty; import com.lf.annotation.SetTable; public class UserEntity { private String userName; private int userAge;

  • vuex mutations的两种调用方法小结

    目录 mutations的调用方法 直接通过$store.commit调用 通过在methods中注册方法调用 细数mutations的用法 为什么要用mutations 用法 mutations的调用方法 直接通过$store.commit调用 <button @click="$store.commit('mutations中的方法名','可带参数')">调用</button> 不需要再进行其他配置 通过在methods中注册方法调用 //先引入mapMuta

随机推荐