如何调用Creator Method's

时间:2011-09-23 11:07:11

标签: c# winforms syntax

如果我们有一个班级

public class A
{
    public void resetValues()
    {
        //DoSomething
    }

    B b = new B();
}
public class B
{
    public B()
    {

    }

    void doSomething()
    {
        //Is there a way here to call A(the Creator) method resetValues();
        //Like Creator.resetValues();
    }
}

有没有办法调用Creator方法,就像在这个示例类A方法中一样。 当我使用表单显示另一个表单时,这是非常需要的: 来自FormA

FormB frmB = new FormB();
frmB.Show();
this.hide();

我应onFormClose FormB的事件再次显示FormA

修改 首先,我认为通过Ref解析A作为对象,但是稍后将参考文献作为字段存储我发现这是不可能的!

首先我认为可能使用反射我们可以识别和调用创建器方法,但我认为我错配了一些 OOP设计模式

3 个答案:

答案 0 :(得分:3)

唯一的方法是在调用构造函数时传入“creator”:

 B b = new B(this);

当然,这意味着B需要一个具有相应参数类型的构造函数,该构造函数应该与它的创建者需要的任何内容相匹配。

编辑:正如评论中所述,它并不需要在构造时完成 - 它可能是一个属性:

 B b = new B();
 b.Creator = this;

虽然它们基本上是相同的。

老实说,我建议这通常是一个坏主意。它引入了两个类之间相当紧密的耦合。 B可能更好地发布创建者可以订阅的事件,以便在B上处理适当的状态更改等。

答案 1 :(得分:1)

您可以简单地使用Action代替Func<bool>,返回bool允许传回指示操作是否已成功执行的状态。

class B
{ 
  private Func<bool> executeExternal;

  public B(Func<bool> executeExternal) 
  {
       this.executeExternal= executeExternal;

       // here is resetValues() will be executed in case of B class
       bool isDoneSuccessfully = this.executeExternal();
  } 
}

public class A 
{     
  public void resetValues()     
  {         
     //DoSomething     
  }      

  // basically we injecting a delegate
  B b = new B(() => { this.resetValues(); return true; } ); 

} 

答案 2 :(得分:1)

@Jon Skeetanswer之后,B类最好在发生事件时发出事件,而A类最好使用该事件。

通过这种方式,类B不依赖于类A.您可以将类B重用于类A以外的类而不修改类B的内部。从维护POV开始,这是更好的选择。

您可以按照以下方式进行设置:

public class A
{
    B b = new B();

    public A()
    {
       b.SomethingHappened += SomethingHappenedHandler; 
    }
    public void resetValues()
    {
        //DoSomething
    }
    public void SomethingHappenedHandler(object sender, EventArgs args)
    {
        resetValues();
    }

}

public class B
{
    public event EventHandler SomethingHappened;
    public B()
    {

    }

    void doSomething()
    {
        var ev = SomethingHappened;
        if(ev != null)
        {
            ev(this, EventArgs.Empty);
        }
    }
}