C#类、列表和对象之间的继承

问题描述

我创建了一个包含一个对象的列表,其中包含一个对象列表。我想从父类列表/对象中的继承/子类对象中检索值。解释我下面的代码有点令人困惑,应该会有所帮助。也许 Linq 可能是解决方案?我不确定。非常感谢。

RelocationActivityForm 类 -- 这将使用继承的 Relocation 活动类创建一个新对象。

 private Vehicle selectedVehicle;

            selectedVehicle = (Vehicle)mainFormRego.SelectedItem; // Gets the selected item from a listBox

            selectedVehicle.ActivityList.Add(new Relocation() // create an object for the selected vehicle,inside the activitylist (list) creating a new object using the Relocation class.
            {
                Date = date,// In activity class
                Name = name,// In activity class
                Type = "Relocation",// In activity class
                Start = start,// In relocation class
                End = end,// In relocation class
                distance = distance,// In relocation class
                Cost = cost // In activity class
            });
            ViewVehicleForm.Form.updateViewVehicle(); // Method updates textBox display.
            Hide(); // Form hidden

        }

车辆等级

namespace VehicleSystem
{
    [Serializable]
    public class Vehicle
    {
        private int dailyCharge;
        private int year;
        private string model;
        private string make;
        private string rego;
        private List<Activity> _activityList = new List<Activity>();

        public string Rego { get => rego; set => rego = value; }
        public string Make { get => make; set => make = value; }
        public string Model { get => model; set => model = value; }
        public int Year { get => year; set => year = value; }
        public int DailyCharge { get => dailyCharge; set => dailyCharge = value; } // Creating an ativity list for each vehicle
        internal List<Activity> ActivityList { get => _activityList; set => _activityList = value; 
         }

    }
}

活动类

    [Serializable]
    public class Activity
    {
        // Relocation Activity
        private DateTime _date;
        private string _name;
        private string _type;
        private decimal _cost;

        public string Name { get => _name; set => _name = value; }
        public string Type { get => _type; set => _type = value; }
        public decimal Cost { get => _cost; set => _cost = value; }
        public DateTime Date { get => _date; set => _date = value; }
    }

搬迁

    class Relocation : Activity
    {
        private string start;
        private string end;
        private int distance;

        public string Start { get => start; set => start = value; }
        public string End { get => end; set => end = value; }
        public int distance { get => distance; set => distance = value; }
    }

使用它,我想从车辆的 ActivityList 中获取 Relocation 类中的项目。我可以从 ActivityList 中获取项目(通过调用此语句如下所示),但我无法获取使用 Relocation 类存储的活动/项目。

 private void viewVehicleActivityData_CellContentClick(object sender,DataGridViewCellEventArgs e)
        {
            int x = viewVehicleActivityData.CurrentCell.RowIndex; // Getting the datagridview index of a row
            MessageBox.Show(selectedVehicle.ActivityList[x].Name); // Using it to get the name
        }

解决方法

是因为您的 ActivityListList 类型,而 RelocationActivity 的子类> 所以看不到是不是用作Activity,可以尝试将列表中的Activity强制转换为Relocation。

确保在投射前进行适当的检查,请参见此处的示例:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast

示例:

if (selectedVehicle.ActivityList[x] is Relocation relocation) {
   MessageBox.Show(relocation.End);
}
,

您可以在此处使用各种实现。我确实认为@ebv 的回答和对类型转换的引用涵盖了一般概念,但我会为您的场景提供一个片段。 (参考您评论中的“我如何获得 End”)


此答案的实现将使用 as operator

哪个——

将表达式的结果显式转换为给定的引用或可为空的值类型

如果转换失败,它将返回 null

因此,我们将使用 null-conditional operator(即 ?)和 null-coalescing operators (right-associative)(即 ??)来处理 null转换,否则如果发生转换,则返回 End

private void viewVehicleActivityData_CellContentClick(object sender,DataGridViewCellEventArgs e)
{
    int x = viewVehicleActivityData.CurrentCell.RowIndex; // Getting the datagridview index of a row
    MessageBox.Show((selectedVehicle.ActivityList[x] as Relocation)?.End ?? "Activity is not Relocation"); // Using it to get the name
}

或者

在您给定的示例片段中,所有活动都是 Relocation 类型。

如果确实如此,您只需要在此处进行隐式转换 —

private void viewVehicleActivityData_CellContentClick(object sender,DataGridViewCellEventArgs e)
{
    int x = viewVehicleActivityData.CurrentCell.RowIndex; // Getting the datagridview index of a row
    MessageBox.Show(((Relocation)selectedVehicle.ActivityList[x]).End); // Using it to get the name
}