泛化通用类

时间:2018-07-17 09:03:32

标签: c# generics generalization

我写了这样的收藏集:

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

2 个答案:

答案 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)
    {

    }
}