代码之家  ›  专栏  ›  技术社区  ›  Syrlia

泛化泛型类

  •  0
  • Syrlia  · 技术社区  · 7 年前

    我写了一本这样的书:

    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: 我想通过所有动物采集,哪种类型需要“动物园”?

    static void foo(AnimalCollection<Animal> zoo) 
    {
        foreach(var animal in Zoo)
            Console.WriteLine(animal.Name);
         zoo.AddNew();
    }
    

    问题2: 泛化泛型类的最佳实践是什么?


    更新:

    更具体地说,我有一个类可以得到任何动物集合。

    class ZooController
    {
       public AnimalCollection<Animal> Animals{get; set;}
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Marc Gravell    7 年前

    泛型可以工作:

    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> 上面所示的方法更简单、更直接。

        2
  •  0
  •   Marco Salerno    7 年前

    尝试以下方法:

    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)
        {
    
        }
    }
    
    推荐文章