我很难理解如何在现实世界中使用协变和逆变。
到目前为止,我看到的唯一示例是相同的旧数组示例。
object[] objectArray = new string[] { "string 1", "string 2" };
如果我能看到它在其他地方使用,那么很高兴看到一个允许我在开发过程中使用它的示例。
假设您有一个 Person 类和一个派生自它的类 Teacher。您有一些以 anIEnumerable<Person>作为参数的操作。在您的 School 课程中,您有一个返回IEnumerable<Teacher>. 协方差允许您直接将该结果用于采用 的方法,将IEnumerable<Person>派生程度更高的类型替换为派生程度较低(更通用)的类型。与直觉相反,逆变允许您使用更通用的类型,其中指定了更派生的类型。
IEnumerable<Person>
IEnumerable<Teacher>
另请参阅MSDN 上泛型中的协变和逆变。
课程 :
public class Person { public string Name { get; set; } } public class Teacher : Person { } public class MailingList { public void Add(IEnumerable<out Person> people) { ... } } public class School { public IEnumerable<Teacher> GetTeachers() { ... } } public class PersonNameComparer : IComparer<Person> { public int Compare(Person a, Person b) { if (a == null) return b == null ? 0 : -1; return b == null ? 1 : Compare(a,b); } private int Compare(string a, string b) { if (a == null) return b == null ? 0 : -1; return b == null ? 1 : a.CompareTo(b); } }
用法 :
var teachers = school.GetTeachers(); var mailingList = new MailingList(); // Add() is covariant, we can use a more derived type mailingList.Add(teachers); // the Set<T> constructor uses a contravariant interface, IComparer<in T>, // we can use a more generic type than required. // See https://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx for declaration syntax var teacherSet = new SortedSet<Teachers>(teachers, new PersonNameComparer());