You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建子类列表并在常规循环中获取其Salary属性

如何正确获取子类的Salary属性

问题场景

你有带Rank属性的Worker基类,以及带Salary属性的Manager、Marketer子类,基类无Salary属性。需要创建仅包含这些子类的列表,并通过循环获取所有元素的Salary属性。

现有类定义

public class Worker
{
    public int Rank { get; set; }

    public Worker(int rank)
    {
        Rank = rank;
    }
}

public class Manager : Worker
{
    public Manager(int rank)
        : base(rank) { }

    public static int BaseSalary = 50000;
    public int Salary 
    {       
        get
        {
            return BaseSalary * Rank;
        }
    }
}

public class Marketer : Worker
{
    public Marketer(int rank)
        : base(rank) { }

    public static int BaseSalary = 20000;
    public int Salary
    {
        get
        {
            return BaseSalary * Rank;
        }
    }
}

出错的循环代码

List<Worker> List = new List<Worker>();
var Manager = new Manager(3);
List.Add(Manager);
var Marketer = new Marketer(2);
List.Add(Marketer);

for (int i = 0; i < List.Count; i++)
{
    Console.WriteLine(List[0].Salary);
}

问题原因

  1. 编译类型限制:List<Worker>中的元素编译时被视为Worker类型,而基类Worker没有Salary属性,直接访问会报错。
  2. 循环索引错误:循环中始终访问List[0],无法遍历所有元素。

解决方案

方案一:定义统一接口(推荐)

创建包含Salary属性的接口,让子类实现该接口,列表声明为接口类型即可直接访问Salary。

// 定义接口
public interface IPaidWorker
{
    int Salary { get; }
}

// 修改子类实现接口
public class Worker
{
    public int Rank { get; set; }

    public Worker(int rank)
    {
        Rank = rank;
    }
}

public class Manager : Worker, IPaidWorker
{
    public Manager(int rank) : base(rank) { }

    public static int BaseSalary = 50000;
    public int Salary => BaseSalary * Rank;
}

public class Marketer : Worker, IPaidWorker
{
    public Marketer(int rank) : base(rank) { }

    public static int BaseSalary = 20000;
    public int Salary => BaseSalary * Rank;
}

// 修正后的列表和循环代码
List<IPaidWorker> paidWorkers = new List<IPaidWorker>();
paidWorkers.Add(new Manager(3));
paidWorkers.Add(new Marketer(2));

for (int i = 0; i < paidWorkers.Count; i++)
{
    Console.WriteLine(paidWorkers[i].Salary);
}

方案二:使用抽象类

如果Worker不需要实例化,可改为抽象类并定义抽象Salary属性,让子类实现。

// 修改Worker为抽象类
public abstract class Worker
{
    public int Rank { get; set; }

    public Worker(int rank)
    {
        Rank = rank;
    }

    // 定义抽象Salary属性
    public abstract int Salary { get; }
}

// 子类实现Salary属性
public class Manager : Worker
{
    public Manager(int rank) : base(rank) { }

    public static int BaseSalary = 50000;
    public override int Salary => BaseSalary * Rank;
}

public class Marketer : Worker
{
    public Marketer(int rank) : base(rank) { }

    public static int BaseSalary = 20000;
    public override int Salary => BaseSalary * Rank;
}

// 列表和循环代码
List<Worker> workers = new List<Worker>();
workers.Add(new Manager(3));
workers.Add(new Marketer(2));

for (int i = 0; i < workers.Count; i++)
{
    Console.WriteLine(workers[i].Salary);
}

方案三:类型转换(不推荐)

若不想修改类结构,可在循环中判断并转换类型,但这种方式扩展性差,破坏面向对象封装性。

List<Worker> workers = new List<Worker>();
workers.Add(new Manager(3));
workers.Add(new Marketer(2));

for (int i = 0; i < workers.Count; i++)
{
    if (workers[i] is Manager manager)
    {
        Console.WriteLine(manager.Salary);
    }
    else if (workers[i] is Marketer marketer)
    {
        Console.WriteLine(marketer.Salary);
    }
}

关键修改点总结

  • 确保列表元素的编译类型包含Salary属性(通过接口或抽象类实现)
  • 循环中使用i作为索引访问对应元素,而非固定的0

内容的提问来源于stack exchange,提问作者Battlecruiser Games

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:32:28