C#泛型中的抗变和协变

在.net4之前,泛型接口是不变的。.net4通过协变和抗变为泛型接口和泛型委托添加了一个重要的拓展

1、抗变:如果泛型类型用out关键字标注,泛型接口就是协变的。这也意味着返回类型只能是T。

 实例:

 1 static void Main(string[] args)
 2         {
 3             IIndex<Rectangle> rectangles = RectangleCollection.GetRectangles();
 4             IIndex<Shape> shapes = rectangles;        
 5             Console.ReadKey();
 6         }
 7 
 8 
 9 public interface IIndex<out T>
10     {
11         T this[int index] { get; }
12         int Count { get; }
13     }
14     public class RectangleCollection : IIndex<Rectangle>
15     {
16         private Rectangle[] data = new Rectangle[3]
17         {
18             new Rectangle{Width=2,Height=3},
19             new Rectangle{Width=3,Height=7},
20             new Rectangle{Width=4.5,Height=2.9}
21         };
22         private static RectangleCollection coll;
23 
24         public static RectangleCollection GetRectangles()
25         {
26             return coll ?? (coll = new RectangleCollection());
27         }
28         public Rectangle this[int index]
29         {
30             get
31             {
32                 if (index < 0 || index > data.Length)
33                 {
34                     throw new ArgumentOutOfRangeException("index");
35                 }
36                 return data[index];
37             }
38         }
39         public int Count
40         {
41             get
42             {
43                 return data.Length;
44             }
45         }
46     }
47     public class Shape
48     {
49         public double Width { get; set; }
50         public double Height { get; set; }
51         public override string ToString()
52         {
53             return String.Format("width:{0},height:{1}", Width, Height);
54         }
55     }
56     public class Rectangle : Shape
57     {
58 
59     }
View Code

2、抗变:如果泛型类型用in关键字,泛型接口就是抗变得。这样,接口的只能把泛型类型T用作方法的输入

 实例:

static void Main(string[] args)
        {
            IIndex<Rectangle> rectangles = RectangleCollection.GetRectangles();        
            IDisplay<Shape> shapeDisplay = new ShapeDisplay();
            IDisplay<Rectangle> rectangleDisplay = shapeDisplay;
            rectangleDisplay.Show(rectangles[0]);
            Console.ReadKey();
        }

public interface IDisplay<in T>
    {
        void Show(T item);
    }
    public class ShapeDisplay : IDisplay<Shape>
    {
        public void Show(Shape item)
        {
            Console.WriteLine("{0} width:{1},height:{2}", item.GetType().Name, item.Width, item.Height);
        }
    }
View Code

猜你喜欢

转载自www.cnblogs.com/minrh/p/9460612.html