【问题标题】:Accessing subclass members when using polymorphism and List使用多态和 List 时访问子类成员
【发布时间】:2014-05-04 07:44:18
【问题描述】:

我有 3 个课程:"ChemDataChemicals(Super)"、"ChemDataAlcohol(Sub)、"ChemDataAcidBase"(Sub) 和包含所有对象的通用列表(类型:ChemDataChemicals)。我的超类包含我的大部分字段,但子类都包含一个额外的字段 - pH(十进制)和 VolPercentage(十进制)。

下面的代码应该在 ListBox 中添加 item.Name 和 item.VolPercentage/item.pH,但我无法访问我的子类中的字段。

 foreach (ChemDataChemicals item in tmpChemDataChemicalsList)
        {
            if (item is ChemDataAlcohol)
            {

                listBox1.Items.Add(String.Format("{0}: {1}%", item.Name, (ChemDataAlcohol)item.VolPercentage));
            }

            else if (item is ChemDataAcidBase)
            {
                listBox1.Items.Add(String.Format("{0}: {1}M", item.Name, item.pH));
            }
        }

我尝试了一些强制转换,但似乎没有任何效果。 (Windows 窗体 - C#) 谢谢,

【问题讨论】:

  • IMO 你应该重新标记“非多态性”。哈哈。您应该在基类中添加一个抽象成员,例如“ToShortDescription()”,并在派生类中覆盖它。摆脱“项目是 XYZ”...
  • 嗨阿德里亚诺。我对编程很陌生,刚刚开始了解 OOP。我认为,调用 obj 时使用超类引用的能力是多态性。换句话说,由于继承, chemDataAcidBase(sub) obj 是 chemDataChemical(super) obj。我误解了这个概念吗?谢谢

标签: c# list inheritance polymorphism


【解决方案1】:

改变

(ChemDataAlcohol)item.VolPercentage

((ChemDataAlcohol)item).VolPercentage

另外,我建议你使用as关键字:

(item as ChemDataAlcohol).VolPercentage

因为第一种方法,如果转换失败,抛出异常。使用as 方法,它会产生null,可以检查它,并且避免抛出异常

【讨论】:

  • @JoergenMathiesen 我很高兴它有帮助。
【解决方案2】:

如果您遇到更普遍的问题,还有另一种方法可以访问列表中一个子类的项目,那就是在任何集合上使用 OfType 扩展方法。

private class Chemical
{
    public string formula;
}
private class ChemDataAlcohol : Chemical
{
    public string Name;
}
private class ChemDataAcidBase : Chemical
{
    public decimal pH; // at 1.0 M
}

public static void Test()
{
    Chemical[] chemicals = {
        new Chemical { formula = "H2O" },
        new ChemDataAcidBase { formula = "H2SO4", pH = 0 },
        new ChemDataAlcohol { formula = "C2H6O", Name="ethanol" },
        new Chemical { formula = "CO2" },
        new ChemDataAcidBase { formula = "CH3COOH", pH = 2.4M },
                            };

    List<ChemDataAlcohol> alcohols = chemicals.OfType<ChemDataAlcohol>().ToList();
    foreach (ChemDataAlcohol alcohol in alcohols) { string name = alcohol.Name; }

    List<ChemDataAcidBase> acids = chemicals.OfType<ChemDataAcidBase>().ToList();
    foreach (ChemDataAcidBase acid in acids) { decimal pH = acid.pH; }
}

缺点:并非在所有情况下都适用,并且需要进行一定程度的调整以适应您的问题。

【讨论】:

    猜你喜欢
    • 2018-10-05
    • 2014-08-07
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多