代码之家  ›  专栏  ›  技术社区  ›  Sasha

矛盾似乎会导致矛盾的行为

  •  1
  • Sasha  · 技术社区  · 17 年前

    以下示例取自 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一样工作呢 一串 不是

    2 回复  |  直到 8 年前
        1
  •  3
  •   itowlson    17 年前

    从概念上讲,Derived.CandidateAction的签名是“我可以处理你想扔给我的任何对象。”SampleDelegate的合同是“你必须能够处理字符串”。现在,如果一个方法可以处理任何对象,它肯定可以处理字符串。因此,Derived.CandidateAction能够满足SampleDelegate的需要,因此可以分配给SampleDelegate变量。

    http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html .

        2
  •  1
  •   Erv Walter    17 年前

    相反允许您使用具有参数的方法,这些参数是委托方法签名中参数的基本类型。

    委托签名定义将传递给方法的类型。方法本身可以具有不太“特定”的类型。在您的示例中,当传递字符串时调用委托。实际方法只需要一个对象是完全可以的,因为允许object类型的变量保存string类型的实例。

    这在事件处理场景中非常有用,您可以编写这样的事件处理程序,它可以附加到几乎任何事件(即使传递的args参数更具体,如ItemCheckedEventArgs):

    public void GenericHandler(object source, EventArgs args) {
        //do something generic
    }
    
    推荐文章