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

ActionDelegate、Generics、CovarianceandContravariance分享

时间:2023-04-10 22:20:05 C#

ActionDelegate、Generics、CovarianceandInversion我有两个业务合约类:publicBusinessContractpublicPerson:BusinessContract在另一个类中,我有如下代码:privateAction_foo;publicvoidFoo(Actionbar)whereT:BusinessContract{_foo=bar;上面甚至没有编译,这让我很困惑。我将T限制为BusinessContract,为什么编译器不知道bar可分配给_foo?为了解决这个问题,我们尝试将其更改为以下内容:publicvoidFoo(Actionbar)whereT:BusinessContract{_foo=(Action)bar;现在编译器很高兴,所以我在我的应用程序的其他地方编写了以下代码:Foo(p=>p.Name="Joe");该应用程序在运行时因InvalidCastException而崩溃。我不明白。我不应该能够将更具体的类型转换为不太具体的类型并分配它吗?更新乔恩回答了这个问题,所以得到了点头,但只是为了结束循环,这就是我们最终解决问题的方式。私人行动_foo;publicvoidFoo(Actionbar)whereT:BusinessContract{_foo=contract=>bar((T)contract);}我们为什么要这样做呢?我们有一个用于单元测试的假DAL。使用其中一种方法,我们需要让测试开发人员能够指定在测试期间调用方法时应该发生什么(这是一种从数据库更新缓存对象的刷新方法)。Foo的目的是设置调用刷新时应该发生的事情。IOW,在本课程的其他地方,我们有以下内容。publicvoidRefresh(BusinessContractcontract){if(_foo!=null){_foo(contract);例如,测试开发人员可以决定在调用Refresh时将名称设置为不同的值。Foo(p=>p.Name="新名字");你的协变和逆变是错误的。让我们考虑一下Action和Action。删除实际的泛型,你正在尝试做这样的事情:privateAction_foo;publicvoidFoo(Actionbar){//这不会编译..._foo=bar;现在假设我们写:_foo(newButton());这无关紧要,因为Action可以传递给任何对象……但我们使用必须采用字符串参数的委托对其进行初始化。哎哟。这不是类型安全的,因此无法编译。另一种可行的方法:privateAction_foo;publicvoidFoo(Actionbar){//这很好..._foo=bar;现在当我们调用_foo时,我们必须传入一个字符串——但这没关系,因为我们用一个委托初始化它,它可以将任何对象引用作为参数,我们恰好给它一个字符串。所以基本上Action是逆变的-而Func是协变的:Funcbar=...;功能foo=酒吧;//这是一个很好的对象x=foo();//到目前为止这肯定没问题目前还不清楚你想用这个动作做什么,所以不幸的是我不能就如何解决这个问题给出任何建议......它不能被分配因为你正在使用逆变而不是协变,不能保证您可以分配分配给foo的泛型类型。以上就是C#学习教程的全部内容:动作表示、仿制药、协方差和反转共享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,并不代表侵权,如有侵权,请点击右边联系管理员删除。如需转载请注明出处: