泛型 介面約束: 普通 單例模式: 上面用到的是類中一個方法來獲取類的唯一實例對象 那完全也可以用屬性的訪問器來初始化一個類的對象啊,如下: 調用的話:var str = Singleton.Instance.Outresult("我是輸出內容...."); 綜上:兩種方式實現單例 泛型 new() ...
泛型 介面約束:
using System; namespace ConsoleApp1 { /* * * 介面約束:where T:interfaceName * T是類型形參的名稱,interfaceName是介面名稱, * 介面約束是 指定某個類型實參必須實現的介面。 * 它的兩個主要的功能和基類約束一樣,允許開發人員在泛型類中使用介面中的成員;確保只能使用實現了特定介面的類型實參。 * 也就是說,對任何給定的介面約束,類型實參必須是介面本身或者是實現了該介面的類。 * */ class Program { static void Main(string[] args) { Console.WriteLine(Compare<int>.CompareData(3, 12));//12 } } /// <summary> /// 介面約束,T的類型用IComparable這個介面來約束 /// 也就是說T的類型就是IComparable介面,用T可以調用它裡面的任何方法,只要你願意,這也就實現了介面約束的目的,即你要使用我這個介面,就必須按照我的規定來! /// </summary> /// <typeparam name="T"></typeparam> public class Compare<T> where T : IComparable { // 定義一個方法,返回值類型為 T , 其兩個形參也是T類型的 // 方法的功能:返回較大值 public static T CompareData(T n1,T n2) { // 調用IComparable介面中方法CompareTo(),這個方法的返回值類型為int return n1.CompareTo(n2) > 0 ? n1 : n2; //先不考慮兩值相等的時候 } } }
普通 單例模式:
class Program { static void Main(string[] args) { //使用單例:類名.靜態方法() <----獲取到實例對象,然後再用對象調用它裡面的其他方法即可 var str = Singleton.getInstance().Outresult("我是輸出內容...."); Console.WriteLine(str); } } /// <summary> /// 單例模式-----即一個函數只允許有一個實例對象! /// </summary> public class Singleton { // 首先定義一個Singleton類型的對象(必須靜態的,不然調用它還要實例化,相悖了....),intance就是Singleton類的唯一實例對象 public static Singleton instance; // 一個獲取實例對象的方法 public static Singleton getInstance() { // 只有當Singleton類型的對象不存在時(即本類的實例對象),才去創建這樣一個對象! if (instance == null) { instance = new Singleton(); } return instance; } // 本類中一個輸出方法(測試用的) public string Outresult(string str) { return str; } }
上面用到的是類中一個方法來獲取類的唯一實例對象
那完全也可以用屬性的訪問器來初始化一個類的對象啊,如下:
public class Singleton { public static Singleton instance; // 用屬性的get訪問器 生成單例的對象 public static Singleton Instance { get { if (instance == null) { instance = new Singleton(); } return instance; } } //其他輸出方法...... }
調用的話:var str = Singleton.Instance.Outresult("我是輸出內容....");
綜上:兩種方式實現單例
泛型 new()約束:父類是一個單例類
using System; namespace ConsoleApp1 { /* * * new()構造函數約束: where T: new() * 它允許開發人員實例化一個泛型類型的對象。 * new()約束要求類型實參必須提供一個無參數的公有構造函數。 * 使用new()約束時,可以通過調用該無參構造器來創建對象。 * * 註意: * 1. new()在與其他約束一起使用時,必須放在約束列表的末端 * 2. 僅允許使用無參構造器構造一個對象,即使同時存在其他的構造器也是如此。即不允許給類型形參的構造器傳遞實參。 * 3. 不可以同時使用new()約束和值類型約束。因為值類型都是隱式的提供一個無參公共構造器。就如同定義介面時指定訪問類型為public一樣,編譯器會報錯,因為介面一定是public的!!! * */ class Program { static void Main(string[] args) { Console.WriteLine(Person.Instance.getPerson()); Console.WriteLine(Student.Instance.getStudent()); Console.WriteLine(Person.Instance.Outresult()); Console.ReadKey(); } } /// <summary> /// 單例模式-----即一個函數只允許有一個實例對象! /// </summary> public class Singleton<T> where T : new() { private static T instance; // 用屬性的get訪問器 生成單例的對象 public static T Instance { get { if (instance == null) { // 這裡創建的不再是一個Singleton對象,而是T對象 instance = new T(); // 這樣寫會報錯:變數類型 T 沒有new()約束,因此無法創建該類型的實例 //解決:類上面寫new()的約束...... } return instance; } } // 本類中一個輸出方法(測試用的) public string Outresult() { return "this method in Singleton"; } } /* * 對於繼承Singleton的類,必須要有一個無參構造器,因為他有new()約束!!! * */ // Person類繼承Singleton類,就必須指定T的類型,這裡指定為Person.... public class Person : Singleton<Person> { public string getPerson() { return "this method in Person class"; } } public class Student : Singleton<Student> { public string getStudent() { return "this method in Student"; } } }
組合約束:
/* * 五種約束: * * where T:struct 值類型約束----類型參數必須為值類型 * * where T:class 引用類型約束:適用於類、介面、委托、數組等----類型參數必須為引用類型 * * where T:new() new()約束-----類型參數必須有一個公有的無參構造器 * * where T:<base class name> 基類約束-----類型參數必須是指定的基類或是派生自指定的基類 * * where T:<interface> 介面約束-----類型參數必須是指定介面或實現指定的介面,可以指定多個介面約束,約束介面也可以是泛型的 * * * 組合約束:用的不多,基本都是別人封裝好的,我們拿來直接調用即可 * 同一個類型形參可以使用多個約束。逗號隔開 * 在約束列表中,第一個必須是引用類型約束或者值類型約束,或者是基類約束,然後才是介面約束,最後才是new()約束 * 指定引用類型約束或值類型約束的同時也指定基類約束是非法的 * * 例如: * class Test<T> where T : Myclass, Interface, new(){......} * 替換T的類型實參必須是繼承Myclass類,實現Interface介面,且擁有一個無參構造器 * * 在使用兩個或多個類型形參時,也可以使用多條where子句分別為它們指定約束 * */