我可以干净地创建派生类型的派生集合吗?

问题描述 投票:0回答:1

我有三门课:

  • 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。

如何解决这个问题?我是否缺少一种替代方法,或者我应该完全放弃基类并接受派生集合类中将有重复的方法?

c# inheritance covariance
1个回答
0
投票

我认为泛型

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");
}
© www.soinside.com 2019 - 2024. All rights reserved.