《C#入门到精通》学习笔记 -- 逆变接口与协变接口

不是很懂,先转一片看似不错的博客。

http://www.cnblogs.com/luminji/archive/2010/09/12/1824487.html

 

本章概要:
1:协变与逆变概念
2:协变
3:逆变
4:注意事项
5:接口变体语法

 

1:逆变与协变概念
    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。
    “逆变”则是指能够使用派生程度更小的类型。
     如果泛型接口或委托的泛型参数声明为协变或逆变,则将该泛型接口或委托称为“变体”。

 

2:协变
     查看下面代码:

IEnumerable<String> strings = new List<String>(); 
IEnumerable<Object> objects = strings;

 

     在 .NET Framework 早期版本中,在 Option Strict On 条件下,此代码会导致 C# 和 Visual Basic 中出现编译错误。但是现在,您可以使用 strings 代替 objects,如上例所示,因为 IEnumerable<(Of <(T>)>) 接口为协变接口。

 

3:逆变
     逆变允许方法具有与接口的泛型形参所指定的实参类型相比,派生程度更小的实参类型。为展示逆变功能,假设您已创建 BaseComparer 类来比较 BaseClass 类的实例。BaseComparer 类实现 IEqualityComparer<BaseClass>(在 Visual Basic 中为 IEqualityComparer(Of BaseClass))接口。因为 IEqualityComparer<(Of <(T>)>) 接口现在为逆变接口,所以您可以使用 BaseComparer 来比较继承 BaseClass 类的类的实例。以下代码示例中演示了这一点。

// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }

// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass> 
{
    public int GetHashCode(BaseClass baseInstance)
    {
        return baseInstance.GetHashCode();
    }
    public bool Equals(BaseClass x, BaseClass y)
    {
        return x == y;
    }
}
class Program
{
    static void Test()
    {
        IEqualityComparer<BaseClass> baseComparer = new BaseComparer();

        // Implicit conversion of IEqualityComparer<BaseClass> to 
        // IEqualityComparer<DerivedClass>.
        IEqualityComparer<DerivedClass> childComparer = baseComparer;
    }
}

 

4:注意事项

    有引用类型才支持使用泛型接口中的变体。值类型不支持变体。 实现变体接口的类仍是固定类。例如,虽然 List<(Of <(T>)>) 实现协变接口 IEnumerable<(Of <(T>)>),但无法将 List<string>.

// The following line generates a compiler error
// because classes are invariant.
// List<Object> list = new List<String>();

// You can use the interface object instead.
IEnumerable<Object> listObjects = new List<String>();

 

5:接口变体语法
     若要声明变体泛型接口,可以对泛型类型参数使用 in 和 out 关键字。
     您可以使用 out 关键字,将泛型类型参数声明为协变。
     您可以使用 in 关键字,将泛型类型参数声明为逆变。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值