繁体   English   中英

C#如何将对象列表传递给构造函数?

[英]C# how to pass a list of objects to a constructor?

我想将对象列表传递给NavigationPage的构造函数,以便可以在该页面上填充ListView的内容。

这些对象将是不同的类型,它们都是从同一个父对象继承的,父对象是一个抽象类,称为“动物”,定义如下:

abstract class Animal { ...

继承的类是这样的:

public class Horse : Animal { ...

public class Cow : Animal { ...

public class Dog : Animal { ...

显示此列表的页面是从NavigationPage继承的类,如下所示:

public List<Animal> Animals = new List<Animal>();

    public AnimalListPage(string title, List<Animal> animals) {
    ....

并按如下方式创建AnimalListPage对象:

var horses = new List<Horse>() {
    new Horse("Silver", 65, 70),
    new Horse("Tucker", 60, 68)
};
horsesListPage = new AnimalListPage("Horses", horses);
....

编辑:回应一些建议; 需要说明的是:我需要在列表中保留“马”,“牛”,“狗”等对象类型,因为每种动物类型都有要显示的唯一属性。 而且,“动物列表”的每个实例都只会具有一种类型,即,永远不会有将马,牛和狗结合在一起的列表。

但是我得到了错误:

Error CS1503 Argument 2: cannot convert from System.Collections.Generic.List<AnimalTracker.Horse> to System.Collections.Generic.List<AnimalTracker.Animal>

我是否必须“投射”“马”列表以某种方式键入“动物”? 还是让“ AnimalListPage()”构造函数减少类型的特定性? 我怎么做?

注意:我正在使用Xamarin进行开发(尽管我认为这与该问题无关)。

只需将列表设为List<Animal>如构造函数所期望的那样:

var horses = new List<Animal>() {
    new Horse("Silver", 65, 70),
    new Horse("Tucker", 60, 68)
};

如果您不控制该值的来源,并且它可以是任何派生类型的List<T> ,则需要执行强制转换操作以将其用作List<Animal>

var horses = someExistingList.Cast<Animal>().ToList();

以下是一些选项:

简单的解决方案是使用List<Animal>而不是List<Horse> 然后,您的代码将符合构造函数要求的类型。

更复杂的是使AnimalListPage通用性。 然后,您可以在AnimalListPage强烈键入要使用的Animal类型。 仅在您要使用一种Animal这才起作用。

最后一个选项是使用协变量接口IAnimal ,并将其用作列表类型。 所有Animal类型都应实现这一点,但是我想您已经可以在您的基类中实现这一点。 或使用协变量收集接口,例如IEnumerable<Animal>

让我稍微解释一下这种情况的本质。
即使听起来安全且正确,也不能将集合隐式转换为基本类型的集合。
想象以下情况:

public void CalledMethod(List<Animal> animals)
{ 
    animals.Add(new Dog()); 
    // error! you've tried to insert a dog into List<Horse>
}

public void CallingMethod()
{
    var horses = new List<Horse>() {
      new Horse("Silver", 65, 70),
      new Horse("Tucker", 60, 68)
    };

    CalledMethod(horses);

    string result = horses[2].RideOrDoSomeOtherHorseOnlyThings(); // it would be strange
}

您需要通过声明List<Animal>而不是List<Horse>或使用.Cast<Animal>()扩展方法来传递Animal的集合,正如其他.Cast<Animal>()已经充分描述的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM