//用來統計單詞的個數
//泛型類型包括(類,接口,委託和結構---沒有泛型枚舉)和泛型方法
//用來統計單詞的個數
class DictionaryDemo
{
static Dictionary<string,int> CountWords(string text)
{
Dictionary<string,int> frequencies;
frequencies = new Dictionary<string,int>();
string[] words = Regex.Split(text, @"/W+"); //將文本分解成單詞
foreach (string word in words)
{
if (frequencies.ContainsKey(word))
{
frequencies[word]++;
}
else
{
frequencies[word] = 1;
}
}
return frequencies;
}
static void Main()
{
string text = @"Do you like green eggs and ham?
I do not like them, Sam-I-am.
I do not like green eggs and ham.";
Dictionary<string, int> frequencies = CountWords(text);
foreach (KeyValuePair<string, int> entry in frequencies)
{
string word = entry.Key;
int frequency = entry.Value;// 若用c#1的HASHTABLE的相似的鍵和值屬性的非返型dictionaryentry,但是word和frequency需要強制類型轉換:因爲Key,Value都是以object類型返回的
Console.WriteLine("{0}: {1}", word, frequency);
}
}
}
//泛型方法: 雖然dictionary<tkey,tvalue>沒有泛型方法,但它的近親list<T>有的
class ListConvertAll
{
static double TakeSquareRoot(int x)
{
return Math.Sqrt(x);
}
static void Main()
{
List<int> integers = new List<int>();
integers.Add(1);
integers.Add(2);
integers.Add(3);
integers.Add(4);
// Converter Represents a method that converts an object from one type to another type.
Converter<int, double> converter = TakeSquareRoot;
List<double> doubles = integers.ConvertAll<double>(converter); //泛型類型中的泛型方法
foreach (double d in doubles)
{
Console.WriteLine(d);
}
}
}
// 在非泛型類型中實現泛型方法:
class GenericMethodDemo
{
static List<T> MakeList<T> (T first, T second)
{
List<T> list = new List<T>();
list.Add (first);
list.Add (second);
return list;
}
static void Main()
{
List<string> list = MakeList<string>("Line 1", "Line 2"); // 在非泛型類型中實現泛型方法:
foreach (string x in list)
{
Console.WriteLine(x);
}
}
}
// 類型約束:
1: 引用類型約束: T:class 用於確保使用的類型實參是引用類型:
2:值類型約束: T:struct 用於確保使用的類型實參是值類型:將包括枚舉,但是它將可空類型排除在外:
3: 構造函數類型約束: 表示爲T: new(); 必須是所有引用類型參數的最後一個約束,僅覈對所有的類型實參有一個
無參數構造函數,這個構造函數可用於創建類型的實例:
4: 派生類型的約束: (有點難以理解)
5.組合約束:
//泛型方法類型實參的判斷:
調用泛型方法時,指定類型的實參常常會顯得多餘的,根據向方法傳遞的實參,很容易看出傳遞的類型實參
應該是什麼:在調用方法的時候,不需要顯式聲明類型實參,:必須強調: 類型推斷只適用於泛型方法,不適用於類型,
比如上句:
List<string> list = MakeList<string>("Line 1", "Line 2");
可以簡單寫成: List<string> list = MakeList("Line 1", "Line 2");
//以泛型方式將一個給定的值和默認值進行比較: 給出的類型判斷和派生類型約束的實例:
class DefaultValueComparison
{
static int CompareToDefault<T>(T value)
where T : IComparable<T>
{
return value.CompareTo(default(T));
}
static void Main()
{
Console.WriteLine(CompareToDefault("x"));
Console.WriteLine(CompareToDefault(10));
Console.WriteLine(CompareToDefault(0));
Console.WriteLine(CompareToDefault(-10));
Console.WriteLine(CompareToDefault(DateTime.MinValue));
}
}
// // 如果一個類型參數被約束成值類型,就完全不能爲它使用==和!=,如果被約束成引用類型,那麼具體執行的比較完全
//取決於類型參數被約束成什麼類型,如果它只是一個引用類型,那麼執行的是簡單的引用比較,
//如果它進一步約束成一個重載了==和!=操作符指定的特定的類型派,就會使用重載的操作符
// 但要注意的是: 假如調用者指定的類型實參恰巧也進行了重載,那些額外的重載符號是不會使用的:
// 用==和!=進行引用比較
class OperatorOverloading
{
static bool AreReferencesEqual<T>(T first, T second)
where T : class
{
return first == second;
}
static void Main()
{
string name = "Jon";
string intro1 = "My name is " + name;
string intro2 = "My name is " + name;
Console.WriteLine(intro1 == intro2);
Console.WriteLine(AreReferencesEqual(intro1, intro2));
}
}
----作爲實現泛型:
// 作爲了“實現泛型”(實際上實現了中級泛型)這一主題結束,先面給出一個的例子:
//它實現了有用的泛型類型
[Description("Listing 3.06")]
//需要對值進行比較時,有兩個相當的有用的類,分別是: EqualityComparer:(適合對字典進行比較和哈希處理)和
// IComparer<T>(適合於排序)
//這兩個類的default屬性能返回一個實現,該實現都能爲特定的類型採取正確的(比較操作)
// EqualityComparer<T>的例子:
public sealed class Pair<TFirst, TSecond> : IEquatable<Pair<TFirst, TSecond>> // IEquatable<Pair<TFirst, TSecond>>支持排序
{
private static readonly IEqualityComparer<TFirst> FirstComparer =
EqualityComparer<TFirst>.Default;
private static readonly IEqualityComparer<TSecond> SecondComparer =
EqualityComparer<TSecond>.Default;
private readonly TFirst first;
private readonly TSecond second;
public Pair(TFirst first, TSecond second)
{
this.first = first;
this.second = second;
}
public TFirst First { get { return first; } }
public TSecond Second { get { return second; } }
public bool Equals(Pair<TFirst, TSecond> other)
{
return other != null &&
FirstComparer.Equals(this.First, other.First) &&
SecondComparer.Equals(this.Second, other.Second);
}
public override bool Equals(object o)
{
return Equals(o as Pair<TFirst, TSecond>);
}
public override int GetHashCode()
{
return FirstComparer.GetHashCode(first) * 37 +
SecondComparer.GetHashCode(second);
}
}
public static class Pair
{
public static Pair<TFirst, TSecond> Of<TFirst, TSecond>(TFirst first, TSecond second)
{
return new Pair<TFirst, TSecond>(first, second);
}
}
}
//高級泛型:
//靜態字段和靜態構造函數:
// 若在someclass中靜態字段x:不管創建多少個someclass實例,也不管派生多個類型,都只型號有一個someclass.x字段:
//它如何映射到泛型:
//不同的泛型都有它自己的靜態字段集
class StaticFieldPerClosedType
{
class TypeWithField<T>
{
public static string field;
public static void PrintField()
{
Console.WriteLine(field + ": " + typeof(T).Name);
}
}
static void Main()
{
TypeWithField<int>.field = "First";
TypeWithField<string>.field = "Second";
TypeWithField<DateTime>.field = "Third";
TypeWithField<int>.PrintField();
TypeWithField<string>.PrintField();
TypeWithField<DateTime>.PrintField();
}
}
//靜態字段和靜態構造函數:
// 若在someclass中靜態字段x:不管創建多少個someclass實例,也不管派生多個類型,都只型號有一個someclass.x字段:
//它如何映射到泛型:
//不同的泛型都有它自己的靜態字段集
class StaticFieldPerClosedType
{
class TypeWithField<T>
{
public static string field;
public static void PrintField()
{
Console.WriteLine(field + ": " + typeof(T).Name);
}
}
static void Main()
{
TypeWithField<int>.field = "First";
TypeWithField<string>.field = "Second";
TypeWithField<DateTime>.field = "Third";
TypeWithField<int>.PrintField();
TypeWithField<string>.PrintField();
TypeWithField<DateTime>.PrintField();
}
}
// 基本規則: 每個封閉類型有一個靜態字段”同樣的規則: 也適用於靜態初始化程序:
//和靜態構造函數
//--嵌套泛型類型的靜態構造函數:
class StaticConstructors
{
class Outer<T>
{
public class Inner<U, V>
{
static Inner()
{
Console.WriteLine("Outer<{0}>.Inner<{1},{2}>",
typeof(T).Name,
typeof(U).Name,
typeof(V).Name);
Console.ReadLine();
}
Inner()
{
Console.Write("執行構造函數的時候是不會執行構造函數");
Console.ReadLine();
}
public static void DummyMethod()
{
Console.WriteLine("print some th");
Console.ReadLine();
}
}
}
static void Main()
{
Outer<int>.Inner<string, DateTime>.DummyMethod();
Outer<string>.Inner<int, int>.DummyMethod();
Outer<object>.Inner<string, object>.DummyMethod();
Outer<string>.Inner<string, object>.DummyMethod();
Outer<object>.Inner<object, string>.DummyMethod();
Outer<string>.Inner<int, int>.DummyMethod();
}
}
}
//和任何類型一樣,靜態構造函數只執行一次:
泛型迭代:
class CountingEnumerableExample
{
class CountingEnumerable : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator() // 隱式實現”
{
return new CountingEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() //IEnumerable.GetEnumerator: IEnumerable接口名: 實現接口所規定的方法和屬時附加接口名作爲前綴,即稱爲”顯式接口實現“---
{
return GetEnumerator();
}
}
class CountingEnumerator : IEnumerator<int>
{
int current = -1;
public bool MoveNext()
{
current++;
return current < 10;
}
public int Current //隱式實現Current
{
get { return current; }
}
object IEnumerator.Current //IEnumerator.Current 顯式實現:
{
get { return Current; }
}
public void Reset()
{
throw new NotSupportedException();
}
public void Dispose()
{
}
}
static void Main()
{
CountingEnumerable counter = new CountingEnumerable();
foreach (int x in counter)
{
Console.WriteLine(x);
}
}
//
反射泛型方法:
//反射泛型方法:
class GenericMethodReflection
{
public static void PrintTypeParameter<T>()
{
Console.WriteLine (typeof(T));
}
static void Main()
{
Type type = typeof(GenericMethodReflection);
MethodInfo definition = type.GetMethod("PrintTypeParameter");
MethodInfo constructed;
constructed = definition.MakeGenericMethod(typeof(string));
constructed.Invoke(null, null);
}
}
.net2.0中的泛型集合類:
list<T>
dictionary<tkey,tvalue>
queue<t>
stact<t>
linkedlist<t>
協變性和逆變性的缺乏:
缺乏操作符約束或者"數值"約束: