.NET 4泛型中的Covariance和Contravariance

来源:网络 责任编辑:栏目编辑 发表时间:2013-07-01 13:04 点击:

在介绍.NET 4泛型的covariance和contravariance之前,先介绍下编程语言类型系统的variance的概念。简单的说covariance使得你能够用一个更具体的类来替代一个本该父层的类。在C#中,引用类型的数组是covariant的,这是从当时的Java中学来的特性,例如:

namespace variance2
{
    public class Animal { }
    public class Dog : Animal { }
    class Program
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Dog[10];
            animals[0] = new Animal();
        }
    }
}当给animals数组初始化的时候,可以使用它的子类Dog,这里是covariance的。这段代码可以编译通过,但是运行的时候会报如下错误:

Attempted to access an element as a type incompatible with the array.

因为一旦给数组赋值了Dog,实际上它就是一个Dog数组,所以不能再给他赋值Animal。一段能编译通过的代码再运行时发生类型错误并不是好事情,所以在.Net 2引入泛型的时候.net的泛型是invariant的。

List<Animal> listAnimals = new List<Dog>();这样是不能通过编译的。

List<Dog> listDogs = new List<Dog>();
listDogs.Add(new Animal());这样也不能通过编译。.NET2 这样做避免了一些问题,但同时也带来了一些问题,例如: List<Dog> listDogs = new List<Dog>();
IEnumerable<Animal> enumAnimals = listDogs;这样是不能编译通过的。实际上,这种编程场景很常见,而且事实上这是类型安全的,因为通过IEnumerable接口,我们只能从enumAnimals中获取值,而不能给他赋值。

 

下面举一个contravariance的例子:

public class Animal
   {
       public int Weight
       {
           get;set;
       }

       public string Name
       {
           get;set;
       }

       public Animal(string name,int weight)
       {
           Name=name; Weight=weight;
       }
   }
   public class Dog : Animal
   {
       public Dog(string name,int weight):base(name,weight)
       {
       }
   }

   public class WeightComparer : IComparer<Animal>
   {
       public int Compare(Animal x, Animal y)
       {
           return x.Weight - y.Weight;
       }
   }给动物类加上一个重量的属性,并且实现一个根据重量排序的IComparer类。

class Program
{
    static void Main(string[] args)
    {
        WeightComparer comparer = new WeightComparer();
        List<Animal> animals = new List<Animal>();
        animals.Add(new Animal("Dog", 4));
        animals.Add(new Animal("Mouse", 1));
        animals.Add(new Animal("Tiger",44));
        animals.Sort(comparer);   //works fine

    相关新闻>>

      发表评论
      请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
      用户名: 验证码:点击我更换图片
      最新评论 更多>>

      推荐热点

      • 浅析.NET下XML数据访问新机制
      • asp.net 面试+笔试题目第1/2页
      • C# 邮件地址是否合法的验证
      • asp.net 设置GridView的选中行的实现代码
      • C#高级编程:数据库连接[1]
      • 经典C++程序1
      • IIS 自动回收导致后台定时器失效的问题解决
      • ASP.NET&#160;GridView列表代码示例
      • Asp.net MVC源码分析--Action Filter的链式调用
      网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
      Copyright © 2008-2015 计算机技术学习交流网. 版权所有

      豫ICP备11007008号-1