0

我写了一个这样的集合:

class AnimalCollection<TValue> where TValue : Animal, new()
{
    void Add(TValue value){};
    void AddNew()
    {
        Add(new TValue());
    }
}

我有一些从动物派生的类:

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;}
}
4

2 回答 2

1

泛型将起作用:

static void foo<T>(AnimalCollection<T> zoo) where T : Animal, new()
{...}

然而,滚动你自己的集合类型通常不是一个好主意——它往往会造成更多的混乱而不是帮助。您可能想考虑一下List<T>,或IList<T>一推。


你说你不想使用泛型;这是 IMO 一个愚蠢的决定,因为他们正好解决了这个问题,但你也可以使用协方差;如果你有:

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>更简单,更直接。

于 2018-07-17T09:08:09.107 回答
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)
    {

    }
}
于 2018-07-17T10:16:59.700 回答