zoukankan      html  css  js  c++  java
  • C# 反射之调用方法谈

    反射的定义

    反射提供了描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。------摘自MSDN

     

    自我理解

    看到反射二字,自然而然的会想到,小时候拿着一面镜子,反射阳光玩。其实

    反射就好比一面镜子,通过它我们能在不显示引用程序集的情况下,一窥程序集内的“风景”。

     

    利用好反射这把利器,我们在开发中就能体会到荀老夫子所言的,君子性非异也,善假于物也

    本文主要包括以下四节:

    通过反射调用类的构造函数(有参/无参)

    通过反射调用类的静态方法(有参/无参)

    通过反射调用类的非静态方法(有参/无参)

    通过反射调用类的含有ref参数的方法

    代码示例:

     1 namespace TestDLL
     2 {
     3     using System.Linq;
     4 
     5     public class TestClass
     6     {
     7         private int _priValue;
     8 
     9         //无参构造函数
    10         public TestClass()
    11         {
    12             this._priValue = 9;
    13         }
    14 
    15         //有参构造函数
    16         public TestClass(int i)
    17         {
    18             this._priValue = i;
    19         }
    20 
    21         //无参方法
    22         public int Add()
    23         {
    24             return ++this._priValue;
    25         }
    26 
    27         //ref参数的方法
    28         public void Exchange(ref int a, ref int b)
    29         {
    30             int temp = b;
    31             b = a;
    32             a = temp;
    33         }
    34 
    35         // 静态有参方法 
    36         public static string SayHi(string name)
    37         {
    38             return "Hi~ " + name;
    39         }
    40 
    41         public static int AddValue(int[] objsInts)
    42         {
    43             int temp = 0;
    44             if (objsInts != null)
    45             {
    46                 temp += objsInts.Sum();
    47             }
    48             return temp;
    49         }
    50     }
    51 }
    View Code

    通过反射调用代码示例:

        static void Main(string[] args)
            {
                //加载程序集(dll文件地址),使用Assembly类 
                Assembly testDll = Assembly.LoadFile(Environment.CurrentDirectory + "\TestDLL.dll");
    
                //获取类型,参数(名称空间+类)
                Type testClass = testDll.GetType("TestDLL.TestClass");
    
                //创建实例
                var instance = testDll.CreateInstance("TestDLL.TestClass");
    
                //调用无参构造函数
                ConstructorInfo noParamConstructor = testClass.GetConstructor(Type.EmptyTypes);
                object testClassObject = noParamConstructor.Invoke(new object[] { });
    
                //调用有参构造函数
                ConstructorInfo paramConstructor = testClass.GetConstructor(new Type[] { Type.GetType("System.Int32") });
                object testClassObject2 = paramConstructor.Invoke(new object[] { 2 });
    
                #region 调用非静态方法
                MethodInfo addMethod = testClass.GetMethod("Add");
                object addValue = addMethod.Invoke(instance, new object[] { });
                #endregion
    
                #region 调用静态有参方法
                MethodInfo sayHiMethod = testClass.GetMethod("SayHi");
                object sayHi = sayHiMethod.Invoke(null, new object[] { "jason" });
                #endregion
    
                #region 调用含有ref参数的方法
                MethodInfo exchange = testClass.GetMethod("Exchange");
                var objs = new object[2];
                objs[0] = 5;
                objs[1] = 6;
                Console.WriteLine("objs[0]={0}
    objs[1]={1}", objs[0], objs[1]);
                object retValue = exchange.Invoke(instance, objs);
                #endregion
    
                #region 调用参数为数组的方法
                MethodInfo addValueInfo = testClass.GetMethod("AddValue");
                var ints = new int[] {1, 2, 3, 4, 5};
                object obj = addValueInfo.Invoke(null, new object[] {ints});
                #endregion
    
                Console.WriteLine("MethodInfo.Invoke() Example
    ");
                Console.WriteLine("TestClass.Add() returned: {0}", addValue);
                Console.WriteLine("TestClass.SayHi() returned:{0}", sayHi);
                Console.WriteLine("TestClass.Exchange(ref int a,ref int b) returned:{0}", retValue);
                Console.WriteLine("objs[0]={0}
    objs[1]={1}", objs[0], objs[1]);
    
                Console.WriteLine("AddValue(int[] objsInts) result:{0}", obj);
            }

     在此对代码中红色加粗的方法做注(摘自MSDN):

    MethodBase.Invoke 方法 (Object, Object[])

    使用指定的参数调用当前实例所表示的方法或构造函数。

    语法

    public Object Invoke(

    Object obj,

    Object[] parameters

    )

    参数

    obj

    类型:System.Object

    对其调用方法或构造函数的对象。 如果方法是静态的,则忽略此参数。 如果构造函数是静态的,则此参数必须为 null 或定义该构造函数的类的实例。

    若要使用其 MethodInfo 对象来调用静态方法,请将 null 传递给 obj。

    parameters

    类型:System.Object[]

    调用的方法或构造函数的参数列表。 这是一个对象数组,这些对象与要调用的方法或构造函数的参数具有相同的数量、顺序和类型。 如果没有任何参数,则 parameters 应为 null。

    如果此实例所表示的方法或构造函数采用 ref 参数(在 Visual Basic 中为 ByRef),使用此函数调用该方法或构造函数时,该参数不需要任何特殊属性。 如果此数组中的对象未用值来显式初始化,则该对象将包含该对象类型的默认值。 对于引用类型的元素,该值为 null。 对于值类型的元素,该值为 0、0.0 或 false,具体取决于特定的元素类型。

    返回值

    类型:System.Object

    一个对象,包含被调用方法的返回值,如果调用的是构造函数,则为 null。

  • 相关阅读:
    xshell常用命令
    linux传输文件命令: rz 和 sz
    使用openssh-clients的scp命令来传输文件
    RabbitMQ初学之二:直接发送消息到队列
    [App]华为P6设置与Xamarin Studio连通测试
    [Boost]图形处理库Boost::Polygon
    [App]Taste VS2015 && Android Studio
    [Linux&Vim]输入输出流
    [SSD大法好]神舟K480-I5-D3鸟枪换炮M6S
    [IoLanguage]Io Tutorial[转]
  • 原文地址:https://www.cnblogs.com/MrALei/p/4692275.html
Copyright © 2011-2022 走看看