.NET中反射的应用
2012-12-01 11:08
381 查看
【摘要】
反射(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();
}
反射(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();
}
相关文章推荐
- .Net反射技术应用解决对象不同版本方法不同参数的问题
- .Net开发笔记(二十一) 反射在.net中的应用
- .NET 中关于反射的应用
- 反射在.NET中的简单应用(一)
- .Net中通过反射技术的应用----插件程序的开发入门
- .NET的反射在软件设计上的应用
- .Net中通过反射技术的应用----插件程序的开发入门
- .net反射技术的应用—如何调用Java的COM接口[转]
- .Net中通过反射技术的应用----插件程序的开发入门
- .Net开发笔记(二十一) 反射在.net中的应用
- .net中反射技术的应用
- .NET反射应用
- .net反射技术的应用—如何调用Java的COM接口
- 反射在.NET中的简单应用(二)
- 【转】.Net中通过反射技术的应用----插件程序的开发入门
- .NET 中关于反射的应用 (C#)
- .Net反射技术应用—与Java互操作
- 反射在Java Swing编程中的应用之java 模仿.net事件处理
- C#反射之基础应用
- 使用.NET从零开始打造短信应用系统之七