c#如何将对象列表传递给构造函数
本文关键字:构造函数 列表 对象 | 更新日期: 2023-09-27 18:16:06
我想传递一个对象列表给NavigationPage的构造函数,这样我就可以在那个页面上填充ListView的内容。
对象将是不同类型的,都继承自同一个父类,父类是一个抽象类,称为"Animal",定义如下:
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);
....
编辑:回应一些建议;澄清一下:我需要在列表中保留"马"、"牛"、"狗"等对象类型,因为每种动物类型都有要显示的唯一属性。此外,Animal List的每个实例只能有一种类型,即永远不会有马、牛和狗的组合列表。
但是我得到错误:
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();
让我稍微解释一下这种情况的本质。
不能隐式地将集合转换为基类型的集合,即使它听起来安全且正确。
想象下面的情况:
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>
来传递Animal
的集合,或者使用.Cast<Animal>()
扩展方法,正如其他回答者已经完全描述的那样。
以下是一些选项:
简单的解决方案是使用List<Animal>
而不是List<Horse>
。然后你的代码将符合构造函数所要求的类型。
AnimalListPage
通用。然后,您可以强类型地键入想要在AnimalListPage
中使用的Animal
类型。这将只工作,如果你有一个单一类型的Animal
你想使用。
最后一个选项是使用协变接口IAnimal
,并将其用作列表类型。所有Animal
类型都应该实现这一点,但我想你可以在你的基类中实现这一点。或者使用协变集合接口,如IEnumerable<Animal>
。