更新:
糟糕。事实证明,我在最初的回答中混合了方差和“分配兼容性”。相应地编辑了答案。我也写了一篇博客文章,希望可以更好地回答这样的问题:协方差和协方差常见问题
答: 我想您第一个问题的答案是,在此示例中您没有矛盾:
bool Compare(Mammal mammal1, Mammal mammal2); Mammal mammal1 = new Giraffe(); //covariant - no Mammal mammal2 = new Dolphin(); //covariant - noCompare(mammal1, mammal2); //covariant or contravariant? - neither //or Compare(new Giraffe(), new Dolphin()); //covariant or contravariant? - neither
此外,这里甚至没有协方差。您拥有的称为“分配兼容性”,这意味着您始终可以将派生程度更高的实例分配给派生程度较小的实例。
在C#中,数组,委托和通用接口均支持方差。正如埃里克·利珀特(Eric
Lippert)在其博客文章中所说的那样,协方差和赋值兼容性之间有何区别?最好将方差视为类型的“投影”。
协方差更容易理解,因为它遵循分配兼容性规则(可以将派生类型更多的数组分配给派生类型较少的数组“ object [] objs = new string
[10];”)。逆差逆转了这些规则。例如,假设您可以执行类似“ string [] strings = new object
[10];”的操作。当然,由于明显的原因,您不能执行此操作。但这将是协变的(但同样,数组不是协变的,它们仅支持协方差)。
以下是MSDN的示例,希望可以向您展示矛盾的真正含义(我现在拥有这些文档,因此,如果您认为文档中尚不清楚,请随时给我反馈):
在通用集合的接口中使用差异
Employee[] employees = new Employee[3];
// You can pass PersonComparer,
// which implements IEqualityComparer,
// although the method expects IEqualityComparer.
IEnumerablenoduplicates =
employees.Distinct(new PersonComparer()); 在代表中使用差异
// Event hander that accepts a parameter of the EventArgs type.
private void MultiHandler(object sender, System.EventArgs e)
{
label1.Text = System.DateTime.Now.ToString();
}
public Form1()
{
InitializeComponent();
// You can use a method that has an EventArgs parameter,
// although the event expects the KeyEventArgs parameter.
this.button1.KeyDown += this.MultiHandler;
// You can use the same method
// for an event that expects the MouseEventArgs parameter.
this.button1.MouseClick += this.MultiHandler;
}将方差用于函数和动作通用委托
static void AddToContacts(Person person)
{
// This method adds a Person object
// to a contact list.
}// The Action delegate expects
// a method that has an Employee parameter,
// but you can assign it a method that has a Person parameter
// because Employee derives from Person.
ActionaddEmployeeToContacts = AddToContacts;
希望这可以帮助。



