如果一个人正在设计一个像ILookup
这样的界面(为了简单起见,假设它只是ICheckIfContained
,所以项目值的类型无关紧要),那么关于第一个参数的理想方差类型是什么?
检查ICheckIfContained<Animal>
是否包含特定的Cat
将是一个自然的操作,并且在正常的逆变规则下是类型安全的。
检查ICheckIfContained<Cat>
是否包含特定的Animal
在正常的逆变规则下不是类型安全的,但它是自然的和定义良好的(如果Animal
不是Cat
, ICheckIfContained
的正确行为将是说它不包含有问题的动物)。
检查ICheckIfContained<Cat>
是否包含特定的Dog
并不是特别有用(答案总是"否"),但答案将是明确定义的。请注意,与前一个场景不同,这个场景中的答案可以静态地确定。
一种方法是将ICheckIfContained
作为非泛型接口,并简单地接受Object
类型的参数。然而,在列表只包含单一类型的结构体的情况下,这似乎相当低效。另一方面,如果它是一个泛型接口,那么编译器将无法允许在协变场景中使用它(传入一个参数,其声明的类型是预期类型的父类型,这样传入的对象可能是也可能不是预期类型)。
在编译器可以确认所有内容都是相同类型的情况下,是否有任何好的模式可以获得泛型的效率,同时仍然允许检查父类型对象是否在子类型集合中的一般情况行为?
我认为你做不到。如果能够静态地将其检查为false,则肯定是有效的,但是只有当编译器确切地知道该方法执行的是哪种操作时,才能优化将Dog
传递给Contains(cat)
。
如果你的Contains
实际上是Add
呢?编译器不理解方法名