zoukankan      html  css  js  c++  java
  • 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 }

        总结:我们可以在泛型约束的范围内,通过对泛型参数的类型进行判断和处理,这样在照顾到重用性的同时,也可以尽可能的提高程序的性能。

        
    作者:李潘
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    JAVA LinkedList和ArrayList的使用及性能分析
    学习笔记—Node中的模块调试
    学习笔记—Node的核心模块
    学习笔记—Node中VM模块详解
    学习笔记—Node中require的实现
    入园了
    【引用】asp.net服务器推送(ServerPush)和客户端拉拽技术
    ajax xmlHttp.responseXML取不到值问题备忘
    oracle实时插值速度突然变慢问题解决办法
    [转帖 作者: fuyuncat 来源: www.HelloDBA.com ]Oracle IO问题解析
  • 原文地址:https://www.cnblogs.com/wing011203/p/1691944.html
Copyright © 2011-2022 走看看