【问题标题】:how to call derived function using base class object如何使用基类对象调用派生函数
【发布时间】:2016-11-25 18:44:09
【问题描述】:
class Parent
{
    public int GetNo()
    {
        return 1;
    }
}

class Child : Parent
{        
    public Child()
    {

    }

    public int GetNo()
    {                       
        return 2;
    }
}

Parent p = new Child();
p.GetNo();

但它调用Base.GetNo()。我知道如果我在 base 中使用virutal,它会调用Child.GetNo() 但是我不能在Base中使用virutal,因为我必须从已经分布在DLL中的base派生我的类。所以我无法修改基类的现有功能。

任何建议都会被重视。 谢谢

【问题讨论】:

  • 你有更多关于你想使用它的上下文的信息吗?由于基类方法不打算被覆盖,也许通过组合而不是继承来解决它更好?

标签: c# inheritance


【解决方案1】:

你可以施放它:

((Child)p).GetNo();

if(p is Child)
    (p as Child).GetNo();

【讨论】:

  • +1,虽然我不喜欢在代码无法处理结果 null 时使用 as 进行强制转换。
【解决方案2】:

您可以通过显式强制转换来强制执行此操作,例如

((Child)p).GetNo();

或者你可以使用隐藏,例如

public new int GetNo()
{
  return 2;
}

虽然我认为后者只有在变量被键入到隐藏方法的类时才会被调用。

如果您确实需要正确覆盖某个方法并且它来自已编译的 DLL,请考虑与开发人员联系,看看他们是否可以使方法虚拟化(如果不是为什么),或者开源项目是否只是获取源代码自己编码和修改。

【讨论】:

  • 如果您“hiding it” by new 将应用相同的结果“p.GetNo();”将返回父代码而不是子代码。
  • @Jalal 这就是我所说的 - 我认为只有在将变量键入到隐藏方法的类时才会调用后者。我包括隐藏答案的完整性
【解决方案3】:

如果没有在方法上声明virtual,则将始终调用基本方法,因为您将变量声明为Parent。如果您不能将virtual 附加到基类,那么您只能将变量声明为Child,或者将其转换为Child 并调用您的GetNo 方法:

Child p = new Child();
p.GetNo();

或者:

Parent p = new Child();
((Child)p).GetNo();

【讨论】:

    【解决方案4】:

    我刚刚来到这里,所以我可以找到一个不使用强制转换的解决方案,但因为我在这里没有找到它。

    也许对某人有帮助。

    abstract class Parent
    {
        public int GetNo()
        {
            return GetNoImpl();
        }
    
        protected abstract int GetNoImpl();
    
    }
    
    class Child : Parent
    {        
        public Child()
        {
    
        }
    
        protected override int GetNoImpl();
        {                       
            return 2;
        }
    }
    
    Parent p = new Child();
    p.GetNo();
    

    注意:父类是抽象的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多