泛型

一,什麼是泛型
1.這是一個Int類型的集合
public class IntList
    {
        int[] arr;
        int count;

        /// <summary>
        /// 獲取已儲存的元素的個數
        /// </summary>
        public int Count
        {
            get { return count; }
        }

        public IntList(int length)
        {
            arr = new int[length];
        }

        #region 1.0 向集合中 追加元素 +void Add(int ele)
        /// <summary>
        /// 向集合中 追加元素
        /// </summary>
        /// <param name="ele"></param>
        public void Add(int ele)
        {
            //判斷當前已添加元素的個數 是否 大於 數組的容量
            if (count >= arr.Length)
            {
                //建立 2倍 的新數組
                int[] arrNew = new int[arr.Length * 2];
                //將arr 裏的 數據 複製到 新數組中(重新數組的第0個位置開始存放)
                arr.CopyTo(arrNew, 0);
                //將新數組的引用 設置給 arr
                arr = arrNew;
            }
            //將元素 加入到 數組中
            arr[count] = ele;
            //元素總個數 +1
            count++;
        } 
        #endregion

        #region 2.0 索引器  +int this[int index]
        public int this[int index]
        {
            get
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    return arr[index];
                }
            }

            set
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    arr[index] = value;
                }
            }
        } 
        #endregion
 
2.這是一個String類型集合
public class StringList
    {
        string[] arr;
        int count;

        /// <summary>
        /// 獲取已儲存的元素的個數
        /// </summary>
        public int Count
        {
            get { return count; }
        }

        public StringList(int length)
        {
            arr = new string[length];
        }

        #region 1.0 向集合中 追加元素 +void Add(int ele)
        /// <summary>
        /// 向集合中 追加元素
        /// </summary>
        /// <param name="ele"></param>
        public void Add(string ele)
        {
            //判斷當前已添加元素的個數 是否 大於 數組的容量
            if (count >= arr.Length)
            {
                //建立 2倍 的新數組
                string[] arrNew = new string[arr.Length * 2];
                //將arr 裏的 數據 複製到 新數組中(重新數組的第0個位置開始存放)
                arr.CopyTo(arrNew, 0);
                //將新數組的引用 設置給 arr
                arr = arrNew;
            }
            //將元素 加入到 數組中
            arr[count] = ele;
            //元素總個數 +1
            count++;
        } 
        #endregion

        #region 2.0 索引器  +int this[int index]
        public string this[int index]
        {
            get
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    return arr[index];
                }
            }

            set
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    arr[index] = value;
                }
            }
        } 
        #endregion
當咱們操做這些集合的時候
IntList intList = new IntList(3);
            intList.Add(9);
            intList.Add(19);
            intList.Add(59);

            for (int i = 0; i < intList.Count; i++)
            {
                Console.WriteLine(intList[i]);
            }

            StringList stringList = new StringList(3);
            stringList.Add("9a");
            stringList.Add("19b");
            stringList.Add("59c");

            for (int i = 0; i < stringList.Count; i++)
            {
                Console.WriteLine(stringList[i]);
            }

會發現變得只是類型,這樣重複的類型變換有什麼辦法解決了,這就須要用到泛型html

/// <summary>
    /// 自定義泛型集合類,帶泛型參數
    /// </summary>
    /// <typeparam name="MyType">集合的元素類型</typeparam>
    public class MyGenericList<MyType>
{
        MyType aValue;
        MyType[] arr;
        int count;
        //int a = MyType;

        #region 獲取已儲存的元素的個數 +int Count
        /// <summary>
        /// 獲取已儲存的元素的個數
        /// </summary>
        public int Count
        {
            get { return count; }
        } 
        #endregion

        public MyGenericList(int length)
        {
            arr = new MyType[length];
        }

        #region 1.0 向集合中 追加元素 +void Add(MyType ele)
        /// <summary>
        /// 向集合中 追加元素
        /// </summary>
        /// <param name="ele"></param>
        public void Add(MyType ele)
        {
            //判斷當前已添加元素的個數 是否 大於 數組的容量
            if (count >= arr.Length)
            {
                //建立 2倍 的新數組
                MyType[] arrNew = new MyType[arr.Length * 2];
                //將arr 裏的 數據 複製到 新數組中(重新數組的第0個位置開始存放)
                arr.CopyTo(arrNew, 0);
                //將新數組的引用 設置給 arr
                arr = arrNew;
            }
            //將元素 加入到 數組中
            arr[count] = ele;
            //元素總個數 +1
            count++;
        } 
        #endregion

        #region 2.0 索引器  +MyType this[int index]
        public MyType this[int index]
        {
            get
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    return arr[index];
                }
            }

            set
            {
                if (index >= arr.Length)
                {
                    throw new System.Exception("數組下標越界!");
                }
                else
                {
                    arr[index] = value;
                }
            }
        } 
        #endregion
如今調用則能夠變成
MyGenericList<int> intList = new MyGenericList<int>(3);
            intList.Add(9);
            intList.Add(19);
            intList.Add(59);

            for (int i = 0; i < intList.Count; i++)
            {
                Console.WriteLine(intList[i]);
            }
string 類型的則能夠
  MyGenericList<string> stringList = new MyGenericList<string>(3);
            stringList.Add("9a");
            stringList.Add("19b");
            stringList.Add("59c");

            for (int i = 0; i < stringList.Count; i++)
            {
                Console.WriteLine(stringList[i]);
            }
MyType只是至關於一個佔位符,用的時候用具體的類型來替換便可。他只能是一個類型,不能是具體的值。
泛型是指的帶類型參數的類,而不是類型參數自己。如public class MyList<T>{….}其中的MyList就是泛型,而T是類型參數。
泛型參數能夠有多個,好比MyList<T,MyType>也是能夠的
實例化一個引用類型的泛型,它在內存中分配的大小是同樣的。
實例化一個值類型的泛型,它在內存中分配的大小是不同的。
儘管如此,CLR仍是爲每一個不一樣的類型參數建立了不一樣的泛型類版本。       

二.泛型的繼承數組

繼承一個泛型類時,必須爲其傳遞泛型參數!函數

public class Father<k,v>{}//父類this

定義子類時直接爲父類泛型參數賦值
public class Son:Father<int,string>
 
定義子類時把子類泛型參數賦給父類泛型參數
public  class Son<w,y>:Father<int,string>
 
public  class Son:Father<k,v>
這種是錯誤的,由於K,V不存在
 
三.泛型約束
 public class MyGenericDog<T> 
        where T:new()//約束 傳給 T 的類 必須包含一個 無參的構造函數
    {
        T t;
        public MyGenericDog()
        {
            t = new T();
        }
}

在使用時必須保證類有一個無參的構造函數spa

 private void btnNewT_Click(object sender, EventArgs e)
        {
            MyGenericDog<LittleDog> list = new MyGenericDog<LittleDog>();
        }
public class LittleDog
    {
        public LittleDog()
        {
        }

        public LittleDog(string str)
        {
        }
  }

四.用來約束泛型參數 必須是某個類 或者某個類的子類code

class Dog
{
    public void Shout(){}
}
class Cat
{
    public void Walk(){}
}
class House<TPet,TPet2>where TPet:Dog where TPet2:Cat
{
    public c(TPet p,TPet2 p2)
   {
       p1.Shout();
       p2.Walk();
   }
}

1.一個泛型參數不容許多個基類約束,不能寫成htm

class House<TPet,TPet2>where TPet:Dog where TPet:Cat
由於不可能既是狗,又是貓。
2.不能爲密封類指定基類約束(string) 密封類即爲私有類。即sealed這種不能繼承的類。
3.也不能用nullable<T>
五.用來約束泛型參數必須是值類型或者引用類型
public struct A{}
public class B{}
public class C<T> where T:struct  值類型
{
}
public class C2<T> where T:class  引用類型
{
}

好比上面的若是使用c<person>就會報錯
六.泛型方法
public void Test<k>() where k:new()
{
}

K能夠用在三個地方:blog

1.參數繼承

public void Test<k>(k a) {
}

2.能夠在方法體內用到索引

public void Test<k>() where k:new()
{
   k k1=new k();
}

3.能夠當返回值

public K Test<k>() where k:new()
{
   return k;
}

七.泛型方法的重載

void sayA()
            {
            }
           void sayA<T>()
            {
            }
           void sayA<K>()
            {
            }

在使用時能夠看到智能提示出現兩個方法say,say<>說明他們不構成重載

           void sayA<T>()
            {
            }
           void sayA<K>()
            {
            }
這樣是不行的,由於泛型方法只是個佔位符,編譯器會認爲是同一個方法

八.泛型方法重寫

6@%9ZGPL460]WM}N3PO5T3O

子類當中約束where k:class是不能在子類中重寫。而where k:new()不須要些,從父類中繼承過來了。

相關文章
相關標籤/搜索