本篇內容是特性和反射的最後一篇內容,前面三篇文章: 詳解C#特性和反射(一) 詳解C#特性和反射(二) 詳解C#特性和反射(三) 一、晚期綁定(Late Binding)是一種在編譯時不知道類型及其成員,而在運行時創建指定類型的實例並調用其成員的技術,使用命名空間System中的Activator類 ...
本篇內容是特性和反射的最後一篇內容,前面三篇文章:
詳解C#特性和反射(一)
詳解C#特性和反射(二)
詳解C#特性和反射(三)
一、晚期綁定(Late Binding)是一種在編譯時不知道類型及其成員,而在運行時創建指定類型的實例並調用其成員的技術,使用命名空間System中的Activator類來實現晚期綁定,例如:
Type myType = Type.GetType(myClassName); //首先獲取類型信息 object myObj = Activator.CreateInstance(myType); //通過Activator根據類型信息創建對象 //如果獲取的類型可以獲取到,即位於當前程式集,可以使用強制轉換或as運算符得到該類型的變數,然後直接調用該對象的成員: //MyClass myClass = (MyClass)myObj; //也可以使用CreateInstance的泛型重載方法直接獲取該類型的變數: //MyClass myClass = Activator.CreateInstance<MyClass>(); //如果獲取的類型不確定或當前程式編譯時並沒有引入該類型所在的命名空間,則需要通過反射訪問該類型的成員: MethodInfo methodInfo = myType.GetMethod(methodName); //獲取類型中的方法信息 methodInfo.Invoke(myObj, null); //調用類型中的無參實例方法
※靜態方法CreateInstance會調用匹配度最高的構造函數構建對象,例子中的CreateInstance(Type type)和CreateInstance<T>()只會調用目標類型中無參的公有構造函數,當目標類型中沒有無參的公有構造函數時會拋出異常MissingMethodException;Activator類中提供多個CreateInstance的重載方法以調用不同的構造函數並傳入參數,這裡不再一一介紹,用到時查看定義即可看到所有的方法聲明;
二、使用晚期綁定技術也會打破單例模式中的對象唯一性:
public class MyClass { public static MyClass Instace = new MyClass(); private MyClass() { Console.WriteLine("MyClass's Constructor Execute."); } public int MyFiled; } public class Program { static void Main(string[] args) { Console.WriteLine("Access the static member Instace of MyClass."); MyClass.Instace.MyFiled = 10; Console.WriteLine("Use the Activator class to create instance of MyClass.");
//通過CreateInstance的重載方法調用目標類型的私有構造函數 MyClass myObj = (MyClass)Activator.CreateInstance(typeof(MyClass), true); Console.WriteLine($"Instace of MyClass's MyFiled is {MyClass.Instace.MyFiled}, myObj's MyFiled is {myObj.MyFiled}."); Console.Read(); } }
輸出結果為(在.Net Core下運行,不同平臺下靜態成員的初始化時機略有不同,會導致這裡第一行和第二行輸出順序不一致):
Access the static member Instace of MyClass.
MyClass's Constructor Execute.
Use the Activator class to create instance of MyClass.
MyClass's Constructor Execute.
Instace of MyClass's MyFiled is 10, myObj's MyFiled is 0.
因此在使用單例模式時,應當避免使用晚期綁定創建對象,而應使用反射獲取單例中的靜態成員Instance;
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的認可是我寫作的最大動力!
作者:Minotauros
出處:https://www.cnblogs.com/minotauros/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。