以下示例取自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的角度来看)。

08-19 03:49