【问题标题】:C# List<T> adding inherited items [closed]C# List<T> 添加继承项
【发布时间】:2017-03-31 13:08:14
【问题描述】:

假设我们有 2 个类。第一个是人

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

namespace People
{
    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

第二个是老师

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

namespace People
{
    class Teacher:Person
    {
        public string Position { get; set; }
    }
}

我想在列表中添加老师

Teacher teacher = new Teacher() {FirstName="Peter", LastName="Janson",Position="boss" };
            List <Person> people= new List<Person> { };
            people.Add(teacher);

当这个列表是 type 并且 person 只有 FirstName 和 LastName 属性并且“teacher”也有 Position 属性时,我怎么可能在列表中添加老师?

【问题讨论】:

  • 您可以将它们添加到列表中,但您只能访问基类的属性 (Person)。为了获得Position,您必须将类型转换为Teacher

标签: c# inheritance linked-list list-template


【解决方案1】:

这是一个关于称为多态的基本面向对象概念的问题。 Teacher Person,但您的Person 实例列表只知道它包含Person 实例列表;它对派生自Person 的类一无所知,也不需要。

如果您正在使用列表中的元素,您可以确定它们的类型,然后将它们转换到该类型,如下所示:

foreach (Person x in people)
{
    if (x is Teacher)
    {
        Teacher y = (Teacher) x;
    }
}

然后就可以访问老师的属性了:y.Position

【讨论】:

  • 或者,if(x is Teacher t),如果你正在使用花哨的 C#7
  • @Jonesopolis 终于! :-D
  • @BRAHIMKamel -- 协方差在这里不相关。我并不是说List&lt;Teacher&gt; 等同于List&lt;Person&gt;。当b 派生自a 时,总是可以用b 替换a...方差与它无关。我的代码示例在 .NET 4.0 之前运行得非常好(在 2.0 之后,即引入泛型时)。
【解决方案2】:

根据您之前的问题,我认为您在理解多态性方面遇到了一些问题。

尝试将继承视为汽车和车辆之间的关系。车辆是基础类型,汽车、摩托车、飞机、卡车等是派生类型。

public class Vehicle
{
    public string Model {get;set;}
}

假设你有一个飞机库:

List<Vehicle> hangar = new List<Vehicle>();

您可以在飞机库中停放多辆不同的车辆,因为它非常大:

hangar.Add(new Plane());
hangar.Add(new Car());

虽然它们是不同的类型,但它们仍然继承自车辆,因此可以作为车辆存储。

问题是,飞机有机翼而汽车没有。如果你只乘坐第一辆车hangar[0],你就知道这是一辆汽车,你可以得到它的基本信息(所有车辆共有的信息):hangar[0].Model,但你必须更具体地了解车辆的类型如果您想了解更多详细信息,请访问。

现在,由于您可能不知道它是什么类型的车辆,您需要检查一下:

if (hangar[0] is Car)
{
    string registrationNumber = ((Car)hangar[0]).RegistrationNumber;
}
else if (hangar[0] is Plane)
{
    int numberOfWings = ((Plane)hangar[0]).NumberOfWings;
}

使用 C#7 语法,您也可以使用这种简化形式:

if (hangar[0] is Car car)
{
    string registrationNumber = car.RegistrationNumber;
}
else if (hangar[0] is Plane plane)
{
    int numberOfWings = plane.NumberOfWings;
}

与现实生活的类比是,如果你进入机库,你必须看看汽车在哪里,飞机在哪里。这里也一样。

多态性使您可以将许多派生类视为它们的公共基础。在您的个人示例中,如果您希望能够按姓名搜索某人,这将很有用。老师是人,医生也是人,他们都是人,都有名字,所以在这种情况下,你可以一视同仁。

把它想象成快速约会 - 你去,你会遇到人。你先做什么?你问对方的名字。然后你问“你以什么为生?”他们说“我是老师”或“我是医生”。现在你知道他们是什么类型了,你可以问他们“你教什么?”或“您专攻哪个医学分支?”

我希望这能让你更清楚:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 2011-07-19
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    相关资源
    最近更新 更多