应用框架的设计与实现学习手札之类工厂服务——反射

反射

—— 应用框架的设计与实现学习手札

文野:2006814星期一

概述

反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类型于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型,并且对这些新类型的操作进行调用。

 

一些在反射中经常使用的类

Assembly

Assembly类是可重用、无版本冲突并且可自我描述的公共语言运行库应用程序构造块。可以使用Assembly.LoadAssembly.LoadFrom方法动态地加载程序集。

 

Type

反射的中心是System.Type类。System.Type类是一个抽象类,代表公用类型系统中的一种类型。这个类使您能够查询类型名、类型中包含的模块和名称空间、以及该类型是一个数值类型还是一个引用类型。

System.Type类使您能够查询几乎所有与类型相关的属性,包括类型访问限定符、类型是否、类型的COM属性等等。

 

Activator

Activator类支持动态创建.NET程序集和COM对象。可以通过CreateComInstanceFromCreateInstanceCreateInstanceFromGetObject四个静态方法加载COM对象或者程序集,并能创建指定类型的实例。

 

Binder

Binder类是一个用于执行类型转换的绑定器,Type对象的InvokeMember方法接受Binder对象,这个对象描述了如何将传递给InvokeMember的参数转换成方法实际需要的类型。

Binder类是一个抽象类,要创建绑定器,需要重写方法BindToMethodBindToFieldSelectMehtodSelectPropertyChangeType

 

DefaultMemberAttribute

    DefaultMemberAttribute类用于类型并带有一个指明默认成员名称的字符串参数。能够通过InvokeMember调用默认成员,而不需要传递调用成员的名称。当需要绑定器但不需要特别的绑定行为时就可以使用它。

 

其它

还有一些对元素类型信息描述的类,ConstrutorInfo(构造函数)、MethodInfo(方法)、FieldInfo(字段)、PropertyInfo(属性)、EventInfo(事件)、MemberInfo(成员)、ParameterInfo(参数)。如果查询得到了具有任何类型信息的实例,就可以获得该类型中任意元素的类型信息,当然出于安全原因,不保证会得到程序集中的任何信息。

 

示例

类定义:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
None.gif
namespace  ReflectionSample
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 说明:一个简单的类
InBlock.gif    
/// 作者:文野
InBlock.gif    
/// 联系:stwyhm.cnblog.com
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class ClassSample
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// 默认构造
InBlock.gif
        public ClassSample()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.name = "您调用了默认构造创建了一个类实例。";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// 带参构造
InBlock.gif
        public ClassSample(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.name = name;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// 字段 
InBlock.gif
        public string name;
InBlock.gif
InBlock.gif        
public string Field;
InBlock.gif
InBlock.gif        
// 属性
InBlock.gif
        private string property;
InBlock.gif        
public string Property
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifthis.property = value; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn property; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// public方法 
InBlock.gif
        public string PublicClassMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return string.Format("您反射了一个Public方法");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// private方法
InBlock.gif
        private string PrivateClassMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return string.Format("您反射了一个Private方法");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// static方法
InBlock.gif
        public static string StaticMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "您反射了一个Static方法";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// 帶參方法
InBlock.gif
        public string ParameterMethod(string para)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return para;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public event EventHandler eventHandler;
InBlock.gif
InBlock.gif        
public void DoEvent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            eventHandler(
null,EventArgs.Empty);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

反射示例

None.gif using  System;
None.gif
using  System.Data;
None.gif
using  System.Configuration;
None.gif
using  System.Web;
None.gif
using  System.Web.Security;
None.gif
using  System.Web.UI;
None.gif
using  System.Web.UI.WebControls;
None.gif
using  System.Web.UI.WebControls.WebParts;
None.gif
using  System.Web.UI.HtmlControls;
None.gif
None.gif
using  System.Reflection;
None.gif
using  ReflectionSample;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /// <summary>
InBlock.gif
/// 说明:一个简单的使用反射示例
InBlock.gif
/// 作者:文野
InBlock.gif
/// 联系:stwyhm.cnblog.com
ExpandedBlockEnd.gif
/// </summary>

None.gif public  partial  class  _Default : System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string path = Server.MapPath(Request.Path);
InBlock.gif        
string filePath = path.Substring(0, path.LastIndexOf('\\')) + @"\bin\ReflectionSample.dll";
InBlock.gif        
// 获取程序集
InBlock.gif
        Assembly classSampleAssembly = Assembly.LoadFrom(filePath);
InBlock.gif
InBlock.gif        
// 从程序集中获取指定对象类型
InBlock.gif
        Type classSampleType = classSampleAssembly.GetType("ReflectionSample.ClassSample");
InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
使用Activator创建一个实例#region 使用Activator创建一个实例
InBlock.gif
InBlock.gif        
// 通过对象类型创建对象实例
InBlock.gif
        ClassSample s1 = Activator.CreateInstance(classSampleType) as ClassSample;
InBlock.gif
InBlock.gif        Response.Write(s1.name 
+ "(使用Activator创建一个实例)<br />");
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
动态调用构造函数#region 动态调用构造函数
InBlock.gif
InBlock.gif        
// 调用无参构造
ExpandedSubBlockStart.gifContractedSubBlock.gif
        ConstructorInfo studentConstructor1 = classSampleType.GetConstructor(new Type[] dot.gif{ });
ExpandedSubBlockStart.gifContractedSubBlock.gif        ClassSample s2 
= studentConstructor1.Invoke(new object[] dot.gif{ }as ClassSample;
InBlock.gif        Response.Write(s2.name 
+ "<br />");
InBlock.gif
InBlock.gif        
// 调用有参构造
ExpandedSubBlockStart.gifContractedSubBlock.gif
        ConstructorInfo studentConstructor2 = classSampleType.GetConstructor(new Type[] dot.giftypeof(string) });
ExpandedSubBlockStart.gifContractedSubBlock.gif        ClassSample s3 
= studentConstructor2.Invoke(new object[] dot.gif"您调用了有参构造创建了一个类实例。" }as ClassSample;
InBlock.gif        Response.Write(s3.name 
+ "<br />");
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
反射方法#region 反射方法
InBlock.gif
InBlock.gif        
// 调用非静态方法
ExpandedSubBlockStart.gifContractedSubBlock.gif
        string returnValue1 = classSampleType.InvokeMember("PublicClassMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] dot.gif{ }as string;
InBlock.gif        Response.Write(returnValue1 
+ "<br />");
InBlock.gif
InBlock.gif        
// 调用静态方法
ExpandedSubBlockStart.gifContractedSubBlock.gif
        string returnValue2 = classSampleType.InvokeMember("StaticMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, s1, new object[] dot.gif{ }as string;
InBlock.gif        Response.Write(returnValue2 
+ "<br />");
InBlock.gif
InBlock.gif        
// 调用私有方法
ExpandedSubBlockStart.gifContractedSubBlock.gif
        string returnValue3 = classSampleType.InvokeMember("PrivateClassMethod", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, s1, new object[] dot.gif{ }as string;
InBlock.gif        Response.Write(returnValue3 
+ "<br />");
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
反射参数#region 反射参数
InBlock.gif
InBlock.gif        MethodInfo parameterMethod 
= classSampleType.GetMethod("ParameterMethod");
InBlock.gif        ParameterInfo[] paras 
= parameterMethod.GetParameters();
InBlock.gif        
for (int i = 0; i < paras.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            Response.Write(
string.Format("您反射了一个带参方法。参数名:{0},参数类型:{1},是不是可选参数:{2},参数位置:{3},默认值:{4}<br/>"new object[] dot.gif{ paras[i].Name, paras[i].ParameterType.ToString(), paras[i].IsOptional.ToString(), paras[i].Position.ToString(), paras[i].DefaultValue.ToString() }));
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
反射属性#region 反射属性
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        classSampleType.InvokeMember(
"Property", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] dot.gif"您反射了一个属性" });
ExpandedSubBlockStart.gifContractedSubBlock.gif        
string returnValue4 = classSampleType.InvokeMember("Property", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] dot.gif{ }as string;
InBlock.gif        Response.Write(returnValue4 
+ "<br />");
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
反射字段#region 反射字段
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        classSampleType.InvokeMember(
"Field", BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] dot.gif"您反射了一个字段" });
ExpandedSubBlockStart.gifContractedSubBlock.gif        
string returnValue5 = classSampleType.InvokeMember("Field", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] dot.gif{ }as string;
InBlock.gif        Response.Write(returnValue5 
+ "<br />");
InBlock.gif
ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


 

总结:

我们看到,简单的反射使用还是挺简单的,一般只要指定搜索的名称与搜索的类型就可以了。而且我觉得现实中使用反射大部分是都是通过动态创建一个接口的实现类的实例,然后调用接口中定义的方法,还是很少象上面那样通过Type调用类内的各个成员。

 

参考资料:

《Visual Basic .NET Power Coding》 

本文源码:

下载

转载于:https://www.cnblogs.com/stwyhm/archive/2006/08/14/476039.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值