C#泛型


1、引入泛型

  泛型不是一個簡單的語法糖,是框架升級支持的

 

 

 List<string>就是泛型,為什么要有泛型?

List<T>是一個集合,可能是一組int,也可能是一組string,泛型就是用一個東西來滿足多種不同類型的需求的。

2、泛型方法

  方法名稱后面加上尖括號,里面是類型參數,類型參數實際上就是一個類型T聲明,方法就可以用這個類型T了。泛型聲明方法時,並沒有寫死類型,T是什么,並不知道,T要等着調用的時候才指定。正式因為沒有寫死,才擁有了無限的可能。

  泛型的設計思想--延遲聲明:推遲一切可以推遲的,一切能晚點再做的事,就晚一點再做。泛型不是一個簡單的語法糖,是框架升級支持的。泛型方法的性能跟普通方法一致,是最好的,而且還能一個方法滿足多個不同類型。

  下面來看下代碼是怎么寫的:

        public static void Show<T>(T tParameter)//, T t = default(T
        {
            Console.WriteLine("This is {0},parameter={1},type={2}",
               typeof(CommonMethod), tParameter.GetType().Name, tParameter);
        }    

  泛型類、泛型委托等和泛型方法聲明類似:

  

//泛型類 
public class GenericClass<T> where T : ISports
    {
    }
//泛型接口
public interface GenericInterface<S>
    {
    }
//方形委托
public delegate void Do<T>() where T : ISports;

 

  WebService  WCF都不能用泛型,為什么?

  因為這些是跨語言的,別的語言也能用,不支持泛型,服務在發布的時候是必須確定的,泛型在編譯時確定不了。

3、泛型約束

  沒有約束,其實很受局限。

  基類約束:

    where T:BaseModel

    1、可以把T當成基類---權利

    2、T必須是BaseModel或者其子類

  為什么要有約束?

    因為有約束才有權利,自由主義的鼻祖洛克先生說過,有了法律,才有自由。

  泛型:不同的類型都能進來,任何的類型都能過來,你知道我是誰?

   where T:class  引用類型約束;引用類型

   where T:struct

   where T:new()   無參構造函數約束

 public static void Show<T>(T tParameter)
            //where T : String//密封類約束的不行,因為沒有意義
            //where T : People
            //where T : ISports
            where T : People, ISports, IWork, new()

        {
            Console.WriteLine("This is {0},parameter={1},type={2}",
               typeof(GenericConstraint), tParameter.GetType().Name, tParameter);

            Console.WriteLine($"{tParameter.Id}  {tParameter.Name}");
            tParameter.Hi();
            //tParameter.Pingpang();
        }
        public T GetT<T, S>()
            //where T : class//引用類型約束
            //where T : struct//值類型
            where T : new()//無參數構造函數
            where S : class
        {
            //return null;
            //return default(T);//default是個關鍵字,會根據T的類型去獲得一個默認值
            return new T();
            //throw new Exception();
        }

 

4、協變、逆變

   .net4.0才出現的,只能放在接口或者委托的泛型參數前面

   out協變 covariant,修飾返回值,只能作為返回值

   in  逆變  contravariant,修飾傳輸參數,只能作為傳入值

    public class Bird
    {
        public int Id { get; set; }
    }
    public class Sparrow : Bird
    {
        public string Name { get; set; }
    }
            {//協變
                IEnumerable<Bird> birdList1 = new List<Bird>();
                IEnumerable<Bird> birdList2 = new List<Sparrow>();

                Func<Bird> func = new Func<Sparrow>(() => null);

                ICustomerListOut<Bird> customerList1 = new CustomerListOut<Bird>();
                ICustomerListOut<Bird> customerList2 = new CustomerListOut<Sparrow>();
            }



            {//逆變
                ICustomerListIn<Sparrow> customerList2 = new CustomerListIn<Sparrow>();
                ICustomerListIn<Sparrow> customerList1 = new CustomerListIn<Bird>();

                ICustomerListIn<Bird> birdList1 = new CustomerListIn<Bird>();
                birdList1.Show(new Sparrow());
                birdList1.Show(new Bird());

                Action<Sparrow> act = new Action<Bird>((Bird i) => { });
            }


            {
                IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>();
                IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>();//協變
                IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>();//逆變
                IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>();//協變+逆變
            }

5、泛型緩存

  每個不同的T,都會生成一份不同的副本,適合不同的類型,需要緩存一份數據 場景,效率高

 

如有不對的地方,希望大家多指教!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM