泛型 接口約束:數組
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; } }
上面用到的是類中一個方法來獲取類的惟一實例對象測試
那徹底也能夠用屬性的訪問器來初始化一個類的對象啊,以下:this
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("我是輸出內容....");spa
綜上:兩種方式實現單例 code
泛型 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"; } } }
組合約束:blog
/* * 五種約束: * * 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子句分別爲它們指定約束 * */