我有三门课:
Animal
Giraffe : Animal
Tiger : Animal
...并且想要实现三个字典类:
abstract AnimalDictionary
GiraffeDictionary : AnimalDictionary, IDictionary<int, Giraffe>
TigerDictionary : AnimalDictionary, IDictionary<int, Tiger>
我很清楚基地
AnimalDictionary
无法实现IDictionary
或ICollection
,因为将老虎放入GiraffeDictionary
会导致问题。我不会假装正确理解协变和逆变,但我确实明白为什么你不能把老虎放在长颈鹿圈里。
相反,我通过让它继承
AnimalDictionary
来实现 IEnumerable<KeyValuePair<int, Animal>>
,并且只是让它实现与字典相同的所有方法,减去 Add()
,因为 Add() 将在派生类中实现。
不幸的是,在派生集合类中实现
IDictionary
给我带来了 GiraffeDictionary 和 TigerDictionary 中的一些丑陋:
ICollection<Giraffe> IDictionary<int, Giraffe>.Values => _internalDictionary.Values.Cast<Giraffe>().ToList();
这让我担心,因为我希望在紧密的循环中迭代这些集合。我希望能够迭代 Values 集合,而无需转换和创建全新列表的性能成本,但 Values 是 ICollection,而不是 IEnumerable。
如何解决这个问题?我是否缺少一种替代方法,或者我应该完全放弃基类并接受派生集合类中将有重复的方法?
我认为泛型
AnimalDictionary<T>
在这里会很有帮助,我们可以在泛型类中编写通用方法,该方法可以被其他派生类型重用。这是我编写的一个示例,它应该给出一些如何解决这个问题的想法:
public class AnimalDictionary<T> where T : Animal
{
}
public class Animal
{
}
public class Cat : Animal
{
}
调用代码如下:
public static void Main()
{
AnimalDictionary<Cat> catDictionary = new AnimalDictionary<Cat>();
Console.WriteLine("Hello World");
}