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

Posted

技术标签:

【中文标题】C# 类、列表和对象之间的继承【英文标题】:C# Inheritance between classes, lists and objects 【发布时间】:2021-08-25 22:00:11 【问题描述】:

我创建了一个包含一个对象的列表,其中包含一个对象列表。我想从继承/子类对象中检索值,即在父类列表/对象中。在下面解释我的代码有点令人困惑,应该会有所帮助。也许 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
        

【问题讨论】:

这个问题有点不清楚。您是说您有一个Activity 对象列表,并且您想要该列表的所有Relocation 对象的子序列?这就是OfType&lt;Relocation&gt; 序列运算符。如果这不是你想要的,那么你能澄清这个问题吗? 不清楚你在问什么。 “我无法获取使用 Relocation 类存储的活动/项目”不清楚。Relocation 类型不存储或具有与活动/项目相关的成员。 我可能在这里冒昧,但我认为您正在寻找的是一种确定或关联 RowIndexselectedVehicle.ActivityList.OfType&lt;Relocation&gt;() 的方法,因为您需要解决索引反对selectedVechicle.ActivityList?这是你面临的问题吗? @BrettCaswell 是的,这就是我的意思。对不起,伙计们 我正在尝试从活动的重定位子类中获取项目。我正在创建一个使用 Relocation 类的对象,但我无法仅从活动类中获取该类中的项目。 【参考方案1】:

您可以在此处使用各种实现。我确实认为@ebv 的回答和对类型转换的引用涵盖了一般概念,但我会为您的场景提供一个 sn-p。 (参考“我如何在您的 cmets 中获得 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

或者

在您给定的示例 sn-ps 中,所有活动都是 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

【讨论】:

其中一些运算符是在较新的 c# 语言中引入的。因此,此实现可能需要 c# 8.0【参考方案2】:

是因为您的 ActivityListList 类型,而 RelocationActivity 的子类> 所以看不到是否使用 as 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);

【讨论】:

那么我需要写什么呢?

以上是关于C# 类、列表和对象之间的继承的主要内容,如果未能解决你的问题,请参考以下文章

继承抽象类和接口

C#接口

C#中继承问题

c#核心基础--类的继承

类 与 继承

C#中的继承