当前位置: 首页 > 编程语言 > C#

表示协方差混沌问题!分享

时间:2023-04-10 21:39:35 C#

代表协方差混淆谜题!为什么这不起作用?我没有正确理解代表性协方差吗?publicdelegatevoidMyDelegate(objectobj)publicclassMyClass{publicMyClass(){//错误:预期方法带有'voidMyDelegate(object)'签名_delegate=MyMethod;私人MyDelegate_delegate;publicvoidMyMethod(SomeObjectobj){}}正确-你没有正确理解协方差-但如果你有相同的类型但返回值如下,你的代码将工作:publicdelegateobjectMyDelegate()publicclassMyClass{publicMyClass(){_delegate=MyMethod;私人MyDelegate_delegate;publicSomeObjectMyMethod(){返回空值;这将证明协方差。或者,您可以将其保留为参数,但切换类型:publicdelegatevoidMyDelegate(SomeObjectobj)publicclassMyClass{publicMyClass(){_delegate=MyMethod;私人MyDelegate_delegate;publicvoidMyMethod(objectobj){}}这现在显示出赤字。我的经验法则是问自己,“给定委托,我能用它做什么?如果我可以传入一个会破坏方法的参数,转换应该失败。如果方法可以返回一些会破坏其调用者的东西,转换应该会失败。“在你的代码中,你可以调用:_delegate(newobject());在这一点上,可怜的MyMethod有一个参数是SomeObject类型,但实际上是对象类型。这将是一件非常糟糕的事情,所以编译器阻止它发生。这一切更有意义吗?参数是逆变的,返回类型是协变的。如果您使用不是SomeObject实例的对象调用委托,则会出现错字。另一方面,返回SomeObject从包装在返回对象的委托中的例程很好。您需要使用泛型。编辑:为什么?因为,正如另一位海报所指出的,Object和SomeObject不等同于Object可能不是SomeObject。这就是重点语言中的泛型。publicdelegatevoidMyDelegate(Tobj)publicclassMyClass{publicMyClass(){_delegate=MyMethod;}privateMyDelegate_delegate;publicvoidMyMethod(SomeObjectobj){}}MyDelegate类型声明你可以通过任何类型的对象。但是,MyMethod只接受SomeObject类型的SomeObject。如果我尝试调用传递不同类型对象的委托会发生什么:_delegate("astringobject")?根据MyDelegate的声明,这应该是允许的,但是YourfunctionMyMethod实际上不能接收字符串参数。从您提供的MSDN链接,Covariance允许方法具有比委托中定义的更多的派生返回类型。逆变允许具有派生类型少于委托类型的参数类型的方法。您正在尝试使用更多不受支持的派生参数类型(尽管.NET4.0可能会解决许多协变/逆变问题)。协变和反转是关于理解继承的原则。在协变和逆变中,s.th.被“传递”,作为返回值或作为委托方法的参数。“通过”的东西必须在容器中“捕获”。在C#或编程术语本身中,我们使用bucket这个词来表示我所说的套接字。有时你必须回到其他单词才能理解常见行话的含义。无论如何,如果您了解继承,这可能是这里的任何读者,那么唯一需要注意的是容器,即用于捕获的桶必须是与正在进行的类型相同或更少的派生类型。通过-对于协变和逆变都是如此。Heritage说你可以用动物桶抓鸟,因为鸟是动物。所以如果一个方法的参数要抓一只鸟,你就把它抓到动物桶里(Animal类型的参数),这就是倒置。如果你的方法,也就是你的委托,返回的是一只鸟,那么“桶”也可以是一种鸟的类型或者派生较少的(父类型),这意味着你捕获方法返回值的变量必须是相同的或者较少的派生类型作为返回值。只需改变您的想法以区分正在传递的内容和正在捕获的内容,所有关于协变和逆变的复杂性都会被很好地消除。然后你意识到同样的原则在起作用。正因为它只以一种方式流动,所以不能违反继承。编译器非常聪明,当您将存储桶转换为更专门的类型时(再次并根据需要),只有这样您才能将所有专门的方法添加到更多的派生类中。这就是它的美妙之处。所以它是捕获、投射和使用您拥有的以及您可能需要的东西。以上就是C#学习教程:代表性协方差混淆问题!如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: