协方差,逆变和一个i - lookup风格的接口



如果一个人正在设计一个像ILookup这样的界面(为了简单起见,假设它只是ICheckIfContained,所以项目值的类型无关紧要),那么关于第一个参数的理想方差类型是什么?

检查ICheckIfContained<Animal>是否包含特定的Cat将是一个自然的操作,并且在正常的逆变规则下是类型安全的。

检查ICheckIfContained<Cat>是否包含特定的Animal在正常的逆变规则下不是类型安全的,但它是自然的和定义良好的(如果Animal不是Cat, ICheckIfContained的正确行为将是说它不包含有问题的动物)。

检查ICheckIfContained<Cat>是否包含特定的Dog并不是特别有用(答案总是"否"),但答案将是明确定义的。请注意,与前一个场景不同,这个场景中的答案可以静态地确定。

一种方法是将ICheckIfContained作为非泛型接口,并简单地接受Object类型的参数。然而,在列表只包含单一类型的结构体的情况下,这似乎相当低效。另一方面,如果它是一个泛型接口,那么编译器将无法允许在协变场景中使用它(传入一个参数,其声明的类型是预期类型的父类型,这样传入的对象可能是也可能不是预期类型)。

在编译器可以确认所有内容都是相同类型的情况下,是否有任何好的模式可以获得泛型的效率,同时仍然允许检查父类型对象是否在子类型集合中的一般情况行为?

我认为你做不到。如果能够静态地将其检查为false,则肯定是有效的,但是只有当编译器确切地知道该方法执行的是哪种操作时,才能优化将Dog传递给Contains(cat)

如果你的Contains实际上是Add呢?编译器不理解方法名

最新更新