【问题标题】:Call parent method from child class c#从子类c#调用父方法
【发布时间】:2012-12-06 12:25:31
【问题描述】:

这是一个与我之前看到的答案略有不同的问题,或者我没有得到它。我有一个父类,其方法名为 MyMethod() 和变量 public Int32 CurrentRow;

public void MyMethod()
{    
     this.UpdateProgressBar();    
}

在父级中,我创建了一个 ChildClass 的新实例

Boolean loadData = true;
if (loadData) 
{    
     ChildClass childClass = new ChildClass();    
     childClass.LoadData(this.Datatable);    
}

在子类LoadData() 方法中,我希望能够设置父类的CurrentRow 变量并调用MyMethod() 函数。

我该怎么做?

【问题讨论】:

  • 如果您尝试与表单/窗口等通信数据(当您正在加载一些数据并更新进度条)我强烈建议您遵循一些 MVC 或 MVVM 方法
  • MyMethod 是私有的。您不能从ChildClass 调用它。
  • 孩子和父母之间有什么样的关联?遗产?聚合?
  • @DanielHilgarth 好地方,我错过了。 OP,您需要将 private 更改为 protected 以允许从子类中使用该方法。
  • @Daniel 抱歉,我已将其编辑为公开

标签: c# .net


【解决方案1】:

要访问父类的属性和方法,请使用base 关键字。所以在你的子类LoadData() 方法中你会这样做:

public class Child : Parent 
{
    public void LoadData() 
    {
        base.MyMethod(); // call method of parent class
        base.CurrentRow = 1; // set property of parent class
        // other stuff...
    }
}

请注意,您还必须将父类 MyMethod() 的访问修饰符更改为至少 protected 才能让子类访问它。

【讨论】:

  • 来自 OP:In the parent I create a new instance of ChildClass - 这对我来说意味着组合,而不是继承。
  • 我认为你可能是对的。不过我会把它留在这里以防万一。
  • 这正是我想要的,尽管这不是他的问题:)。问题标题令人困惑...
  • In the parent I create a new instance of ChildClass - 这对我来说意味着潜在的递归。我喜欢。海龟一路向下。
  • 我同意埃米尔的观点。这段代码对我来说会导致 StackOverflow。
【解决方案2】:

找到了解决办法。

在父类中我声明了一个 ChildClass() 的新实例,然后将该类中的事件处理程序绑定到父类中的本地方法

在子类中我添加了一个公共事件处理程序:

public EventHandler UpdateProgress;

在父类中创建这个子类的新实例,然后将本地父事件绑定到子类中的public eventhandler

ChildClass child = new ChildClass();
child.UpdateProgress += this.MyMethod;
child.LoadData(this.MyDataTable);

然后在我可以调用的子类的LoadData()中

private LoadData() {
    this.OnMyMethod();
}

OnMyMethod 在哪里:

public void OnMyMethod()
{
     // has the event handler been assigned?
     if (this.UpdateProgress!= null)
     {
         // raise the event
         this.UpdateProgress(this, new EventArgs());
     }
}

这会在父类中运行事件

【讨论】:

  • 取决于您的意图,使用 Action 委托可能比 EventHandler 更好。出于一个原因,您不必担心删除事件分配,即:child.UpdateProgress -= this.MyMethod;
【解决方案3】:

跟进 suhendri 对 Rory McCrossan 回答的评论。这是一个动作委托示例:

在孩子中添加:

public Action UpdateProgress;  // In place of event handler declaration
                               // declare an Action delegate
.
.
.
private LoadData() {
    this.UpdateProgress();    // call to Action delegate - MyMethod in
                              // parent
}

在父级中添加:

// The 3 lines in the parent becomes:
ChildClass child = new ChildClass();
child.UpdateProgress = this.MyMethod;  // assigns MyMethod to child delegate

【讨论】:

    【解决方案4】:

    一种方法是将ParentClass 的实例传递给ChildClass 构造

    public ChildClass
    {
        private ParentClass parent;
    
        public ChildClass(ParentClass parent)
        {
            this.parent = parent;
        }
    
        public void LoadData(DateTable dt)
        {
           // do something
           parent.CurrentRow++; // or whatever.
           parent.UpdateProgressBar(); // Call the method
        }
    }
    

    确保在父级内部构造ChildClass 时传递对this 的引用:

    if(loadData){
    
         ChildClass childClass = new ChildClass(this); // here
    
         childClass.LoadData(this.Datatable);
    
    }
    

    警告:这可能不是组织课程的最佳方式,但它直接回答了您的问题。

    编辑:在 cmets 中,您提到超过 1 个父类想要使用 ChildClass。这可以通过引入接口来实现,例如:

    public interface IParentClass
    {
        void UpdateProgressBar();
        int CurrentRow{get; set;}
    }
    

    现在,确保在两个(全部?)父类上实现该接口并将子类更改为:

    public ChildClass
    {
        private IParentClass parent;
    
        public ChildClass(IParentClass parent)
        {
            this.parent = parent;
        }
    
        public void LoadData(DateTable dt)
        {
           // do something
           parent.CurrentRow++; // or whatever.
           parent.UpdateProgressBar(); // Call the method
        }
    }
    

    现在任何实现IParentClass 的东西都可以构造ChildClass 的实例并将this 传递给它的构造函数。

    【讨论】:

    • @CR41G14 - “动态”到底是什么意思?关键字dynamic 或“任何类不只是ParentClass”?
    • 我必须传递一个构造函数吗?我可以“检测”调用它的父类吗?因为我可能希望 parentClass2 调用这个类。对不起,如果我没有意义,但这是一个继承的项目
    • @CR41G14 - 不,它必须是 ParentClass 或任何继承它的东西。如果两个类都需要构造一个ChildClass,那么你可以让子类在构造函数中使用一个接口。我会更新一些细节的答案。
    猜你喜欢
    • 2016-02-14
    • 2012-01-21
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    相关资源
    最近更新 更多