反射的定義:審查元數據並收集關於它的類型信息的能力,元數據(編輯后的基本數據單元)就是一大堆表,編譯器會創建一個類定義表,一個字段定義表,一個方法定義表等,System.Reflection命名空間包含的幾個類,允許你反射(解析)這些元數據的代碼
一、反射的作用:
動態的創建類型的實例,將類型邦定到現有對象,或從現有對象中獲取類型
應用程序需要在運行時從某個特定的程序集中載入一個特定的類型,以便實現某個任務時可以用到反射
反射主要應用於類庫,這些類庫需要知道一個類型的定義,以便提供更多的功能
二、應用要點:
現實應用程序中很少使用到反射
使用反射動態邦定需要犧牲性能
有些元數據信息是不能通過反射獲取的
某些反射類型是專門為那些CLR開發編輯器開發使用的,所以你要意思到不是所有反射類型都是可以使用的
三、取得Assembly的方法:
Assembly.Load
Assembly.LoadFile
Assembly.LoadFrom
Type對象的Assembly方法
四、反射的成員:
MemberInfo-成員
ConstructorInfo-結構
FieldInfo-字段
MethodInfo-方法
PropertyInfo-屬性
EventInfo-事件
五、根據反射取得對象的Member信息
private void WriteReflectionInfo()
{
Type testType = typeof(Test);
Assembly assembly = testType.Assembly;
Response.Write( " Assembly: " + assembly.FullName + " <br/> ");
Type[] typeList = assembly.GetTypes(); // 獲取類型
// 針對每個類型獲取詳細信息
foreach (Type type in typeList)
{
Response.Write( " ------------------------ " + type.Namespace + type.Name + " ------------------------<br/> ");
// 獲得類型的結構信息
ConstructorInfo[] constructs = type.GetConstructors();
// 獲得類型的字段信息
FieldInfo[] fields = type.GetFields();
Response.Write( " <b>類的公共字段信息如下:</b> " + " <br/> ");
int a1 = 1;
foreach (FieldInfo field in fields)
{
Response.Write((a1++).ToString() + " . " + field.Name + " <br/> ");
}
// 獲得方法信息
MethodInfo[] methods = type.GetMethods();
Response.Write( " <b>類的公共方法如下:</b> " + " <br/> ");
int a2 = 1;
foreach (MethodInfo method in methods)
{
ParameterInfo[] parameters = method.GetParameters();
ParameterInfo reparam = method.ReturnParameter;
Response.Write((a2++).ToString() + " . " + reparam.ParameterType.Name + " " + method.Name + " ( ");
int index = 0;
foreach (ParameterInfo para in parameters)
{
if (index++ < parameters.Length - 1)
Response.Write(para.ParameterType.Name + " " + para.Name + " , ");
else
Response.Write(para.ParameterType.Name + " " + para.Name);
}
Response.Write( " )<br/> ");
}
// 獲得屬性的信息
PropertyInfo[] propertys = type.GetProperties();
Response.Write( " <b>類的公共屬性如下:</b> " + " <br/> ");
int a3 = 1;
foreach (PropertyInfo pro in propertys)
{
Response.Write((a3++).ToString() + " . " + pro.PropertyType.Name + " " + pro.Name + " { ");
if (pro.CanRead) Response.Write( " get; ");
if (pro.CanWrite) Response.Write( " set; ");
Response.Write( " }<br/> ");
}
// 獲得事件信息
EventInfo[] events = type.GetEvents();
Response.Write( " <b>類的成員如下:</b> " + " <br/> ");
// 獲得成員
int a4 = 1;
foreach (MemberInfo mi in type.GetMembers())
{
Response.Write((a4++).ToString() + " . " + mi.MemberType.ToString() + " : " + mi.Name + " <br/> ");
}
}
六、動態創建對象
Assembly對象的 CreateInstance方法
Activator. CreateInstance方法
Type對象的 InvokeMember方法
// 使用Assembly的CreateInstance方法來取得對象的實例
private void Assembly_CreateInstance()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
// 創建無參數實例
IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className);
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null);
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
// 使用Activator的CreateInstance方法來取得對象的實例
private void Activator_CreateInstance()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
// 創建無參數實例
System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className);
IDAL.IMember member = (IDAL.IMember)obj.Unwrap();
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null);
IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap();
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
// 使用Type的InvokeMember方法來取得對象的實例
private void Type_InvokeMember()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
Assembly assem = Assembly.Load(assemblyName);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 創建無參數實例
IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null);
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters);
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
七、動態調用對象方法
Type對象的 InvokeMember方法
MethodInfo對象的Invoke方法
// Type對象的 InvokeMember方法來動態調用方法
private void InvokeMember()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 動態調用無參數的方法
methodName = " GetName ";
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用有參數的方法
methodName = " Update ";
Object[] methodParams = new Object[ 1];
methodParams[ 0] = DateTime.Now;
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用參數構架函數的帶有參數的方法
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
obj = assem.CreateInstance(className, false,BindingFlags.CreateInstance, null, parameters, null, null);
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
}
// MethodInfo對象的Invoke方法來動態調用方法
private void MethodInfo_Invoke()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 動態調用無參數的方法
methodName = " GetName ";
MethodInfo methodInfo = type.GetMethod(methodName);
result = ( string)methodInfo.Invoke(obj, null);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用有參數的方法
methodName = " Update ";
Object[] methodParams = new Object[ 1];
methodParams[ 0] = DateTime.Now;
MethodInfo method = type.GetMethod(methodName);
result = ( string)method.Invoke(obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
}
--------------------------------------------------------------------------------
以上所使用的SqlModel.Member為:
新建一個SqlModel類庫,在其下建立一個Member的類
namespace SqlModel
{
public class Member : IDAL.IMember
{
private int _id = 100;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _name = " limin ";
public string Name
{
get { return _name; }
set { _name = value; }
}
public Member() { }
public Member( int id)
{
_id = id;
}
private void Init()
{ }
public string GetName()
{
return _name;
}
public string Update (DateTime cdate)
{
return " { " + String.Format( " ID:{0},Name:{1},CreateDate:{2} ",_id,_name,cdate) + " } ";
}
}
}
一、反射的作用:
動態的創建類型的實例,將類型邦定到現有對象,或從現有對象中獲取類型
應用程序需要在運行時從某個特定的程序集中載入一個特定的類型,以便實現某個任務時可以用到反射
反射主要應用於類庫,這些類庫需要知道一個類型的定義,以便提供更多的功能
二、應用要點:
現實應用程序中很少使用到反射
使用反射動態邦定需要犧牲性能
有些元數據信息是不能通過反射獲取的
某些反射類型是專門為那些CLR開發編輯器開發使用的,所以你要意思到不是所有反射類型都是可以使用的
三、取得Assembly的方法:
Assembly.Load
Assembly.LoadFile
Assembly.LoadFrom
Type對象的Assembly方法
四、反射的成員:
MemberInfo-成員
ConstructorInfo-結構
FieldInfo-字段
MethodInfo-方法
PropertyInfo-屬性
EventInfo-事件
五、根據反射取得對象的Member信息
private void WriteReflectionInfo()
{
Type testType = typeof(Test);
Assembly assembly = testType.Assembly;
Response.Write( " Assembly: " + assembly.FullName + " <br/> ");
Type[] typeList = assembly.GetTypes(); // 獲取類型
// 針對每個類型獲取詳細信息
foreach (Type type in typeList)
{
Response.Write( " ------------------------ " + type.Namespace + type.Name + " ------------------------<br/> ");
// 獲得類型的結構信息
ConstructorInfo[] constructs = type.GetConstructors();
// 獲得類型的字段信息
FieldInfo[] fields = type.GetFields();
Response.Write( " <b>類的公共字段信息如下:</b> " + " <br/> ");
int a1 = 1;
foreach (FieldInfo field in fields)
{
Response.Write((a1++).ToString() + " . " + field.Name + " <br/> ");
}
// 獲得方法信息
MethodInfo[] methods = type.GetMethods();
Response.Write( " <b>類的公共方法如下:</b> " + " <br/> ");
int a2 = 1;
foreach (MethodInfo method in methods)
{
ParameterInfo[] parameters = method.GetParameters();
ParameterInfo reparam = method.ReturnParameter;
Response.Write((a2++).ToString() + " . " + reparam.ParameterType.Name + " " + method.Name + " ( ");
int index = 0;
foreach (ParameterInfo para in parameters)
{
if (index++ < parameters.Length - 1)
Response.Write(para.ParameterType.Name + " " + para.Name + " , ");
else
Response.Write(para.ParameterType.Name + " " + para.Name);
}
Response.Write( " )<br/> ");
}
// 獲得屬性的信息
PropertyInfo[] propertys = type.GetProperties();
Response.Write( " <b>類的公共屬性如下:</b> " + " <br/> ");
int a3 = 1;
foreach (PropertyInfo pro in propertys)
{
Response.Write((a3++).ToString() + " . " + pro.PropertyType.Name + " " + pro.Name + " { ");
if (pro.CanRead) Response.Write( " get; ");
if (pro.CanWrite) Response.Write( " set; ");
Response.Write( " }<br/> ");
}
// 獲得事件信息
EventInfo[] events = type.GetEvents();
Response.Write( " <b>類的成員如下:</b> " + " <br/> ");
// 獲得成員
int a4 = 1;
foreach (MemberInfo mi in type.GetMembers())
{
Response.Write((a4++).ToString() + " . " + mi.MemberType.ToString() + " : " + mi.Name + " <br/> ");
}
}
六、動態創建對象
Assembly對象的 CreateInstance方法
Activator. CreateInstance方法
Type對象的 InvokeMember方法
// 使用Assembly的CreateInstance方法來取得對象的實例
private void Assembly_CreateInstance()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
// 創建無參數實例
IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className);
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null);
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
// 使用Activator的CreateInstance方法來取得對象的實例
private void Activator_CreateInstance()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
// 創建無參數實例
System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className);
IDAL.IMember member = (IDAL.IMember)obj.Unwrap();
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null);
IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap();
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
// 使用Type的InvokeMember方法來取得對象的實例
private void Type_InvokeMember()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
Assembly assem = Assembly.Load(assemblyName);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 創建無參數實例
IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null);
Response.Write( " 創建無參數實例: " + member.ID + " <br/> ");
// 創建有參數實例
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters);
Response.Write( " 創建有參數實例: " + member1.ID + " <br/> ");
}
七、動態調用對象方法
Type對象的 InvokeMember方法
MethodInfo對象的Invoke方法
// Type對象的 InvokeMember方法來動態調用方法
private void InvokeMember()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 動態調用無參數的方法
methodName = " GetName ";
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用有參數的方法
methodName = " Update ";
Object[] methodParams = new Object[ 1];
methodParams[ 0] = DateTime.Now;
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用參數構架函數的帶有參數的方法
Object[] parameters = new Object[ 1];
parameters[ 0] = 10000;
obj = assem.CreateInstance(className, false,BindingFlags.CreateInstance, null, parameters, null, null);
result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
}
// MethodInfo對象的Invoke方法來動態調用方法
private void MethodInfo_Invoke()
{
string assemblyName = " SqlModel ";
string className = assemblyName + " .Member ";
string methodName = String.Empty;
string result = String.Empty;
Assembly assem = Assembly.Load(assemblyName);
Object obj = assem.CreateInstance(className);
Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的
// 動態調用無參數的方法
methodName = " GetName ";
MethodInfo methodInfo = type.GetMethod(methodName);
result = ( string)methodInfo.Invoke(obj, null);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
// 動態調用有參數的方法
methodName = " Update ";
Object[] methodParams = new Object[ 1];
methodParams[ 0] = DateTime.Now;
MethodInfo method = type.GetMethod(methodName);
result = ( string)method.Invoke(obj, methodParams);
Response.Write(methodName + " 方法的返回值: " + result + " <br/> ");
}
--------------------------------------------------------------------------------
以上所使用的SqlModel.Member為:
新建一個SqlModel類庫,在其下建立一個Member的類
namespace SqlModel
{
public class Member : IDAL.IMember
{
private int _id = 100;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _name = " limin ";
public string Name
{
get { return _name; }
set { _name = value; }
}
public Member() { }
public Member( int id)
{
_id = id;
}
private void Init()
{ }
public string GetName()
{
return _name;
}
public string Update (DateTime cdate)
{
return " { " + String.Format( " ID:{0},Name:{1},CreateDate:{2} ",_id,_name,cdate) + " } ";
}
}
}