看到他我一下子就悟了– 泛型(1)

來源:互聯網
上載者:User

1.泛型概念:

      本質上,術語”泛型”指的是”參數化型別(parameterized types)”.參數化型別非常重要,因為它們可以在建立類.結構.方法和委託的時候將要操作的資料類型作為參

數進行指定.使用參數化型別的類.結構.方法和委託都可以稱為泛型,如”泛型類”或者”泛型方法”.

       在具體聲明一個變數或者執行個體化之前,型別參數T只是一個預留位置。等到具體聲明和執行個體化的時候,編譯器要求代碼指定型別參數。泛型型別聲明了泛型參數預留位置類型,由泛型型別的使用者填寫這些預留位置,並作為泛型的參數提供給泛型型別.

 

2.泛型約束:約束聲明了泛型要求的型別參數的特徵。

    為了聲明一個約束,需要使用where關鍵字,後跟一對”參數:要求”.其中,”參數”必須是泛型型別中定義的一個參數,而”要求”用於限制類型從

中”派生”的類或介面,或者限制必須存在一個預設構造器,或者限制使用一個引用/實值型別約束.

2.1基類約束(where T:base-class-name)

       有的時候,你可能需要限制類型從一個特定的類派生.這是用基類約束(base class constraint)做到的.使用基類約束,可以指定某個類型實參

必須繼承的基類.基類約束有兩個重要功能.

  首先,他允許在泛型類中使用由約束指定的基類所定義的成員.例如,可以調用基類的方法或者使用基類的屬性.如果沒有基類約束,編譯器就無法知道某

個類型實參擁有哪些成員.通過提供基類約束,編譯器將知道所有的類型實參都擁有由指定的基類所定義的成員.

  基類約束的第二個功能是,確保只適用支援指定基類的類型實參.這意味著對於任意給定的基類約束,類型實參要麼是基類本身,要麼是派生於該基

類.如果試圖使用沒有匹配或者繼承指定的類型實參,就會導致編譯錯誤例:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//泛型:基類約束
//基類約束兩個作用:1.基類約束允許泛型類訪問基類的成員
// 2.確保只能使用滿足該約束的型別參數,從而實作類別型安全
namespace generic
{
/*案例描述:假設要建立一個管理電話號碼列表的工具.另外,假定不同組的使用者
使用的是不同的列表.例如,一個列表用於朋友,令外一個列表用於供應商等.
*/

/// <summary>
/// PhoneNumber基類,它用於儲存姓名和姓名相對應的電話號碼
/// </summary>
class PhoneNumber
{
public string Number { get; set; }
public string Name { get; set; }

public PhoneNumber(string n, string num)
{
this.Name = n;
this.Number = num;
}
}

/// <summary>
/// 朋友電話
/// </summary>
class Friend : PhoneNumber
{
/// <summary>
/// 電話號碼是否為工作號碼
/// </summary>
public bool IsWorkNumber { get; private set; }

public Friend(string n, string num, bool wk)
: base(n, num)
{
this.IsWorkNumber = wk;
}
}

/// <summary>
/// 供應商電話
/// </summary>
class Supplier : PhoneNumber
{
public Supplier(string n, string num)
: base(n, num)
{
}
}
/*為了管理電話列表,下面建立一個名為PhoneList的類.由於希望該類能夠
* 管理任意類型的電話列表,因此將其實現為泛型.另外,由於列表管理的一部分內容是
* 根據姓名查詢號碼,或者根據號碼查詢姓名,因此要給它添加約束,從而
* 確儲存儲在列表中的對象的類型必須是PhoneNumber衍生類別的執行個體
*/

/// <summary>
/// 管理任意類型的電話列表
/// </summary>
/// <typeparam name="T"></typeparam>
class PhoneList<T> where T:PhoneNumber
{
T[] phList;

int end;

public PhoneList()
{
phList = new T[10];
end = 0;
}

public bool Add(T newEntry)
{
if (end == 10) return false;

phList[end] = newEntry;
end++;

return true;
}

public T FindByName(string name)
{
for (int i = 0; i < end; i++)
{
if (phList[i].Name == name)
return phList[i];
}

throw new NotFoundException();
}

public T FindByNumber(string number)
{
for (int i = 0; i < end; i++)
{
if (phList[i].Number == number)
return phList[i];
}

throw new NotFoundException();
}
}

/// <summary>
/// 此類沒有繼承PhoneNumber,因此不能用於建立PhoneList
/// </summary>
class EmailFriend
{
//.....
}
/*
* 這是一個定製異常,雖然該樣本只使用預設建構函式,但是出於說明的
* 目的,NotFoundException實現了Exception定義的所有建構函式
* 注意:這些建構函式只調用了Exception定義的相等基類建構函式.
* NotFoundException沒有向Exception添加任何內容,因此不需要
* 執行任何進一步的操作
*/
class NotFoundException : Exception
{
public NotFoundException():base(){}
public NotFoundException(string str):base( str){}
public NotFoundException(string str, Exception inner) :
base(str, inner) { }
protected NotFoundException(
System.Runtime.Serialization.SerializationInfo si,
System.Runtime.Serialization.StreamingContext se) :
base(si, se) { }
}
}

 

怎樣調用:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;namespace generic{    class Program    {        static void Main(string[] args)        {            BaseClassConstraint();            Console.Read();        }        //基類約束        public static void BaseClassConstraint()        {           //可以通過編譯            PhoneList<Friend> plist = new PhoneList<Friend>();            //錯誤添加            //plist.Add(new Friend() {Name="Tom",Number="555-1234",IsWorkNumber=true });        //正確添加            plist.Add(new Friend("Tom", "5555-333", true));            plist.Add(new Friend("Gary", "5555-332", true));            plist.Add(new Friend("WangC", "5555-331", false));            try            {                Friend frnd = plist.FindByName("Gary");                Console.WriteLine(frnd.Name+":"+frnd.Number);                if(frnd.IsWorkNumber)                    Console.WriteLine("(work)");                else                    Console.WriteLine();            }            catch (NotFoundException)            {                Console.WriteLine("Not Found");            }            //供應商            PhoneList<Supplier> plist2 = new PhoneList<Supplier>();            plist2.Add(new Supplier("Global Hardware", "400-123"));            plist2.Add(new Supplier("Computer", "400-124"));            plist2.Add(new Supplier("NetWorkCity", "400-125"));            try            {                Supplier sp = plist2.FindByNumber("400-124");                Console.WriteLine(sp.Name+":"+sp.Number);            }            catch (NotFoundException)            {                Console.WriteLine("Not Found");            }            //沒有繼承的           // PhoneList<EmailFriend> plist3 = new PhoneList<EmailFriend>();        }    }   }

 未完待續……

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.