.NET中反射的应用

来源:互联网 发布:获取网页源码 编辑:程序博客网 时间:2024/06/06 00:17
【摘要】
  反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象。
  下面通过二个例子来学习,第一个,动态地调用一个类,第二个,动态地调用类里面的方法、成员变量及属性。


【全文】

  反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象。
  下面通过二个例子来学习,第一个,动态地调用一个类,第二个,动态地调用类里面的方法、成员变量及属性。
  1、动态调用一个类
  在一些设计模式中,比如Abstract Factory和Factory Methord中,我们需要定义一组接口或者抽象类,然后由各个子类去实现这些接口或者抽象类,然后再根据需要进行加载,传统的解决方法是需要对客户端代码进行重构的,但采用.NET的反射功能,便可以大大地减小重构代码的工作量。
  代码如下:

using System;
using System.Reflection;

public abstract class SimplyAbstractClass
{
    public abstract void SayHello();
}

public class SimplyClass1 : SimplyAbstractClass
{
    public override void SayHello()
    {
        Console.WriteLine("Hello
www.webexpress.cn,This is from Simply1!");
    }
}

public class SimplyClass2 : SimplyAbstractClass
{
    public override void SayHello()
    {
        Console.WriteLine("Hello
www.webexpress.cn,This is from Simply2!");
    }
}

public class ClientManager
{
    public static void SayHello(SimplyAbstractClass instanceClass)
    {
        instanceClass.SayHello();
    }
}

public class Client
{
    public static void Main()
    {
        //便于演示,列出所有子类
        string[] Classes = new string[2];
        Classes[0] = "SimplyClass1";
        Classes[1] = "SimplyClass2";

        //根据程序集名称加载程序集
        Assembly assembly = Assembly.Load("ConsoleStudy");
        Type obj;

        //循环调用
        for (int i = 0; i < Classes.Length; i++)
        {
            obj = assembly.GetType(Classes[i]);
            SimplyAbstractClass classInstance = (SimplyAbstractClass)Activator.CreateInstance(obj);
            ClientManager.SayHello(classInstance);
        }

        Console.ReadLine();
    }
}


  2、动态调用类的方法、成员变量及属性
  动态调用类的方法、成员变量及属性,也是较常用的,通过.NET的反射,我们可以方法地对此进行操作,从而增强了程序的灵活性及可配置性。
  代码如下:

using System;
using System.Reflection;


public class AssemblyCall
{
    public AssemblyCall()
    {
    }

    //成员变量
    public string WebStation;

    //属性
    private string AuthorName = "Netlibertine";
    public string _AuthorName
    {
        get
        {
            return this.AuthorName;
        }
        set
        {
            this.AuthorName = (string)value;
        }
    }

    //有返回值方法(不带参数)
    public string GetAuthorName()
    {
        return this.AuthorName;
    }

    //有返回值方法(带参数)
    public string GetAuthorName(string strName)
    {
        return strName;
    }
}

public class Client
{
    public static void Main()
    {
        string strTemp;
        //获得Type信息
        Type type = typeof(AssemblyCall);
        //实例化对象类
        Object obj = type.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);

        #region 成员变量调用
        Console.WriteLine("--成员变量调用--");
        Console.WriteLine("成员变量赋值前值:");
        //调用
        strTemp = (string)type.InvokeMember("WebStation", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,null,obj,null);
        Console.WriteLine(strTemp);
        Console.WriteLine("请输入参数值:");
        strTemp = Console.ReadLine();
        //赋值
        type.InvokeMember("WebStation", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, obj, new object[] { strTemp});
        Console.WriteLine("成员变量赋值后值:");
        strTemp = (string)type.InvokeMember("WebStation", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, obj, null);
        Console.WriteLine(strTemp);
        Console.WriteLine();
        #endregion

        #region 方法(不带参数)
        Console.WriteLine("--方法(不带参数)--");
        Console.WriteLine("函数名称:GetAuthorName");
        Console.WriteLine("调用返回值:");
        //调用
        strTemp = (string)type.InvokeMember("GetAuthorName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, obj, null);
        Console.WriteLine(strTemp);
        Console.WriteLine();
        #endregion

        #region 方法(带参数)
        Console.WriteLine("--方法(带参数)--");
        Console.WriteLine("函数名称:GetAuthorName");
        Console.WriteLine("请输入参数值:");
        strTemp = Console.ReadLine();
        Console.WriteLine("调用返回值:");
        //调用
        strTemp = (string)type.InvokeMember("GetAuthorName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, obj, new object[] { strTemp });
        Console.WriteLine(strTemp);
        Console.WriteLine();
        #endregion

        #region 属性调用
        Console.WriteLine("--属性调用--");
        Console.WriteLine("属性赋值前值:");
        //调用
        strTemp = (string)type.InvokeMember("_AuthorName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null);
        Console.WriteLine(strTemp);
        Console.WriteLine("请输入属性值:");
        strTemp = Console.ReadLine();
        //赋值
        type.InvokeMember("_AuthorName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new object[] { strTemp });
        Console.WriteLine("属性赋值后值:");
        strTemp = (string)type.InvokeMember("_AuthorName", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null);
        Console.WriteLine(strTemp);
        Console.WriteLine();
        #endregion

        Console.ReadLine();
    }

原创粉丝点击