在看源碼的時候看見了where和default,雖說default很常見,但是它的用法我卻是第一次看到,哎,基礎不扎實啊!
下面介紹下這兩個特殊的關鍵字:
一、Where關鍵字
where 子句用于指定類型約束,這些約束可以作為泛型聲明中定義的類型參數的變量。
1.接口約束。
例如,可以聲明一個泛型類 MyGenericClass,這樣,類型參數 T 就可以實現 IComparable<T> 接口:
publicclassMyGenericClass<T>whereT:IComparable{}
2.基類約束:指出某個類型必須將指定的類作為基類(或者就是該類本身),才能用作該泛型類型的類型參數。
這樣的約束一經使用,就必須出現在該類型參數的所有其他約束之前。
class MyClassy<T,U>
whereT:class03.whereU:struct04.{
}
3.where 子句還可以包括構造函數約束。
可以使用 new 運算符創建類型參數的實例;但類型參數為此必須受構造函數約束 new() 的約束。new() 約束可以讓編譯器知道:提供的任何類型參數都必須具有可訪問的無參數(或默認)構造函數。例如:
publicclassMyGenericClass<T>whereT:IComparable,new()
{
//Thefollowinglineisnotpossiblewithoutnew()constraint:04.Titem=newT();
}
new() 約束出現在 where 子句的最后。4.對于多個類型參數,每個類型參數都使用一個 where 子句
例如:
interface MyI{}
class Dictionary<TKey,TVal>
whereTKey:IComparable,IEnumerable
whereTVal:MyI
{
publicvoidAdd(TKeykey,TValval)
{
}
}
5.還可以將約束附加到泛型方法的類型參數,例如:
public bool MyMethod<T>(Tt)whereT:IMyInterface{}
請注意,對于委托和方法兩者來說,描述類型參數約束的語法是一樣的:
delegateTMyDelegate<T>()whereT:new()
總之,Where就是為范型指定類型約束。二、Default關鍵字
在泛型類和泛型方法中產生的一個問題是,在預先未知以下情況時,如何將默認值分配給參數化類型 T:
T 是引用類型還是值類型。
如果 T 為值類型,則它是數值還是結構。
給定參數化類型 T 的一個變量 t,只有當 T 為引用類型時,語句 t = null 才有效;只有當 T 為數值類型而不是結構時,語句 t = 0 才能正常使用。
解決方案是使用 default 關鍵字,此關鍵字對于引用類型會返回空,對于數值類型會返回零。對于結構,此關鍵字將返回初始化為零或空的每個結構成員,具體取決于這些結構是值類型還是引用類型。以下來自 GenericList<T> 類的示例顯示了如何使用 default 關鍵字。
public class GenericList<T>
{
private class Node
{
//...06.07. public Node Next;
public T Data;
}
private Node head;
//...14.15. public T GetNext()
{
T temp = default(T);
Node current = head;
if (current != null)
{
temp = current.Data;
current = current.Next;
}
return temp;
}
}
2. default 另一種用法
在switch語句中,如果沒有任何 case 表達式與開關值匹配,則控制傳遞給跟在可選 default 標簽后的語句。如果沒有 default 標簽,則控制傳遞到 switch 以外。
int id = int32.Parse(Console.ReadLine());
switch (id)
{
case 1:
Console.WriteLine("Lee");
break;
case 2:
Console.WriteLine("Tang");
break;
default:
Console.WriteLine("Sorry, no one match this ID!");
break;
}
where 子句還可以包括構造函數約束。可以使用 new 運算符創建類型參數的實例;但類型參數為此必須受構造函數約束 new() 的約束。new() 約束可以讓編譯器知道:提供的任何類型參數都必須具有可訪問的無參數(或默認)構造函數。
new() 約束出現在 where 子句的最后。
對于多個類型參數,每個類型參數都使用一個 where 子句
還可以將約束附加到泛型方法的類型參數
請注意,對于委托和方法兩者來說,描述類型參數約束的語法是一樣的