天天看點

.NET知識梳理——1.泛型Generic

   .NET知識梳理——1.泛型Generic    

1. 泛型Generic

1.1        引入泛型:延遲聲明

泛型方法聲明時,并未寫死類型,在調用的時候再指定類型。

延遲聲明:推遲一切可以推遲的。

1.2        如何聲明和使用泛型

泛型方法:方法名稱後面加上尖括号,裡面是類型參數

類型參數實際上就是一個類型T聲明,方法就可以用這個類型T了。

如下所示:

public static void Show

        {

            Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

        }

1.3        泛型的好處和原理

泛型方法性能跟普通方法一緻,泛型聲明方法時,并未寫死類型,T是什麼類型,隻有在調用的時候才知道,一個方法能滿足不同類型。

1.4        泛型類、泛型方法、泛型接口、泛型委托

1.4.1  泛型類型

一個類滿足不同類型的需求

具體如下:

public class BaseModel

    {

        public int Id { get; set; }

    }

    public class GenericClass

        where T:BaseModel//為泛型基類限制

1.4.2  泛型方法

一個方法滿足不同類型的需求

1.4.3  泛型接口

一個接口滿足不同類型的需求

   //泛型接口

    public interface IGenericInterface

        public void  SayHi(T t);

}

1.4.4  泛型委托

一個委托滿足不同類型的需求

public delegate void Do

1.5        泛型限制

沒有限制,泛型會很局限。主要有5中泛型的限制。如下:

1.5.1  基類限制

Where T:BaseModel

可以把BaseModel當作基類

隻有該類型的對象或從該類型派生出的對象,可被用作類型參數。(密封類限制的不行,因為沒有意義。)

//基類

    public class BaseModel

    //泛型類

調用:

  GenericConstraint.Show

1.5.2  引用類型限制

//引用類型限制

        public static T Get

            return default(T);//default是關鍵字,根據類型T傳回對應的預設值

GenericConstraint.Get

1.5.3  值類型限制

  //值類型限制

        Public static D GetD

            return default(D);

GenericConstraint.GetD

1.5.4  無參數構造函數

//無參數構造函數限制

        Public static S GetS()

            where S: new()//無餐構造函數限制

        {     

            return new S();

GenericConstraint.GetS

1.5.5  接口限制

//接口限制

        public static void Show2

            t.Basketball();

GenericConstraint.Show2

1.6        協變、逆變

所謂協變、逆變都是跟泛型有關的(多用在接口)。

1.6.1  協變

修飾傳回值

讓右邊用子類,讓泛型用起來更友善(子類轉父類)

Out修飾,協變後隻能是傳回結果,不能做參數

IEnumerable

  //out 協變,隻能是傳回結果(子類轉父類)

    public interface ICustomerListOut

        T Get();

    public class CustomerListOut

        public T Get()

            return default(T);

ICustomerListOut

            Func

            IEnumerable

1.6.2  逆變

修飾傳入參數

讓右邊可以用父類,讓泛型用起來更友善(父類轉子類)

In修飾,逆變後隻能當作參數

//in 逆變 隻能是輸入參數(父類轉子類)

    public interface ICustomerListIn

        void Show(T t);

    public class CustomerListIn

        public void Show(T t)

            Console.WriteLine(t.GetType().Name);

  //逆變

            ICustomerListIn

            Action

public interface IMyList

        void Show(inT t);

        outT Get();

        outT Do(inT t);

    public class MyList

        public T1 Get()

            Console.WriteLine(typeof(T1).Name);

            return default(T1);

        public T1 Do(T t)

   IMyList

    IMyList

IMyList

1.7        泛型緩存

泛型緩存,每個類型都會生成一個不同的副本(适合不同類型需要緩存一份資料的場景)

  public class GenericCache

        private static string _TypeTime = "";

        static GenericCache()

            Console.WriteLine("This is GenericCache 靜态構造函數");

            _TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";

        public static string GetCache()

            return _TypeTime;

///

    /// 字典緩存:靜态屬性常駐記憶體

    ///

    public class DictionaryCache

        private static Dictionary

        static DictionaryCache()

            Console.WriteLine("This is DictionaryCache 靜态構造函數");

            _TypeTimeDictionary = new Dictionary

        public static string GetCache

            Type type = typeof(Type);

            if (!_TypeTimeDictionary.ContainsKey(type))

                _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH mm:ss")}";

繼續閱讀