以下示例取自C# in Depth: What you need to master C# 2 and 3,似乎仅会导致jskeet确定的重大更改,但是是错误的。请解释:
delegate void SampleDelegate(string x);
public void CandidateAction (string x)
{
Console.WriteLine("Snippet.CandidateAction")
}
public class Derived: Snippet
{
public void CandidateAction (object x)
{
Console.WriteLine("Derived.CandidateAction")
}
}
....
Derived x = new Derived();
SampleDelegate factory = new SampleDelegate (x.CandidateAction);
factory ("test");
现在,为什么它应该一起工作,因为SampleDelegate接受字符串而不是对象。据我所知,对象不是从字符串派生的。相反。这就是c#2.0下的互逆性所允许的。似乎显示出相反的效果。
最佳答案
从概念上讲,Derived.CandidateAction的签名是说:“我可以处理要扔给我的任何物体。” SampleDelegate的合同为“您必须能够处理字符串”。现在,如果一个方法可以处理任何对象,那么它肯定可以处理字符串。因此,Derived.CandidateAction能够满足SampleDelegate的需求,因此可以将其分配给SampleDelegate变量。
我在http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html上对此进行了更详细的讨论(从C#4的角度来看)。