gpt4 book ai didi

c# - 同一类型参数的协变和逆变

转载 作者:可可西里 更新时间:2023-11-01 08:51:05 25 4
gpt4 key购买 nike

C# 规范指出参数类型不能同时是协变和逆变的。

这在创建协变或逆变接口(interface)时很明显,您分别用“out”或“in”修饰类型参数。没有同时允许两者的选项(“outin”)。

这种限制仅仅是一种特定于语言的约束,还是基于范畴论的更深层、更根本的原因会让您不希望您的类型既是协变又是逆变的?

编辑:

我的理解是数组实际上是协变和逆变的。

public class Pet{}
public class Cat : Pet{}
public class Siamese : Cat{}
Cat[] cats = new Cat[10];
Pet[] pets = new Pet[10];
Siamese[] siameseCats = new Siamese[10];

//Cat array is covariant
pets = cats;
//Cat array is also contravariant since it accepts conversions from wider types
cats = siameseCats;

最佳答案

正如其他人所说,泛型类型既是协变又是逆变在逻辑上是不一致的。到目前为止,这里有一些很好的答案,但让我再补充两个。

首先,阅读我关于方差“有效性”主题的文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/03/exact-rules-for-variance-validity.aspx

根据定义,如果一个类型是“协变有效”的,那么它不能以逆变方式使用。如果它“逆变有效”,那么它不能以协变方式使用同时协变有效和逆变有效的东西既不能以协变方式也不能以逆变方式使用。也就是说,它是不变的。因此, 是协变和逆变的并集:它们的并集不变

其次,让我们暂时假设您如愿以偿,并且有一个类型注释以我认为您想要的方式工作:

interface IBurger<in and out T> {}

假设您有一个 IBurger<string> .因为它是协变的,所以可以转换为 IBurger<object> .因为它是逆变的,所以它又可以转换为 IBurger<Exception> ,即使“string”和“Exception”没有任何共同点。基本上“进出”意味着IBurger<T1>可转换为任何类型IBurger<T2>对于任意两个引用类型 T1 和 T2。 这有什么用?您会使用这样的功能做什么?假设你有一个 IBurger<Exception> , 但对象实际上是一个 IBurger<string> .你能用它做什么,两者都利用了类型参数是 Exception 的事实,并允许该类型参数是一个完整的谎言,因为“真实”类型参数是一个完全不相关的类型?

回答您的后续问题:涉及数组的隐式引用类型转换是协变;它们是逆变的。你能解释为什么你错误地认为它们是逆变的吗?

关于c# - 同一类型参数的协变和逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4528186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com