zoukankan      html  css  js  c++  java
  • C# 反射

    反射是一种能够在运行时动态创建对象、调用对象属性、成员、方法、属性等的特性。通俗的讲,通过反射不需要添加引用DLL,就可以动态的给类的属性赋值,动态的调用里面的方法。我们在VS中给控件的属性赋值就是通过反射来完成的,此外在调用web服务时也可以通过反射去动态的创建代理对象,而不需要添加web引用,还有在开发插件化(多个DLL)的应用程序时,反射是一种很重要的机制。

    因此,反射提供了一种更加灵活的方式,让我们根据需要进行动态的编程。这里举几个简单的例子以供参考:

    1、动态调用系统自带的类的静态方法

     MethodInfo methodInfo = typeof(string).GetMethod("Concat", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new Type[] { typeof(string), typeof(string) }, null);
     object result = methodInfo.Invoke(null, new string[] { "Hello ", "Reflection" });
     Console.WriteLine(result.ToString());

    2、动态调用系统自带的类的实例方法

    string str = "Hello World";
    object result = typeof(string).InvokeMember("Contains", BindingFlags.InvokeMethod, null, str, new object[] { "World" });
    Console.WriteLine(result.ToString());

    3、动态调用类库项目中的静态方法

    namespace 类库项目
    {
        public class Calculator
        {
            public static double Add(double a, double b)
            {
                return a + b;
            }
    
            public static double Sub(double a, double b)
            {
                return a - b;
            }
    
            public static double Mutiply(double a, double b)
            {
                return a * b;
            }
    
            public static double Divide(double a, double b)
            {
                return a / b;
            }
        }
    }

    反射调用:

    object obj = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "类库项目.dll").CreateInstance("类库项目.Calculator");
    
    object addResult = obj.GetType().InvokeMember("Add", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, obj, new object[] { 1, 2 });
    object subResult = obj.GetType().InvokeMember("Sub", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, obj, new object[] { 1, 2 });
    object mutiplyResult = obj.GetType().InvokeMember("Mutiply", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, obj, new object[] { 1, 2 });
    object divideResult = obj.GetType().InvokeMember("Divide", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, obj, new object[] { 1, 2 });
    
    Console.WriteLine("add:{0}	 sub:{1}	 mutiply:{2}	 divide:{3}",
            addResult.ToString(),
            subResult.ToString(),
            mutiplyResult.ToString(),
            divideResult.ToString());

    4、动态调用类库项目中的实例方法

    namespace 类库项目
    {
        public class Test
        {
            private int x;
            private string y;
    
            /// <summary>
            /// 属性X
            /// </summary>
            public int X { get { return x; } set { x = value; } }
    
            /// <summary>
            /// 属性Y
            /// </summary>
            public string Y { get { return y; } set { y = value; } }
    
            /// <summary>
            /// 默认无参构造函数
            /// </summary>
            public Test()
            {
    
            }
    
            /// <summary>
            /// 带两个参数的构造函数
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            public Test(int x, string y)
            {
                this.X = x;
                this.Y = y;
            }
    
            /// <summary>
            /// 方法的重载1(无参)
            /// </summary>
            /// <returns></returns>
            public string Show()
            {
                return string.Format("这是Test里的Show方法,参数x为{0},y为{1}", X, Y);
            }
    
            /// <summary>
            /// 方法的重载2(带两个参数)
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public string Show(int x, string y)
            {
                return string.Format("这是Test里的Show方法,参数x为{0},y为{1}", x, y);
            }
    
            /// <summary>
            /// 重写ToString方法
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                return string.Format("x的值为{0},y的值为{1}", x, y);
            }
        }
    }

    反射调用:

    object obj2 = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "类库项目.dll").CreateInstance("类库项目.Test");
    
    //获取构造函数
    ConstructorInfo constructorInfo = obj2.GetType().GetConstructor(new Type[] { typeof(int), typeof(string) });
    //通过构造函数创建类的实例
    object constructor = constructorInfo.Invoke(new object[] { 1, "guwei4037" });
    
    //调用实例的ToString方法
    Console.WriteLine(constructor.ToString());
    
    //获取带两个参数的Show方法对象
    MethodInfo methodInfo1 = obj2.GetType().GetMethod("Show", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(int), typeof(string) }, null);
    
    //返回带两个参数的Show方法的返回值
    Console.WriteLine(methodInfo1.Invoke(constructor, new object[] { 1, "guwei4037" }).ToString());
    
    //获取无参的Show方法
    MethodInfo methodInfo2 = obj2.GetType().GetMethod("Show", BindingFlags.Public | BindingFlags.Instance, null, System.Type.EmptyTypes, null);
    
    //动态设置属性的值
    PropertyInfo[] propertyInfos = obj2.GetType().GetProperties();
    foreach (PropertyInfo propertyInfo in propertyInfos)
    {
        if (propertyInfo.Name.Equals("X"))
            propertyInfo.SetValue(constructor, 2, null);
    
        if (propertyInfo.Name.Equals("Y"))
            propertyInfo.SetValue(constructor, "guwei4037_new", null);
    }
    
    //返回无参的Show方法的返回值
    Console.WriteLine(methodInfo2.Invoke(constructor, null).ToString());
  • 相关阅读:
    POJ 3630 Phone List/POJ 1056 【字典树】
    HDU 1074 Doing Homework【状态压缩DP】
    POJ 1077 Eight【八数码问题】
    状态压缩 POJ 1185 炮兵阵地【状态压缩DP】
    POJ 1806 Manhattan 2025
    POJ 3667 Hotel【经典的线段树】
    状态压缩 POJ 3254 Corn Fields【dp 状态压缩】
    ZOJ 3468 Dice War【PD求概率】
    POJ 2479 Maximum sum【求两个不重叠的连续子串的最大和】
    POJ 3735 Training little cats【矩阵的快速求幂】
  • 原文地址:https://www.cnblogs.com/guwei4037/p/8005036.html
Copyright © 2011-2022 走看看