我写了这样的收藏集:
class AnimalCollection<TValue> where TValue : Animal, new()
{
void Add(TValue value){};
void AddNew()
{
Add(new TValue());
}
}
我有一些来自Animal的类:
class Animal
{
string Name;
}
class Fish : Animal
{
Fish(){};
}
class Mammal : Animal
{
Mammal(){};
}
接下来,我想以相同的方式对待所有集合。
static void Main(string[] args)
{
var FishAquarium = new AnimalCollection<Fish>();
var MammalEnclosure = new AnimalCollection<Mammal>();
foo(FishAquarium);
foo(MammalEnclosure);
}
问题1:我想传递每个AnimalCollection,哪种类型需要'zoo'?
static void foo(AnimalCollection<Animal> zoo)
{
foreach(var animal in Zoo)
Console.WriteLine(animal.Name);
zoo.AddNew();
}
问题2::泛化泛型类的最佳实践是什么?
更新:
更具体地说,我有一个可以获取任何AnimalCollection的类。
class ZooController
{
public AnimalCollection<Animal> Animals{get; set;}
}
答案 0 :(得分:1)
泛型将起作用:
static void foo<T>(AnimalCollection<T> zoo) where T : Animal, new()
{...}
但是,滚动自己的集合类型通常不是一个好主意-往往会造成混乱,而不是帮助。您可能只想考虑一下List<T>
或IList<T>
。
您说您不想使用泛型;这是国际海事组织的愚蠢决定,因为他们可以解决这个问题,但是您也可以使用协方差;如果您有:
interface IAnimalCollection<out TValue> : IEnumerable<TValue>
{
void AddNew();
}
和:
class AnimalCollection<TValue> : IAnimalCollection<TValue>
where TValue : Animal, new()
{...}
然后您可以使用:
static void foo(IAnimalCollection<Animal> zoo)
{
foreach (var animal in zoo)
Console.WriteLine(animal.Name);
zoo.AddNew();
}
和您的代码:
var FishAquarium = new AnimalCollection<Fish>();
var MammalEnclosure = new AnimalCollection<Mammal>();
foo(FishAquarium);
foo(MammalEnclosure);
可以正常工作;但这-无缘无故地工作-通过上面显示的foo<T>
方法的简单泛型更简单,更直接。
答案 1 :(得分:0)
尝试这种方法:
class Program
{
static void Main(string[] args)
{
List<IAnimal> animals = new List<IAnimal>() { new Animal("Fuffy"), new Fish("Fishy"), new Mammal("Mommy") };
OutputAnimalsNames(animals);
}
private static void OutputAnimalsNames(List<IAnimal> animals)
{
foreach (IAnimal animal in animals)
{
Console.WriteLine(animal.Name);
}
}
}
public interface IAnimal
{
Guid Guid { get; }
string Name { get; }
}
public class Animal : IAnimal
{
public Guid Guid { get; private set; }
public string Name { get; set; }
public Animal(string name)
{
this.Name = name;
this.Guid = Guid.NewGuid();
}
}
public class Fish : Animal
{
public Fish(string name) : base(name)
{
}
}
public class Mammal : Animal
{
public Mammal(string name) : base(name)
{
}
}