c# – 为什么类类型参数的方差必须与方法的返回值参数类型参数的方差相匹配?

c# – 为什么类类型参数的方差必须与方法的返回值参数类型参数的方差相匹配?,第1张

概述以下提出投诉: interface IInvariant<TInv> {}interface ICovariant<out TCov> { IInvariant<TCov> M(); // The covariant type parameter `TCov' // must be invariantly valid on 以下提出投诉:
interface IInvariant<TInv> {}interface ICovariant<out TCov> {    IInvariant<TCov> M(); // The covariant type parameter `TCov'                          // must be invariantly valID on                          // `ICovariant<TCov>.M()'}interface IContravariant<in TCon> {    voID M(IInvariant<TCon> v); // The contravariant type parameter                                // `TCon' must be invariantly valID                                // on `IContravariant<TCon>.M()'}@H_404_3@  

但我无法想象这不会是类型安全的. (snip *)这是不允许这样做的原因,还是有其他违反我不知道的类型安全的情况?

*我的初步想法是无可比拟的,但尽管如此,答案非常彻底,@Theodoros Chatzigiannakis甚至以令人印象深刻的准确度解释了我的初步假设.

除了回想起来,我意识到我错误地认为ICovariant :: M的类型签名仍然是一个Func< IInvariant< Derived>>>当它的ICovariant< Derived>被分配给ICovariant< Base>.然后,将该M分配给Func< IInvariant< Base>>看起来很好从一个ICovariant< Base>,但当然是非法的.为什么不禁止这最后一个,非常非法的演员? (所以我认为)

我觉得这个错误和切向的猜测减损了这个问题,正如Eric Lippert也指出的那样,但为了历史目的,

The most intuitive explanation to me is that,taking ICovariant as an example,the covariant TCov implIEs that the method IInvariant<TCov> M() Could be cast to some IInvariant<TSuper> M() where TSuper super TCov,which violates the invariance of TInv in IInvariant. However,this implication doesn’t seem necessary: the invariance of IInvariant on TInv Could easily be enforced by disallowing the cast of M.

解决方法 到目前为止,我并不确定您是否已经在任何答案中回答了问题.

Why does the variance of a class type parameter have to match the variance of its methods’ return/argument type parameters?

它不是,所以问题是基于一个假的前提.实际规则在这里:

https://blogs.msdn.microsoft.com/ericlippert/2009/12/03/exact-rules-for-variance-validity/

现在考虑:

interface IInvariant<TInv> {}interface ICovariant<out TCov> {   IInvariant<TCov> M(); // Error}@H_404_3@  

Is this the reason why this is disallowed,or is there some other case which violates type safety which I’m not aware of?

我没有遵循你的解释,所以让我们来说明为什么不允许你参考你的解释.在这里,让我用一些等效的类型替换这些类型. IInvariant< TINV>可以是T中不变的任何类型,我们假设ICage< TCage&gt ;::

interface ICage<TAnimal> {  TAnimal Remove();  voID Insert(TAnimal contents);}@H_404_3@  

也许我们有一个类型Cage< TAnimal>实现ICage< TAnimal&gt ;. 我们来替换ICovariant< T>同

interface ICageFactory<out T> {   ICage<T> MakeCage();}@H_404_3@  

我们来实现接口:

class TigerCageFactory : ICageFactory<Tiger> {   public ICage<Tiger> MakeCage() { return new Cage<Tiger>(); }}@H_404_3@  

一切顺利ICageFactory是协变的,所以这是合法的:

ICageFactory<Animal> animalCageFactory = new TigerCageFactory();ICage<Animal> animalCage = animalCageFactory.MakeCage();animalCage.Insert(new Fish());@H_404_3@  

我们只是把一只鱼放进一只老虎笼里.每一步都是完全合法的,我们最终会遇到类型系统违规.我们得出的结论是,使ICageFactory协调一致不能是合法的.

我们来看看你的逆向例子基本上是一样的:

interface ICageFiller<in T> {   voID Fill(ICage<T> cage);}class AnimalCageFiller : ICageFiller<Animal> {  public voID Fill(ICage<Animal> cage)  {    cage.Insert(new Fish());  }}@H_404_3@  

现在,界面是相反的,所以这是合法的:

ICageFiller<Tiger> tigerCageFiller = new AnimalCageFiller();tigerCageFiller.Fill(new Cage<Tiger>());@H_404_3@  

我们再次把鱼放进老虎笼里.我们再次得出结论,首先将类型违反是非法的.

所以现在让我们考虑一下我们如何知道这些是非法的.在第一种情况下,我们有

interface ICageFactory<out T> {   ICage<T> MakeCage();}@H_404_3@  

相关规则是:

The return types of all non-voID interface methods must be valID covariantly.

ICage< T> “有效协变”?

A type is valID covariantly if it is:
1) a pointer type,or a non-generic class… nopE
2) An array type… nopE
3) A generic type parameter type … nopE
4) A constructed class,struct,enum,interface or delegate type X<T1,… Tk> YES! … If the ith type parameter was declared as invariant,then Ti must be valID invariantly.

在ICage< TAnimal>,So T in ICage>中,TAnimal是不变的必须是不变的.是吗?不可变的,不变地必然是有效的,而且是相反的,但它只有共同的有效.

因此这是一个错误.

对逆转案件进行分析是作为一项工作.

总结

以上是内存溢出为你收集整理的c# – 为什么类类型参数方差必须与方法的返回值/参数类型参数的方差相匹配?全部内容,希望文章能够帮你解决c# – 为什么类类型参数的方差必须与方法的返回值/参数类型参数的方差相匹配?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1258835.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存