[英]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.