zoukankan      html  css  js  c++  java
  • 13.3.2 在接口中使用可变性

    1. 用 in 和 out 表示可变性

    我们使用的两个接口是 IEnumerable<T> (对于 T 是协变的)和 IComparer<T> (对于 T 是逆变的),它们可以很好地展示可变性。以下是它们在.NET 4中的声明:

        public interface IEnumerable<out T>
        public interface IComparer<in T>

    这非常好记:如果类型参数只用于输出,就使用 out ;如果只用于输入,就用 in 。编译器可不知道你是否记住了哪种形式是协变,哪种形式是逆变。

     1     public interface IShape
     2     {
     3         double Area { get; }
     4 
     5         System.Windows.Rect BoundingBox { get; }
     6     }
     7     /// <summary>
     8     /// WindowsBase.dll下
     9     /// </summary>
    10     public sealed class Circle : IShape
    11     {
    12         private readonly System.Windows.Point center;
    13         public System.Windows.Point Center { get { return center; } }
    14 
    15         private readonly double radius;
    16         public double Radius { get { return radius; } }
    17 
    18         public Circle(System.Windows.Point center, int radius)
    19         {
    20             this.center = center;
    21             this.radius = radius;
    22         }
    23 
    24         public double Area
    25         {
    26             get { return Math.PI * radius * radius; }
    27         }
    28 
    29         public System.Windows.Rect BoundingBox
    30         {
    31             get
    32             {
    33                 return new System.Windows.Rect(center - new System.Windows.Vector(radius, radius), new System.Windows.Size(radius * 2, radius * 2));
    34             }
    35         }
    36     }
    37     public sealed class Square : IShape
    38     {
    39         private readonly Point topLeft;
    40         private readonly double sideLength;
    41 
    42         public Square(Point topLeft, double sideLength)
    43         {
    44             this.topLeft = topLeft;
    45             this.sideLength = sideLength;
    46         }
    47 
    48         public double Area { get { return sideLength * sideLength; } }
    49 
    50         public Rect BoundingBox
    51         {
    52             get { return new Rect(topLeft, new Size(sideLength, sideLength)); }
    53         }
    54     }
    View Code

    2. 接口的协变性

     1             List<Circle> circles = new List<Circle>()
     2             {
     3                 new Circle(new Point(0, 0), 15),
     4                 new Circle(new Point(10, 5), 20),
     5             };
     6             List<Square> squares = new List<Square>()
     7             {
     8                 new Square(new Point(5, 10), 5),
     9                 new Square(new Point(-10, 0), 2),
    10             };
    11 
    12             List<IShape> shapesByAdding = new List<IShape>();
    13             shapesByAdding.AddRange(circles);
    14             shapesByAdding.AddRange(squares);
    15             List<IShape> shapesByConcat = circles.Concat<IShape>(squares).ToList();

    实际上,代码清单13-12在4个地方使用了协变性,对于类型系统而言,每次将圆形或方形序列转换为普通几何形状时,都用到了协变性。
    首先新建了一个 List<IShape> ,并调用 AddRange向其添加圆形和方形列表 。(我们也可以向构造函数传递一个列表,然后调用 AddRange 一次。)
    List<T>.AddRange 的参数为 IEnumerable<T> 类型,因此在这种情况下我们将这两个列表都看成是 IEnumerable<IShape> ,而这在以前是不被允许的。

    3. 接口的逆变性

     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             List<Circle> circles = new List<Circle>()
     6             {
     7                 new Circle(new Point(0, 0), 15),
     8                 new Circle(new Point(10, 5), 20),
     9             };
    10             List<Square> squares = new List<Square>()
    11             {
    12                 new Square(new Point(5, 10), 5),
    13                 new Square(new Point(-10, 0), 2),
    14             };
    15 
    16             IComparer<IShape> areaComparer = new AreaComparer();
    17             circles.Sort(areaComparer);
    18         }
    19     }
    20     class AreaComparer : IComparer<IShape>
    21     {
    22         public int Compare(IShape x, IShape y)
    23         {
    24             return x.Area.CompareTo(y.Area);
    25         }
    26     }
  • 相关阅读:
    BEC listen and translation exercise 44
    中译英12
    BEC listen and translation exercise 43
    中译英11
    BEC listen and translation exercise 42
    中译英10
    BEC listen and translation exercise 41
    中译英9
    BEC listen and translation exercise 40
    中译英8
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/10105698.html
Copyright © 2011-2022 走看看