协变接口与具有通用参数的方法的益处

时间:2015-12-08 16:55:10

标签: c# covariance

我试图通过

为字典构建协变IEnumerable
public interface ICovariantKeyValuePair<K, out V>
{
  K Key { get; }
  V Value { get; }
}

因为我只想使用一个方法来处理具有一些常见值类型的不同类型的词典。最后,我真的很惊讶忽略了使用通用方法的简单解决方案

public void Print<S,T>(Dictionary<S,T> dict) { ... }

现在我想知道协变接口的真正好处是什么,以及只能用这些接口做什么,而没有其他方法。

编辑我明白,如果我想将两个值保持在一起,就像上面描述的协变键值对一样,这是有意义的。以下来自Heinzi的例子(见下文)

var kv1 = new CovariantKeyValuePair<string, Dog>("MyDog", myDog);
var kv2 = new CovariantKeyValuePair<string, Cat>("MyCat", myCat);
ICovariantKeyValuePair<string, Animal>[] myAnimals = { kv1, kv2 };

显然只适用于协变接口。但为了达到中心点,让我们进一步简化:我可以写

Dog d = new Dog();
Cat c = new Cat();
List<Animal> l = new List<Animal>() { d, c };

我的数据类型无需协方差。

因此协变接口优于List<BaseType>数据结构和方法Foo<BaseType>(..)的好处是“当需要将某些内部部分具有附加的继承关系保持在一起时”,就像在键 - 值对的?

1 个答案:

答案 0 :(得分:2)

我认为这是一个非常有趣的问题。你基本上要求一个例子,其中(1)有一个使用协变接口的简单解决方案,但(2)如果您唯一的选择是使方法通用,则没有简单的解决方案。

这是一个例子:假设我想要一个键值对数组,其中键是一个字符串,值是动物的某个子类型。使用协变类型,我可以执行以下操作:

str_replace(html_entity_decode('&ndash;', ENT_COMPAT, 'UTF-8'), '', $string);

这是唯一可能的,因为类型是协变的,即因为var kv1 = new CovariantKeyValuePair<string, Dog>("MyDog", myDog); var kv2 = new CovariantKeyValuePair<string, Cat>("MyCat", myCat); ICovariantKeyValuePair<string, Animal>[] myAnimals = { kv1, kv2 }; kv1