看了老师QQ签名,写下的一组类

[ 569 查看 / 3 回复 ]

  1.     class 学生 : IComparable<学生>
  2.     {
  3.         public string Name { get; set; }

  4.         #region IComparable<学生> 成员

  5.         public int CompareTo(学生 other)
  6.         {
  7.             return this.Name.CompareTo(other.Name);
  8.         }

  9.         #endregion
  10.     }

  11.     class 学生比较器 : Comparer<学生>
  12.     {

  13.         public override int Compare(学生 x, 学生 y)
  14.         {
  15.             return x.Name.CompareTo(y.Name);
  16.         }
  17.     }

  18.     class 学生Test
  19.     {
  20.         public 学生Test()
  21.         {
  22.             List<学生> list = new List<学生>();
  23.            
  24.             list.Sort(new 学生比较器());
  25.             list.Sort(new Comparison<学生>(new 学生比较器().Compare));
  26.             list.Sort((学生x, 学生y) => 学生x.Name.CompareTo(学生y.Name));
  27.         }
  28.     }
复制代码
1

评分次数

    TOP

    上面的写法,有冗余。。需要重构。。既然已经在定义类:学生 的时候,声明该类是 IComparable的。。那么,在 学生比较器 类中,就不应该再去写 x.Name.CompareTo(y.Name)。。而是应该直接写成: x.CompareTo(y)——直接调用 学生类 实现的IComparable接口 的公有方法。这是 接口 的作用。这跟 构造函数 重载时的道理,如出一辙。
    1.     class 学生 : IComparable<学生>
          {
              public string Name { get; set; }

              #region IComparable<学生> 成员

              public int CompareTo(学生 other)
              {
                  return this.Name.CompareTo(other.Name);
              }

              #endregion
          }

          class 学生比较器 : Comparer<学生>
          {

              public override int Compare(学生 x, 学生 y)
              {
                  return x.CompareTo(y);
              }
          }

          class 学生Test
          {
              public 学生Test()
              {
                  List<学生> list = new List<学生>();
                 
                  list.Sort(new 学生比较器());
                  list.Sort(new Comparison<学生>(new 学生比较器().Compare));
                  list.Sort((学生x, 学生y) => 学生x.CompareTo(学生y));
              }
          }
    复制代码
    TOP

    做几个非常有趣的实验:
    首先让 学生比较器 继承了Comparer<学生>之后,再去实现 IComparer<学生>
    1.     class 学生比较器 : Comparer<学生>, IComparer<学生>
    2.     {

    3.         public override int Compare(学生 x, 学生 y)
    4.         {
    5.             return x.CompareTo(y);
    6.         }


    7.     }
    复制代码
    这样会有什么效果呢?这就跟上次跟1002班板块那位同学提到的问题很相似。继承了Comparer<学生>,自然而然就实现了IComparer<学生>接口,做这个增加动作,甚至不需要更改任何代码,只管增加一个实现继承IComparer<学生>接口,即可。
    TOP

    然后把 Comparer<学生> 这个 抽象基类 删除,让 学生比较器 仅仅 实现 IComparer<学生>接口 。。你会发现,这时候,代码不能通过编译。。原因其实很好玩,那就是 override 这个关键字。。很明显,如果一个类只是实现了 接口,是不可能使用这个关键字的,必须删除该关键字。那么,如果,你实现了 接口 的这个公共方法,并且想让子类有机会重写的话,那个关键字应该是啥?
    1. class 学生比较器 : IComparer<学生>
    2.     {

    3.         public int Compare(学生 x, 学生 y)
    4.         {
    5.             return x.CompareTo(y);
    6.         }


    7.     }
    复制代码
    不用多考虑了,肯定应该是 virtual(中间垫一个 抽象基类 的话,抽象基类用 abstract,如果是非抽象的父类,正是该用 virtual)。。CLR对于 virtual 是很敏感的,对于 CLR 而言,virtual不virtual,那是两种不同的方法调用。
    TOP