如何将具有不同类型的ObservableCollections添加到ObservableCollection

时间:2018-11-08 16:20:18

标签: c# list

我正在尝试添加到ObservableCollectionObservableCollections中的不同类型。这些类型来自基类,在此示例中,我使用“动物”。尝试添加到Observable Collection中时,如下面的代码所示,出现以下错误:

cannot convert from 'System.Collections.ObjectModel.ObservableCollection<Cat>' to 'System.Collections.ObjectModel.ObservableCollection<Animal>'

public ObservableCollection<ObservableCollection<Animal>> Animals { get; set; }
private ObservableCollection<Dog> Dogs = new ObservableCollection<Dog>();
private ObservableCollection<Cat> Cats = new ObservableCollection<Cat>();
private ObservableCollection<Bird> Birds = new ObservableCollection<Bird>();

public DefaultConstructor()
{
    Animals = new ObservableCollection<ObservableCollection<Animal>>()
    { Cats, Dogs, Birds };
}

课程示例:

public abstract class Animal
{
    ...
}
public class Dog : Animal
{
    ...
}
public class Cat : Animal
{
    ...
}
public class Bird : Animal
{
    ...
}

我也尝试过使ObservableCollection仅仅采用ObservableCollection<object>的类型,但是结果是相同的。

4 个答案:

答案 0 :(得分:0)

考虑对基类和过滤器方法使用单个可观察的集合:

public class AnimalContainer : ObservableCollection<Animal>
{
    public IEnumerable<Dog> Dogs => this.Where(animal => animal is Dog).Cast<Dog>();
    public IEnumerable<Cat> Cats => this.Where(animal => animal is Cat).Cast<Cat>();
}

//...
AnimalContainer container = new AnimalContainer();

container.Add(new Dog());
container.Add(new Cat());

int dogsCount = container.Dogs.Count();
int catsCount = container.Cats.Count();

答案 1 :(得分:0)

为什么不使用界面?假设您有动物类的界面。

    public interface IAnimal{
}

Dog and Cat将实现IAnimal接口,如下所示:

public class Dog: IAnimal{
}
public class Cat:IAnimal{
}

现在,假设您想拥有一个包含猫和狗的收藏。只要做:

ObservableCollection<IAnimal> animals=new  ObservableCollection (){
new Dog (),
new Cat()
};

几乎相同的逻辑适用于abstract类。 考虑一个简单的Animal抽象类。

public abstract class Animal
    {
        public abstract string GetName(string animalName);
        //I dont know what to do!
    }

狗类

public class Dog : Animal
    {
        public override string GetName(string animalName)
        {
            return animalName;
        }
    }

可爱的猫课

public class Cat : Animal {
        public override string GetName(string animalName)
        {
            return animalName;
        }
    }

狗和猫的清单

public class DoStuff{
        public void TestThings()
        {
            List<Animal> animals = new List<Animal>()
        {
            new Dog(),
            new Cat()
        };
            foreach(Animal animal in animals)
            {
                Console.WriteLine(animal.GetName("My name is: "+animal.GetType()));
            }
        }
    }

结果:

My name is: StuffClass.Dog
My name is: StuffClass.Cat

答案 2 :(得分:0)

将Animal用作界面,您可以执行以下操作:

public interface Animal
{
    string Name { get; set; }
}

public class Dog : Animal
{
    public string Name { get; set; }
}

public class Cat : Animal
{
    public string Name { get; set; }
}

public class Bird : Animal
{
    public string Name { get; set; }
}

然后与动物一起上课:

private List<Dog> Dogs = new List<Dog>();
private List<Cat> Cats = new List<Cat>();
private List<Bird> Birds = new List<Bird>();

public MainWindowViewModel()
{
    Animals = new ObservableCollection<ObservableCollection<Animal>>();
    Animals.Add(new ObservableCollection<Animal>(Cats));
    Animals.Add(new ObservableCollection<Animal>(Dogs));
    Animals.Add(new ObservableCollection<Animal>(Birds));
}

public ObservableCollection<ObservableCollection<Animal>> Animals { get; set; }

这将使您的媒体资源填充所需的集合。 然后,您可以在代码中创建如下的帮助方法:

private void AddToCats()
{
    ObservableCollection<Animal> cats = Animals.FirstOrDefault(a => a.Any(cat => cat is Cat));
    cats.Add(new Cat{Name = "Biggles"});
}

这是猜测您要在初始填充之后对各个ObservableCollection进行处理。

答案 3 :(得分:0)

我将假设您正在执行任务要求您执行的操作,例如可观察的集合和抽象类(您指出必须执行此操作)。我重新创建了您的类,但是在我的实现中,这是我如何实现而又没有出现构建错误的方法。

public class BuildZoo
{
  private ObservableCollection<Animal> cats = new ObservableCollection<Animal>();
  private ObservableCollection<Animal> dogs = new ObservableCollection<Animal>();
  private ObservableCollection<Animal> birds = new ObservableCollection<Animal>();

  private ObservableCollection<ObservableCollection<Animal>> zoo =
  new ObservableCollection<ObservableCollection<Animal>>();

  public void construct ()
  { zoo. Add(cats);
    zoo.Add(dogs);
    zoo.Add(birds);
    cats.Add(new Cat());
    dogs.Add(new Dog());
    birds.Add(new Bird());
  }
}

如果您需要对将狗添加到dog集合进行强类型验证,则必须做一个自己的继承ObservableColletion并覆盖Add逻辑的集合。

  public class DogCollection<T> : ObservableCollection<T>
  {
    public new void Add(T animal)
    {
      if (animal is Dog)
        base.Add(animal);
      throw new InvalidCastException("Animal is not a Dog");
    }
  }

因此,使用ObservableCollection,您可以将每个动物集合替换为DogCollection,CatCollection等。基类的其余部分将完成此工作。