久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

.Net反射機制分析和使用

 weijianian 2016-08-07


1..NET反射的概述


.NET反射是審查元數(shù)據(jù)并動態(tài)收集關(guān)于它的類型信息的能力。
應(yīng)用程序結(jié)構(gòu)分為應(yīng)用程序域—程序集—模塊—類型—成員幾個層次,公共語言運行庫加載器管理應(yīng)用程序域。這些域在擁有相同應(yīng)用程序范圍的對象周圍形成了確定邊界。
這種管理包括將每個程序集加載到相應(yīng)的應(yīng)用程序域以及控制每個程序集中類型層次結(jié)構(gòu)的內(nèi)存布局,。程序集包含模塊,而模塊包含類型,類型又包含成員,,反射則提供了封裝程序集、模塊和類型的對象,。
我們可以使用反射動態(tài)地創(chuàng)建類型的實例,,將類型綁定到現(xiàn)有對象或從現(xiàn)有對象中獲取類型,然后調(diào)用類型的方法或訪問其字段和屬性,。


反射的層次模型:


2..NET反射的作用和應(yīng)用


(1).可以使用反射動態(tài)地創(chuàng)建類型的實例,,將類型綁定到現(xiàn)有對象,或從現(xiàn)有對象中獲取類型,;
(2).應(yīng)用程序需要在運行時從某個特定的程序集中載入一個特定的類型,,以便實現(xiàn)某個任務(wù)時可以用到反射;
(3).反射主要應(yīng)用與類庫,,這些類庫需要知道一個類型的定義,,以便提供更多的功能;
(4).在.NET中實現(xiàn)工廠模式會使用反射較多,;
(5).在JavaScript等語言編譯器使用反射來構(gòu)造符號表;
(6).反射也可用于創(chuàng)建稱為類型瀏覽器的應(yīng)用程序,,使用戶能夠選擇類型,然后查看有關(guān)選定類型的信息;
(7).System.Runtime.Serialization命名空間中的類使用反射來訪問數(shù)據(jù)并確定要永久保存的字段,;
(8).System.Runtime.Remoting命名空間中的類通過序列化來間接地使用反射,。


3..NET反射的性能


使用反射來調(diào)用類型或者觸發(fā)方法,或者訪問一個字段或者屬性時clr 需 要做更多的工作:校驗參數(shù),,檢查權(quán)限等等,,所以速度是非常慢的。 所以盡量不要使用反射進(jìn)行編程,對于打算編寫一個動態(tài)構(gòu)造類型(晚綁定)的應(yīng)用程序,,可以采取以下的幾種方式進(jìn)行代替:


(1).通過類的繼承關(guān)系
讓該類型從一個編譯時可知的基礎(chǔ)類型派生出來,,在運行時生成該類 型的一個實例,將對其的引用放到其基礎(chǔ)類型的一個變量中,,然后調(diào)用該基礎(chǔ)類型的虛方法,。


(2).通過接口實現(xiàn)
在運行時,構(gòu)建該類型的一個實例,,將對其的引用放到其接口類型的一個變量中,,然后調(diào)用該接口定義的虛方法。


(3).通過委托實現(xiàn)
讓該類型實現(xiàn)一個方法,,其名稱和原型都與一個在編譯時就已知的委托相符,。 在運行時先構(gòu)造該類型的實例,然后在用該方法的對象及名稱構(gòu)造出該委托的實例,,接著通過委托調(diào)用你想要的方法,。這個方法相對與前面兩個方法所作的工作要多一些,效率更低一些,。
提高反射的性能:反射的性能損失主要來源于比較類型,、遍歷成員、調(diào)用成員三種情形,,其中比較類型耗時最小。 調(diào)用成員耗時最多,,所以盡量減少采用成員動態(tài)調(diào)用等反射方式可以提高應(yīng)用程序性能,。除此之外,采取后期綁定,、避免將反射方法放到循環(huán)內(nèi)產(chǎn)生放大效應(yīng)等辦法均可提升反射性能,。

4..NET反射常用類型


System.reflection命名空間下常用類型,允許你反射(解析)這些元數(shù)據(jù)表的代碼和反射相關(guān)的命名空間(可以通過這幾個命名空間訪問反射信息):


(1).System.Reflection.Assembly
使用Assembly定義和加載程序集,,加載在程序集清單中列出模塊,,以及從此程序集中查找類型并創(chuàng)建該類型的實例??梢允褂肁ssembly.Load和Assembly.LoadFrom方法動態(tài)地加載程序集,。


(2).System.Reflection.Module
使用Module了解包含模塊的程序集以及模塊中的類等,還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法,。


(3).System.Reflection.ConstructorInfo
使用ConstructorInfo了解構(gòu)造函數(shù)的名稱,、參數(shù)、訪問修飾符(如pulic 或private)和實現(xiàn)詳細(xì)信息(如abstract或virtual)等,。使用Type的GetConstructors或GetConstructor方法來調(diào)用特定的構(gòu)造函數(shù),。


(4).System.Reflection.MethodInfo
使用MethodInfo了解方法的名稱、返回類型、參數(shù),、訪問修飾符(如pulic 或private)和實現(xiàn)詳細(xì)信息(如abstract或virtual)等,。使用Type的GetMethods或GetMethod方法來調(diào)用特定的方法。


(5).System.Reflection.FieldInfo
使用FieldInfo了解字段的名稱,、訪問修飾符(如public或private)和實現(xiàn)詳細(xì)信息(如static)等,,并獲取或設(shè)置字段值。


(6).System.Reflection.EventInfo
使用EventInfo了解事件的名稱,、事件處理程序數(shù)據(jù)類型,、自定義屬性、聲明類型和反射類型等,,添加或移除事件處理程序,。


(7).System.Reflection.PropertyInfo
使用PropertyInfo了解屬性的名稱、數(shù)據(jù)類型,、聲明類型,、反射類型和只讀或可寫狀態(tài)等,獲取或設(shè)置屬性值,。


(8).System.Reflection.ParameterInfo
使用ParameterInfo了解參數(shù)的名稱,、數(shù)據(jù)類型、是輸入?yún)?shù)還是輸出參數(shù),,以及參數(shù)在方法簽名中的位置等,。
System.Reflection.Emit命名空間的類提供了一種特殊形式的反射,可以在運行時構(gòu)造類型,。


(9).System.Type
System.Type類是一個抽象類,,代表公用類型系統(tǒng)中的一種類型。這個類使您能夠查詢類型名,、類型中包含的模塊和名稱空間,、以及該類型是一個數(shù)值類型還是一個引用類型。 System.Type類使您能夠查詢幾乎所有與類型相關(guān)的屬性,,包括類型訪問限定符,、類型是否、類型的COM屬性等等,。


(10).System.Activator
Activator類支持動態(tài)創(chuàng)建.NET程序集和COM對象,。可以通過CreateComInstanceFrom,、CreateInstance,、CreateInstanceFrom、GetObject四個靜態(tài)方法加載COM對象或者程序集,,并能創(chuàng)建指定類型的實例,。

使用注意:
(1).Load方法:極力推薦的一種方法,,Load 方法帶有一個程序集標(biāo)志并載入它,Load 將引起CLR把策略應(yīng)用到程序集上,。 先后在全局程序集緩沖區(qū),,應(yīng)用程序基目錄和私有路徑下面查找該程序集,,如果找不到該程序集系統(tǒng)拋出異常,。


(2).LoadFrom方法:傳遞一個程序集文件的路徑名(包括擴(kuò)展名),CLR會載入您指定的這個程序集,,傳遞的這個參數(shù)不能包含任何關(guān)于版本號的信息,,區(qū)域性,和公鑰信息,,如果在指定路徑找不到程序集拋出異常,。


(3).LoadWithPartialName:永遠(yuǎn)不要使用這個方法,因為應(yīng)用程序不能確定再在載入的程序集的版本,。該方法的唯一用途是幫助那些在.Net框架的測試環(huán)節(jié)使用.net 框架提供的某種行為的客戶,,這個方法將最終被拋棄不用。

5..NET反射示例Demo


(1).代碼結(jié)構(gòu)


(2).TestClassLib類庫的Arithmetic類


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestClassLib
{
///


/// 定義示例接口Iwel
///

public interface Iwel
{
string Print();
}

///
/// 構(gòu)造測試數(shù)據(jù)類
///

public class Arithmetic:Iwel
{
//定義私有變量
private int numOne;
private int numTwo;

#region 構(gòu)造函數(shù)測試
//不帶參數(shù)的構(gòu)造函數(shù)
public Arithmetic() { }

//帶參數(shù)構(gòu)造函數(shù),,初始化numOne和numTwo
public Arithmetic(int intNumOne, int intNumTwo)
{
this.numOne = intNumOne;
this.numTwo = intNumTwo;
}
#endregion

#region 屬性測試
//公共屬性訪問NumOne
public int NumOne
{
get { return numOne; }
set { numOne = value; }
}

//公共屬性 訪問NumTwo
public int NumTwo
{
get { return numTwo; }
set { numTwo = value; }
}
#endregion

#region 方法測試
///
/// 私有非靜態(tài)不帶參數(shù)的方法
///

///
private string Add()
{
return 'Add()方法是一個私有不帶參數(shù)的方法';
}

///
/// 私有靜態(tài)帶參數(shù)無返回值的方法
///

///
private static void Multiplcation(int intNumOne)
{
Console.WriteLine('Multiplication()方法是一個私有不帶參數(shù)無返回值的靜態(tài)方法');
}

///
/// 私有非靜態(tài)帶參數(shù)的方法
///

///
///
private void Subtration(int intNumOne, int intNumTwo)
{
string strMeesage = '{0}-{1}={2} Subtration(int intNumOne, int intNumTwo)方法是一個私有帶參數(shù)的方法';

Console.WriteLine(strMeesage, intNumOne, intNumTwo, intNumOne - intNumTwo);

}

///
/// 公有非靜態(tài)不帶參數(shù)的方法
///

///
public void Write()
{
Console.WriteLine( 'Write() 是一個共有的不帶參數(shù)無返回值的方法');
}

///
/// 公有靜態(tài)帶參數(shù)的方法
///

///
///
public static string Multiplcation(int intNumOne, int intNumTwo)
{
string strMessage = '{0}*{1}={2} Multiplcation(int intNumOne,int intNumTwo)方法是一個公有的靜態(tài)帶參數(shù)的方法';
strMessage = string.Format('{0}*{1}={2}', intNumOne, intNumTwo, intNumOne * intNumTwo);
return strMessage;
}

///
/// 公有非靜態(tài)帶參數(shù)的方法
///

///
///
///
public string Add(int intNumOne,int intNumTwo)
{
string strMessage = string.Format('{0}+{1}={2}', intNumOne, intNumTwo, intNumOne + intNumTwo);
return strMessage;
}
#endregion

///
/// 集成接口方法
///

///
public string Print()
{
return ' Print() 繼承接口方法';
}
}
}


(3).TestClassLib類庫的TestClass類


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestClassLib
{
public class TestClass
{
//模擬測試
public class Dialog : DialogInvoker { }

public virtual string TestMethod(string pp)
{
return pp;
}
}
}


(4).TestClassLib類庫的DialogInvoker類


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestClassLib
{
public class DialogInvoker
{
public int TestInt;
public void RegisterWithKey(string strOne,string strTwo)
{
Console.WriteLine('Test組合類:'+strOne+','+strTwo);
}
}
}


(5).TestClassLib類庫的TestDialog類


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestClassLib
{
public class TestDialog
{
//模擬測試
public void OnInit()
{
new TestClass.Dialog().RegisterWithKey('PP', 'TT');
}
}
}


(6).ReflectTest的Program.cs代碼調(diào)用測試


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestClassLib;

namespace ReflectTest
{
class Program
{
//定義委托測試
delegate void TestDelegate(int intNumOne,int intNumTwo);

static void Main(string[] args)
{
SimpleTest();//簡單測試

TestArithmetic();//分析測試

TestDialog();//模擬測試

Console.ReadLine();
}

///


/// 基本簡單測試
///

static void SimpleTest()
{
//System.Reflection.Assembly ass = Assembly.Load('TestClassLib'); //加載DLL
//System.Type t = ass.GetType('TestClassLib.TestChildrenClass');//獲得類型

string path = 'TestClassLib.TestClass' + ',' + 'TestClassLib';//命名空間.類型名,程序集
Type testType = Type.GetType(path);//加載類型

object objType = System.Activator.CreateInstance(testType);//創(chuàng)建實例
System.Reflection.MethodInfo methodReflection = testType.GetMethod('TestMethod');//獲得方法

object str = methodReflection.Invoke(objType, new object[] { 'MM' });//調(diào)用方法
Console.WriteLine('簡單測試輸出:'+str.ToString());
}

///
/// 反射分析測試
///

static void TestArithmetic()
{
string strAssembly = 'TestClassLib';//程序集DLL
string strReflectClass = 'TestClassLib.Arithmetic';//命名空間.類型
string strMethodAdd = 'Add';//調(diào)用方法Add名稱
string strMethodWrite = 'Write';//調(diào)用方法Write名稱
string strMethodMul = 'Multiplcation';//調(diào)用方法Multiplcation名稱

Assembly AssTestClassLib = Assembly.Load(strAssembly);//得到程序集
Type ArithmeticClass = AssTestClassLib.GetType(strReflectClass);;//得到具體類型
//Type ArithmeticClass = Type.GetType(strReflectClass + ',' + strAssembly);//創(chuàng)建對象也可以使用:命名空間.類型名,程序集

#region 獲取程序集下的信息
Console.WriteLine('\n得到'+strAssembly+'中所有類:' );
foreach (Type type in AssTestClassLib.GetTypes())
{
Console.WriteLine(type.Name+'是'+strAssembly+'命名空間下的對象');
}

Console.WriteLine('\n得到'+strAssembly+'.dll中的模塊集:');
Module[] modules = AssTestClassLib.GetModules();
foreach (Module module in modules)
{
Console.WriteLine(module.Name+'是'+strAssembly+'下的模塊集');
}
#endregion

#region 獲取指定類下的信息

Console.WriteLine('\n具體類型是'+ArithmeticClass.Name);
Console.WriteLine('{0}是不是Public類型{1}',ArithmeticClass,ArithmeticClass.IsPublic);
Console.WriteLine('{0}是不是Privet類型{1}',ArithmeticClass,ArithmeticClass.IsPrimitive);

Console.WriteLine('\n得到' + ArithmeticClass + '類下的構(gòu)造函數(shù):');
ConstructorInfo [] constructorInfos = ArithmeticClass.GetConstructors();
foreach (ConstructorInfo constructor in constructorInfos)
{
Console.WriteLine(constructor);
}

Console.WriteLine('\n得到'+ArithmeticClass+'類下的所有屬性:');
PropertyInfo[] propertyInfos = ArithmeticClass.GetProperties();
foreach (PropertyInfo prop in propertyInfos)
{
Console.WriteLine(prop.Name+'是'+ArithmeticClass + '類下的屬性');
}

Console.WriteLine('\n得到'+ArithmeticClass+'類下所有的接口:');
Type[] typeInterfaces = ArithmeticClass.GetInterfaces();
foreach (Type typeInterface in typeInterfaces)
{
Console.WriteLine(typeInterface.Name+'是'+ArithmeticClass+'類下的接口');
}

#region 獲取所有方法的信息
Console.WriteLine('\n得到'+ArithmeticClass+'類下所有方法:');
//查找私有方法
MethodInfo[] methodPrivates = ArithmeticClass.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (MethodInfo method in methodPrivates)
{
Console.WriteLine('私有方法 方法名稱:{0} 方法信息:{1}',method.Name,method);
}
//查找公有方法
MethodInfo[] methodPublics = ArithmeticClass.GetMethods(BindingFlags.Instance | BindingFlags.Public);
foreach (MethodInfo method in methodPublics)
{
Console.WriteLine('公有方法 方法名稱:{0} 方法信息:{1}', method.Name, method);
}
//查找私有靜態(tài)方法
MethodInfo[] methodStaticPrivates = ArithmeticClass.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
foreach (MethodInfo method in methodStaticPrivates)
{
Console.WriteLine('私有靜態(tài)方法 方法名稱:{0} 方法信息:{1}', method.Name, method);
}
//查找公有靜態(tài)方法
MethodInfo[] methodStaticPublics = ArithmeticClass.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach (MethodInfo method in methodPrivates)
{
Console.WriteLine('公有靜態(tài)方法 方法名稱:{0} 方法信息:{1}', method.Name, method);
}
#endregion
#endregion

#region 創(chuàng)建對象實例
Console.WriteLine('\n創(chuàng)建對象實例:');
int num1 = 3, num2 = 5;//定義參數(shù)

//創(chuàng)建一個不帶參數(shù)的實例
object obj = Activator.CreateInstance(ArithmeticClass, null);

//公有非靜態(tài)帶參數(shù)和返回值的方法調(diào)用
MethodInfo methodAdd = ArithmeticClass.GetMethod(strMethodAdd);
object[] addParams = new object[] {num1,num2 };
string strReturnAdd=methodAdd.Invoke(obj, addParams).ToString();
Console.WriteLine('創(chuàng)建{0}類,,調(diào)用公有非靜態(tài){1}方法,傳入?yún)?shù){2}和{3},,返回值:{4}',ArithmeticClass, strMethodAdd, num1, num2, strReturnAdd);

//私有非靜態(tài)無參無返回值方法調(diào)用
MethodInfo methodStaticAdd = ArithmeticClass.GetMethod(strMethodAdd, BindingFlags.Instance | BindingFlags.NonPublic);
string strStaticAdd=methodStaticAdd.Invoke(obj,null).ToString();
Console.WriteLine('創(chuàng)建{0}類,調(diào)用私有非靜態(tài){1}方法,,返回值:{2}:', ArithmeticClass, strMethodAdd, strStaticAdd);

//公有非靜態(tài)無參數(shù)無返回值方法調(diào)用
MethodInfo methodWite = ArithmeticClass.GetMethod(strMethodWrite, BindingFlags.Instance | BindingFlags.Public);
Console.WriteLine('創(chuàng)建{0}類,,調(diào)用公有非靜態(tài){1}方法,,無參數(shù)無返回值:', ArithmeticClass, strMethodWrite, methodWite.Invoke(obj, null));

//公有靜態(tài)帶參數(shù)有返回值的方法調(diào)用
MethodInfo methodMultiplcation = ArithmeticClass.GetMethod(strMethodMul, BindingFlags.Public | BindingFlags.Static);
object[] multParams = new object[] { num1, num2 };
string multReturn = methodMultiplcation.Invoke(obj, multParams).ToString();
//string multReturn = methodMultiplcation.Invoke(null, multParams).ToString();//調(diào)用靜態(tài)方法也可以轉(zhuǎn)入null對象
Console.WriteLine('創(chuàng)建{0}類,,調(diào)用公有靜態(tài){1}方法,傳入?yún)?shù){2}和{3},返回值:{4}', ArithmeticClass, strMethodMul, num1, num2, multReturn);

//測試InvokeMember方法
object objReturn= ArithmeticClass.InvokeMember(strMethodAdd, BindingFlags.InvokeMethod, null, obj,new object[]{num1,num2});
Console.WriteLine('測試InvokeMember方法:創(chuàng)建{0}類,,調(diào)用公有靜態(tài){1}方法,,傳入?yún)?shù){2}和{3},返回值:{4}:' ,
ArithmeticClass, strMethodAdd, num1, num2, objReturn.ToString());
#endregion

//動態(tài)創(chuàng)建委托
Console.WriteLine('\n動態(tài)創(chuàng)建委托:');
TestDelegate testDel = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), obj, 'Subtration');
testDel(9,3);

}

///
/// 模擬測試
///

static void TestDialog()
{
string strAssembly = 'TestClassLib';//程序集DLL
string strDialogReflect = 'TestClassLib.TestDialog';
string strDialogInvokerReflect = 'TestClassLib.DialogInvoker';
string strDialogNestedTypeReflect = 'TestClassLib.TestClass';//嵌套如何關(guān)系類,命名空間.類
string strNestedType = 'Dialog';//嵌套組合類
string strDialogMethod = 'OnInit';
string strDialogInvokerMethod = 'RegisterWithKey';

Console.WriteLine('\n模擬測試:');

Assembly assemblyTest = Assembly.Load(strAssembly);

//間接調(diào)用
Type typeDialog = assemblyTest.GetType(strDialogReflect);
object objDialog = Activator.CreateInstance(typeDialog);
MethodInfo methodDialog = typeDialog.GetMethod(strDialogMethod);
methodDialog.Invoke(objDialog, null);

//直接調(diào)用
Type typeDialogInvoker = assemblyTest.GetType(strDialogInvokerReflect);
object objDialogInvoker = Activator.CreateInstance(typeDialogInvoker);
MethodInfo methodDialogInvoker = typeDialogInvoker.GetMethod(strDialogInvokerMethod);
methodDialogInvoker.Invoke(objDialogInvoker, new object[] { 'MM', 'KK' });

//使用嵌套組合關(guān)系調(diào)用(這個更實用)
var typeTestClass =assemblyTest.GetType(strDialogNestedTypeReflect);
//var typeTestClass = Assembly.GetExecutingAssembly().GetType(strDialogNestedTypeReflect);//如果在同一個程序集下可以使用這種方式
var testClass= Activator.CreateInstance(typeTestClass);//創(chuàng)建本類

var typeNestedDialog= typeTestClass.GetNestedType(strNestedType);//獲取嵌套組合類
var dialogClass = Activator.CreateInstance(typeNestedDialog);//創(chuàng)建嵌套組合類
var methodInfo = dialogClass.GetType().GetMethod(strDialogInvokerMethod, BindingFlags.Instance | BindingFlags.Public);
methodInfo.Invoke(dialogClass, new object[] {'TT','KK' });
}
}
}


6.運行效果如下:



原文出自:博客園-SanMaoSpace

原文鏈接:http://www.cnblogs.com/SanMaoSpace/p/3764953.html



    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多