More Effective C# Item3 : 运行时检查泛型参数的类型并提供特定的算法
??? 我感覺這一條目應該算是對Item2的補充,還是在“約束”的條件下,如何使得程序得到最優化的結果,頗有“帶著腳銬跳芭蕾”的意味。Item2中的條目可以看做是在有約束的情況下,對泛型類外部的影響;本條目可以看做是對泛型內部的影響。
??? 通常情況下,.NET框架,或者我們自身針對不同項目制定的框架,都會包含一系列的接口或者基類,接口或者基類之間,會有繼承的關系,形成一個系統的骨架,在此基礎上根據具體的業務,對框架進行填充,使得最終的系統才會有血有肉。
??? 在設計泛型類時,如果指定的“約束”是很寬泛的“約束”,即從類型層次結構上來看,“約束”指定的類型包含了子類型。那么可以在編寫泛型方法時,對泛型參數的類型進行判斷,如果該參數的類型屬于某一種特定的類型(這里的特定類型一定會是泛型類型的子類型),那么就可以調用特定類型的方法,從而可以充分利用子類型的特點。
??? 我們還是使用《More Effective C#》中提供的示例進行說明吧,來看下面的代碼。
代碼 1 public sealed class ReserseEnumerable<T> : IEnumerable<T>
2 {
3 private class ReserseEnumerator : IEnumerator<T>
4 {
5 int currentIndex;
6 IList<T> collection;
7 public ReserseEnumerator(IList<T> srcCollection)
8 {
9 collection = srcCollection;
10 currentIndex = collection.Count;
11 }
12
13 #region IEnumerator<T> Members
14
15 public T Current
16 {
17 get { return collection[currentIndex]; }
18 }
19
20 #endregion
21
22 #region IDisposable Members
23
24 public void Dispose()
25 {
26
27 }
28
29 #endregion
30
31 #region IEnumerator Members
32
33 object IEnumerator.Current
34 {
35 get { return this.Current; }
36 }
37
38 public bool MoveNext()
39 {
40 return --currentIndex >= 0;
41 }
42
43 public void Reset()
44 {
45 currentIndex = collection.Count;
46 }
47
48 #endregion
49 }
50
51 IEnumerable<T> sourceSequence;
52 public IList<T> originalSequence;
53
54 public ReserseEnumerable(IEnumerable<T> sequence)
55 {
56 sourceSequence = sequence;
57 }
58 #region IEnumerable<T> Members
59
60 public IEnumerator<T> GetEnumerator()
61 {
62 if (originalSequence == null)
63 {
64 originalSequence = new List<T>();
65 foreach (T item in sourceSequence)
66 {
67 originalSequence.Add(item);
68 }
69 }
70 return new ReserseEnumerator(originalSequence);
71 }
72
73 #endregion
74
75 #region IEnumerable Members
76
77 IEnumerator System.Collections.IEnumerable.GetEnumerator()
78 {
79 return this.GetEnumerator();
80 }
81
82 #endregion
83 } ??? 上述代碼實現了一個對列表進行反轉的功能,它指定的“約束”是比較寬泛的,在代碼中,并沒有對泛型參數的類型再做進一步的判斷和處理。
??? 這里有必要說明一點,上面的代碼是沒有錯誤的,對于使用者來說,它從最大程度上開放了“約束”。但是在內部實現方面,我們還可以做以下優化,來看一下IReserseEnumerable<T>的構造函數,我們可以對其進行以下改動。
代碼 1 public ReverseEnumerable(IEnumerable<T> sequence)
2 {
3 sourceSequence = sequence;
4 // If sequence doesn't implement IList<T>,
5 // originalSequence is null, so this works
6 // fine.
7 originalSequence = sequence as IList<T>;
8 }
9
10 public ReverseEnumerable(IList<T> sequence)
11 {
12 sourceSequence = sequence;
13 originalSequence = sequence;
14 } ??? 對于GetEnumerator<T>方法來說,我們可以對其進行以下改動。
代碼 1 public IEnumerator<T> GetEnumerator()
2 {
3 // Create a copy of the original sequence,
4 // so it can be reversed.
5 if (originalSequence == null)
6 {
7 if (sourceSequence is ICollection<T>)
8 {
9 ICollection<T> source = sourceSequence
10 as ICollection<T>;
11 originalSequence = new List<T>(source.Count);
12 }
13 else
14 originalSequence = new List<T>();
15 foreach (T item in sourceSequence)
16 originalSequence.Add(item);
17 }
18 return new ReverseEnumerator(originalSequence);
19 }
?
??? 總結:我們可以在泛型約束的范圍內,通過對泛型參數的類型進行判斷和處理,這樣在照顧到重用性的同時,也可以盡可能的提高程序的性能。
轉載于:https://www.cnblogs.com/wing011203/archive/2010/03/22/1691944.html
總結
以上是生活随笔為你收集整理的More Effective C# Item3 : 运行时检查泛型参数的类型并提供特定的算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《监控》书评
- 下一篇: js时断时续————动态参数传递