【问题标题】:C# / accessing methods of sub-classes in a list when accessing through foreachC#/通过foreach访问时访问列表中子类的方法
【发布时间】:2014-05-29 08:09:42
【问题描述】:

试图了解当列表被键入为超类时如何访问子类的方法。这应该是基本的多态性,但我很困惑。

public class super
{ 
  public Boolean isSuper()
  {
    return true;
  }
}

public class sub : super
{ 
  public Boolean isSuper()
  {
    return false;
  }
}

现在我列出这些对象

List <super> myList = new List<super>();
myList.Add(new super());
myList.Add(new sub());

现在我尝试让列表中的每个对象查询自己,看看它是超类还是子类

foreach(super objInList in myList)
{
  if(objInList.isSuper())
    Debug.Print("Super");
  else
    Debug.Print("Sub");
}

所以发生的情况是,由于每个对象都被强制转换为超类,它使用 isSuper() 的超类方法,并且始终作为超类响应。

我想访问子类的 isSuper() 而不必在循环的每次迭代中都使用 instanceof。显然,如果您可以查询对象以查看它是超级对象还是子对象,那么 O/S 中的某些内容就知道对象的类型。为什么要通过一个猜谜游戏来检查每一种可能性?为什么不让它深入到适当的子类并执行适当的方法呢?有没有办法实现这个目标?

【问题讨论】:

  • 与 Java 不同,您必须在 C# 中显式声明成员为虚拟成员并显式覆盖它们(使用 override 关键字)。
  • 旁注:如果您打算将 Java 示例复制/粘贴为 C#(您是根据编码约定进行的),那么检查 Java 与 C# 的差异可能是个好主意......就像数字类型或默认虚拟行为。
  • 还有助于注意编译器警告,尤其是当您的代码无法按预期工作时。在这种情况下,它会警告您隐藏 isSuper 方法。

标签: c# list polymorphism subclass superclass


【解决方案1】:

您必须在 sub 类中使用 override super 类属性才能获得所需的行为。

相应地更改您的类定义:

public class super
{ 
  public virtual Boolean isSuper()
  {
    return true;
  }
}

public class sub : super
{ 
  public override Boolean isSuper()
  {
    return false;
  }
}

【讨论】:

  • 我什至建议让代码更符合 C# 的习惯:public virtual bool IsBase { get { return true; } }
  • 哇...就这么简单?那为什么编译器允许它编译呢?没有明确的覆盖是没有意义的。
  • @user3533030 因为hiding/shadowing 不是错误,而是警告(考虑将所有项目的“将警告视为错误”...)
  • @user3533030 - 在某些情况下确实有意义,并且编译器确实发出了警告,您应该覆盖该方法,或者用new 标记它以使其隐藏(但不覆盖)基本方法:public class Sub : Super { new public bool IsSuper() { ... } }
  • @user3533030 C# 经过精心设计,可以避免脆弱的基类问题。这就是不产生错误的原因。
猜你喜欢
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 2016-01-16
  • 2021-05-27
  • 2015-03-16
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
相关资源
最近更新 更多