问题标签 [generic-variance]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - C# 4.0 中如何实现泛型协方差和逆变换?
我没有参加 PDC 2008,但我听说 C# 4.0 宣布支持通用协变和逆变换的消息。也就是说,List<string>
可以分配给List<object>
。怎么可能?
在 Jon Skeet 的C# in Depth一书中,解释了为什么 C# 泛型不支持协变和逆变。它主要用于编写安全代码。现在,C# 4.0 更改为支持它们。会不会带来混乱?
有人知道有关 C# 4.0 的详细信息可以给出一些解释吗?
.net-4.0 - C# 4.0 中的泛型变体
C# 4.0 中的 Generic Variance 的实现方式使得可以毫无例外地编写以下内容(这在 C# 3.0 中会发生):
[示例非功能性:参见 Jon Skeet 的回答]
我最近参加了一个会议,Jon Skeet 对通用方差进行了出色的概述,但我不确定我是否完全理解它 - 我理解in
和out
关键字在反方差和协方差方面的重要性,但我很好奇幕后发生的事情。
执行此代码时,CLR 会看到什么?它是隐式转换List<int>
为List<object>
还是简单地内置,我们现在可以在派生类型之间转换为父类型?
出于兴趣,为什么在以前的版本中没有引入它,主要的好处是什么 - 即现实世界的使用?
有关通用差异的这篇文章的更多信息(但问题非常过时,正在寻找真实的最新信息)
c# - 类层次结构问题(具有泛型的差异!)
问题:
假设IList
返回的是只读的,我知道我想要实现的是安全的(或者不是?)。有什么办法可以完成我正在尝试的事情吗?我不想尝试自己实现TasksChain
算法(再次!),因为它容易出错并且会导致代码重复。也许我可以定义一个抽象链,然后从那里实现TasksChain
两者StatesChain
?或者也许实现一个Chain<T>
类?
您将如何处理这种情况?
详细信息:
我定义了一个ITask
接口:
和一个IState
继承自的接口ITask
:
我还定义了一个IHasTasksList
接口:
和一个IHasStatesList
:
现在,我定义了一个TasksChain
,这是一个具有一些代码逻辑的类,可以操作一系列任务(请注意,TasksChain
它本身就是一种ITask
!):
我正在实施State
以下方式:
如您所见,它使用显式接口实现来“隐藏”FailureTask
而不是显示FailureState
属性。
问题来自这样一个事实,即我还想定义 a StatesChain
,它继承自IState
and IHasStateList
(并且它也实现ITask
and IHasTaskList
,实现为显式接口)并且我希望它也隐藏IHasTaskList
'sTasks
并且只显示IHasStateList
's States
。(“问题”部分中包含的内容应该在此之后,但我认为把它放在第一位会更便于读者阅读)。
(pff..长文本)谢谢!
c# - C# Delegate under the hood 问题
在阅读了 SO 中的以下问题后,我正在研究委托差异:Delegate.CreateDelegate() and generics: Error binding to target method
我在https://www.blogger.com/comment.g?blogID=8184237816669520763&postID=2109708553230166434从 Barry kelly 那里找到了一段非常好的代码
在这里(以糖化形式:-)
除了这一行(看起来很简单)之外,我都了解。
b = a.调用;// 使用方差分配委托的简单方法,虽然增加了间接层
谁能告诉我:
- 如何在不传递静态函数所需的参数的情况下调用调用。
- 当您从调用调用分配返回值时,何时在幕后发生
- 巴里所说的额外间接是什么意思(在他的评论中)
c#-4.0 - 使用懒惰的问题从通用抽象类中
我有一个泛型类,我的所有 DAO 类都从该类派生,定义如下。我的所有实体也都有一个基类,但这不是通用的。
该方法GetIdOrSave
将与我定义的类型不同SabaAbstractDAO
,因为我试图获取主键来满足外键关系,所以这个函数要么获取主键,要么保存实体,然后获取主键钥匙。
最后一个代码片段有一个解决方案,如果我去掉通用部分,它将如何工作,所以我认为这可以通过使用方差来解决,但我不知道如何编写一个可以编译的接口。
当我尝试编译时出现此错误:
我试图这样称呼它:
如果我将定义更改为此,它会起作用。
那么,如何使用方差(如果需要)和泛型来编译它,这样我就可以有一个非常通用的方法,只适用于BaseModel
and AbstractDAO<BaseModel>
?我希望我只需要在方法和抽象类定义中进行更改,用法应该没问题。
更新: 有一个非常有用的回应,我有一个稍微改进的例子,但一个有趣的困境:
我现在已经定义了这个,并且我没有任何in
or out
on T这里因为我得到了矛盾的错误,如果out T
我得到它必须是contravariantly valid
并且如果in T
then covariantly valid
,所以我使它保持不变,因为它似乎 VS2010 无法计算出来。
我收到此错误,尽管它确实编译了:
我修复了上面的两个代码片段,但似乎方差不会像我希望的那样起作用。
我试过这个:
但是我遇到了与界面相同的问题,如果我把out
它抱怨,那么我就提出in
了相反的抱怨。
如果这是合法的,我想我可以让它工作:
scala - 如何确定类型参数的方差?
受到Scala中协变和逆变的真实示例的启发,我认为一个更好的问题是:
在设计库时,在确定类型参数应该是协变还是逆变时,是否应该问自己一组特定的问题?还是应该让所有内容保持不变,然后根据需要进行更改?
c# - 自定义 Autofac 的组件分辨率/具有通用协变/逆变的问题
首先,对于模糊的问题标题感到抱歉。我想不出更精确的。
鉴于这些类型:
我想编写一个Dispatch
接受任何命令并将其发送到适当的ICommandHandler<>
. 我认为使用 DI 容器(Autofac)可能会大大简化从命令类型到命令处理程序的映射:
假设 DI 容器知道上面显示的所有类型。现在我打电话给:
实际上,这将导致 Autofac 抛出 a ComponentNotRegisteredException
,因为没有ICommandHandler<SpecialFooCommand>
可用的。
然而,理想情况下,我仍然希望 aSpecialFooCommand
由可用的最匹配的命令处理程序处理,即。上面例子中的 a FooCommandHandler
。
是否可以为此定制 Autofac,也许使用自定义注册源?
PS:我知道可能存在阻碍协变/逆变的基本问题(如下例所示),唯一的解决方案可能是根本不使用泛型的解决方案......但我会如果可能的话,想坚持使用泛型类型。
c++ - C ++中的泛型JAVA?怎么做?
我的代码有什么问题..输出如下...
1>链接...
1>TemplateStuding1.obj:错误LNK2001:无法解析的外部符号“class X __cdecl doIt(class X)”(??$doIt@VXClass@@@@YA?AVXClass@@V0@@Z)
1 >D:\Programming\cpp\cpp-how-to-program\CppHowToProgram\Release\Test.exe : 致命错误 LNK1120: 1 unresolved externals
c# - 为什么我可以转换 IList 的不变性离开?
目前,我正在为我的同事准备 C# 中新的通用方差特性的演示文稿。简而言之,我写了以下几行:
是的,这当然是不可能的,因为 IList(Of T) 是不变的(至少我的想法)。编译器告诉我:
无法将类型隐式转换
System.Collections.Generic.IList<System.Windows.Forms.Form>
为System.Collections.Generic.IList<System.Windows.Forms.Control>
. 存在显式转换(您是否缺少演员表?)
嗯,这是否意味着我可以强制进行显式转换?我刚试过:
而且......它编译!这是否意味着我可以抛弃不变性?- 至少编译器可以接受,但我只是将以前的编译时错误变成了运行时错误:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Windows.Forms.Form]' to type 'System.Collections.Generic.IList`1[System.Windows.Forms.Control]'.
我的问题:为什么我可以抛弃IList<T>
(或任何其他关于我的实验的不变接口)的不变性?我真的抛弃了不变性,或者这里发生了什么样的转换(因为IList(Of Form)
并且IList(Of Control)
完全不相关)?这是我不知道的 C# 的一个黑暗角落吗?
c# - 多泛型歧义
下面的代码完全一样,只是一个是C#,另一个是VB.Net。C# 编译得很好,但 VB.Net 抛出警告:
由于 'Interface IObserver(Of In T)' 中的 'In' 和 'Out' 参数,接口 'System.IObserver(Of Foo)' 与另一个实现的接口 'System.IObserver(Of Bar)' 不明确
为什么 VB.Net 显示警告而不是 C#?最重要的是,我该如何解决这个问题?
Obs:我正在使用 .Net Framework 4 和 Visual Studio 2010 Ultimate。
VB.Net 代码:
C#代码: