小编典典

协方差和逆变现实世界的例子

all

我很难理解如何在现实世界中使用协变和逆变。

到目前为止,我看到的唯一示例是相同的旧数组示例。

object[] objectArray = new string[] { "string 1", "string 2" };

如果我能看到它在其他地方使用,那么很高兴看到一个允许我在开发过程中使用它的示例。


阅读 72

收藏
2022-07-29

共1个答案

小编典典

假设您有一个 Person 类和一个派生自它的类 Teacher。您有一些以 anIEnumerable<Person>作为参数的操作。在您的
School 课程中,您有一个返回IEnumerable<Teacher>. 协方差允许您直接将该结果用于采用
的方法,将IEnumerable<Person>派生程度更高的类型替换为派生程度较低(更通用)的类型。与直觉相反,逆变允许您使用更通用的类型,其中指定了更派生的类型。

另请参阅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());
2022-07-29