在设计中,设计师通常不会随便设计“相互循环依赖”的对象。如果head.ascx是个通用服务组件,可能用在各种宿主ascx(以及aspx)中,那么它就不想当然地去纠结什么P1、P2、......Pn变化。它通常会定义一个public int sid{get;set;}属性,然后让宿主把参数传给它,就好像TextBox控件它让你把Text属性传给它一样。而如果这个值是很偶然才会用到的,也许head.ascx会重新解释这个机制,说成是“事件”。例如public event MyEventHandler RequireSid;然后在自定义的委托类型MyEventHandler中的自定义参数(例如第二个参数)中有一个int类型的属性,用户宿主程序响应这个事件时给它赋值。于是head.ascx可能就写if(this.RequireSid !=null)
{
    var e = new MyEventArgument();
    this.RequireSid(this, e);
    int result = e.RetData;
    .......
}

解决方案 »

  1.   

    有时候,可能会把所有宿主通用的某种interface作为参数,传给head.ascx。例如定义一个属性public MyInterface Parent{get;set;}
    这就把P1、P2、......等等宿主所具有的相同的父类接口抽象出来,以达到比一个简单的sid属性更高级更复杂一点的目的。这里所有的原则就是,假设你知道 P1、P2、......以及其他宿主程序都可能把head.ascx当作通用的服务组件,那么就要谨慎地维系这种通用性。不要让head.ascx再循环依赖于宿主。如果你嫌麻烦,觉得无所谓这样把握原则,那么你可能很快就弄出一个非常诡异、非常难以拆解扩展、变本加厉提高耦合度的head.ascx出来了,想要扩展通用head.ascx的想法会迅速碰到“硬伤”。反而更加麻烦。这是面向对象的一个重要原则。
      

  2.   

    head.ascx 中不应该依赖于aspx中的值的,要不它怎么被用到其它页面。
      

  3.   

    head.ascx  添加一个公共属性sid 
    以便外部访问