根据其他参数指定通用列表的类型

时间:2015-03-17 17:18:11

标签: c# list class

我有一个问题,我无法用简单的语言解释,所以我会用一个考试来说明我的想法。

我有三个班牛,马,羊。和类动物。现在我希望clas Animal存储动物列表但只有一个指定物种(用户在构造函数中选择类型)。现在我不想使用模板,我不想在一个类中创建三个不同的列表。所以我想知道是否有其他方法可以做到这一点。我认为可以这样做:

public class Animal
{

}
public class Cow : Animal
{

}
public class Horse : Animal
{

}
public class Sheep : Animal
{

}
public class Animals
{
    public String Type { get; protected set; }
    public List<Animal> List { get; set;}
    public Animals(String type)
    {
        this.Type = type;
        switch (type)
        {
            case "Cow":
                List = new List<Cow>();
                break;
            case "Horse":
                List = new List<Horse>();
                break;
            case "Sheep":
                List = new List<Sheep>();
                break;
        }
    }
}

当然,这段代码只是样本而且不起作用,但我认为它说明了我的问题。我确信我在过去看过类似的东西,但我不知道它是C#还是Java。如果我记得它看起来像那样:

Animal animal = new Cow();

告诉我是否有办法做到这一点。

3 个答案:

答案 0 :(得分:0)

怎么样?
public class Animals<T>
    where T : Animal
{
    public List<T> List {get;set;}
}

var Cows = new Animals<Cow>();

答案 1 :(得分:0)

您可以在每种情况下将列表创建为List<Animal>,并且它将很乐意存储从Animal派生的任何对象。问题在于列表中对象的强制执行是相同的类型 - 它不清楚你想要强制执行的那个,但是我通过在成员变量中保留所需的Type来对它进行攻击。

如果你想要的只是特定类型的枚举器,你可以使用OfType(感谢Kevin D)来生成枚举器。我知道你说你不想使用泛型,但你的Animal类不必有类型参数,使用模板方法是一个更优雅的解决方案(恕我直言)。

public class Animal
{
}

public class Cow : Animal
{
}

public class Animals
{
    private Type _animalType;
    private List<Animal> _animals = new List<Animal>();

    public Animals(Type animalType)
    {
        _animalType = animalType;
    }

    public IEnumerable<T> GetAnimals<T>() where T : Animal
    {
        return _animals.OfType<T>();
    }

    public void Add(Animal animal)
    {
        if (! _animalType.IsAssignableFrom(animal.GetType()))
            throw new Exception("Expected a " + _animalType.Name + " but was passed a " + animal.GetType().Name);
        _animals.Add(animal);
    }
}


public class Program
{
    public static void Main()
    {
        Animals animals = new Animals(typeof(Cow));

        animals.Add(new Cow());
        IEnumerable<Cow> cows = animals.GetAnimals<Cow>();

        foreach (var cow in cows)
        {
            // do something
        }
    }
}

答案 2 :(得分:-2)

我相信Generics是解决问题的最佳方式,我希望这段代码可以帮助您。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication7
{
  public class Animal
  {

  }
  public class Cow : Animal
  {

  }
  public class Horse : Animal
  {

  }
  public class Sheep : Animal
  {

  }    

  public class Animals
  {        
    protected ArrayList List { get; set; }
    protected Type Type { get; set; }

    public Animals(Type type)
    {
        this.Type = type;
        this.List = new ArrayList();
    }

    public void AddAnimal(Animal animal)
    {
        if (animal.GetType() == this.Type)            
            this.List.Add(animal);            
        else
            throw new Exception("Not expected type");
    }
 }

class Program
{
    static void Main(string[] args)
    {
        var s1 = new Sheep();
        var s2 = new Sheep();
        var c1 = new Cow();
        var sheepList = new Animals(typeof(Sheep));
        sheepList.AddAnimal(s1);
        sheepList.AddAnimal(s2);
        sheepList.AddAnimal(c1);//throws an exception
    }
  }
}