• 接口和委托的泛型可变性


    Before You Read:

    This article is ablout a branch of generic. Covariant and Contravariant. Generic first come up in C#2.0,in that time period. Generic variance is not support. It called invariant.

    Where should we use conravariant?

    ​ We can transform SomeType<Circle> to SomeType<IShape> when we use covariant. However, contravariant is opposite. It can transform SomeType<IShape to SomeType<Circle>.

    Only when SomeType describe return type parameter, covariant is safe.

    Only when SomeType describe accept type parameter, contravariant is safe.

    协变性和逆变性

    可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用。例如:若某方法声明返回类型为 Stream ,在实现时可以返回一个 MemoryStream。可变性应用于泛型接口和泛型委托的类型参数中。

    协变性

    ​ 协变性用于向调用者返回某项操作的值。

    interface IFactory<T>
      {
        T CreateFactoryInstance();
      }
    

    上述 T 仅作为返回值使用, 即方法的输出。

    逆变性

    ​ 逆变性指的是调用者向API传人值,API是在使用值,而不是产生值。

    interface IPrinter<T>
      {
        void Print(T document);
      }
    

    上述 T 只作为参数出现在接口的输入位置。

    还有一个就是 不变性, 这种类型称为 不变体 (invariant)

    在接口中使用可变性

    ​ 在泛型接口或委托的声明中,使用 out 修饰符来制定类型参数的 协变性, 使用 in 修饰符来指定 逆变性

    : 变体的转换是引用转换 任何使用了协变和逆变的转换都是引用转换,这意味着转换之后将返回相同的引用。它不会创建新的对象,只是认为现有引用与目标类型匹配。

    使用in 和out 表示可变性

    //Interface Example
    public interface IEnumerbale<out T>
    public interface IComparer<in T>
    

    如果类型参数只用于输出,就使用out; 如果只用于输入,就用in

    //A Demo for interface convarint
    
    List<Circle> aCircle = new List<Circle>
      {
          new Circle(new Point(0,0),15),
          new Circle(new Point(1,1),10)
      };
    
    List<Trangle> aTrangle = new List<Trangle>
      {
          new Trangle(new Point(1,1),2),
          new Trangle(new Point(2,2),3)
      };
    

    接口的协变性

    List<IShape> shapes = new List<IShape>();
    shapes.AddRange(aCircle);
    shapes.AddRange(aTrangle);
    
    List<IShape> shapesAll = aCircle.Contact<IShape>(aTrangle).ToList();
    

    接口的逆变性

    class AreaComparer : IComparer<IShape>
      {
        public int Compare(IShape x, IShape y){
          return x.Area.CompareTo(y.area);
        }
      }
    

    在委托中使用可变性

    delegate T Func<out T>()
    delegate void Action<in T>(T obj)
    
    //使用Func<T> 和 Action<T>委托演示可变性
    Func<Trangle> TrangleFactory = () => new Trangle(new Point(1,1),2);
    Func<IShape> shapeFactory = TrangleFactory;
    
    Action<IShape> shapePrinter = shape => Console.WriteLine(shape.area);
    Action<Trangle> TranglePrinter = shapePrinter;
    
    shapePrinter(shapeFactory());
    TranglePrinter(TrangleFactory());
    
  • 相关阅读:
    生成组合算法
    今天复习C++的const,又学到了很多内容,总结一下[原创]
    文字和图片在一行,文字靠左,图片靠右(div)[转]
    联合查询
    排序查询
    分页查询 ★
    分组查询
    基础查询
    条件查询
    连接查询 (二)sql99语法
  • 原文地址:https://www.cnblogs.com/xiyin/p/7295991.html
Copyright © 2020-2023  润新知