C#2.0新增功能06 协变和逆变

在 C# 中,协变和逆变可以实现数组类型、委托类型和泛型类型参数的隐式引用转换。 协变保留分配兼容性,逆变则与之相反。html

如下代码演示分配兼容性、协变和逆变之间的差别。api

// 分配兼容性.   
string str = "test";  
// 将派生类型更高的对象分配给派生类型更低的对象  
object obj = str;  
  
IEnumerable<string> strings = new List<string>();  
// 用派生类型参数实例化的对象被分配给用派生类型参数实例化的对象。// 分配兼容性保持不变。  
IEnumerable<object> objects = strings;  
  
// 逆变.             
// 假设如下方法在类中:static void SetObject(object o) { }   
Action<object> actObject = SetObject;  
// 使用派生程度较低的类型参数实例化的对象被分配给使用派生程度较高的类型参数实例化的对象。// 分配兼容性被反转.   
Action<string> actString = actObject;

对方法组的协变和逆变支持容许将方法签名与委托类型相匹配。 这样,不只能够将具备匹配签名的方法分配给委托,还能够分配与委托类型指定的派生类型相比,返回派生程度更大的类型的方法(协变)或接受具备派生程度更小的类型的参数的方法(逆变)。 有关详细信息,请参阅委托中的变体 (C#)使用委托中的变体 (C#)数组

如下代码示例演示对方法组的协变和逆变支持。app

static object GetObject() { return null; }  
static void SetObject(object obj) { }  
  
static string GetString() { return ""; }  
static void SetString(string str) { }  
  
static void Test()  
{  
    // 协变. 委托将返回类型指定为对象,但能够指定返回字符串的方法。
    Func<object> del = GetString;  
  
    // 逆变. 委托将参数类型指定为字符串,但能够指定接受对象的方法。
    Action<string> del2 = SetObject;  
}

在 .NET Framework 4 或较新的 C# 中,支持在泛型接口和委托中使用协变和逆变,并容许隐式转换泛型类型参数。 有关详细信息,请参阅泛型接口中的变体 (C#)委托中的变体 (C#)《C#4.0新增功能03 泛型中的协变和逆变》ide

如下代码示例演示泛型接口的隐式引用转换。ui

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

若是泛型接口或委托的泛型参数被声明为协变或逆变,该泛型接口或委托则被称为“变体”。 凭借 C#,可以建立本身的变体接口和委托。 有关详细信息,请参阅建立变体泛型接口 (C#)委托中的变体 (C#)spa

Title 说明
泛型接口中的变体 (C#) 讨论泛型接口中的协变和逆变,提供 .NET Framework 中的变体泛型接口列表。
建立变体泛型接口 (C#) 演示如何建立自定义变体接口。
在泛型集合的接口中使用变体 (C#) 演示 IEnumerable<T> 接口和 IComparable<T> 接口中对协变和逆变的支持如何帮助重复使用代码。
委托中的变体 (C#) 讨论泛型委托和非泛型委托中的协变和逆变,并提供 .NET Framework 中的变体泛型委托列表。
使用委托中的变体 (C#) 演示如何使用非泛型委托中的协变和逆变支持以将方法签名与委托类型相匹配。
对 Func 和 Action 泛型委托使用变体 (C#) 演示 Func 委托和 Action 委托中对协变和逆变的支持如何帮助重复使用代码。

 

相关文章
相关标签/搜索