泛型約束:接口約束、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;
    }
}

上面用到的是類中一個方法來獲取類的惟一實例對象測試

那徹底也能夠用屬性的訪問器來初始化一個類的對象啊,以下: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子句分別爲它們指定約束
*  
*/
相關文章
相關標籤/搜索