简体   繁体   中英

MasterPage needs property from abstract generic class derived from System.Web.UI.Page

I have two classes that are derived from an abstract generic class, which is derived from System.Web.UI.Page. I have a System.Web.UI.MasterPage that may or may not be the master for either of my two derived page classes, or System.Web.UI.Page.

The problem is that the generic class has a property that I need to access in my MasterPage, but I don't know any elegant way to get it.

Here is an example...

Content types:

public abstract class Fruit
{
    public int ID { get; set; } //Just an identifier
}

public class Apple : Fruit {  }

public class Banana : Fruit {  }

Pages:

public abstract class FruitPage<T> : System.Web.UI.Page where T : Fruit
{
    public T MyFruit { get; set; } 
}

public class ApplePage : FruitPage<Apple> {  }

public class BananaPage : FruitPage<Banana> {  }

Master:

public partial class FoodMaster : System.Web.UI.MasterPage
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (this.Page is FruitPage<Fruit>) //I know this is wrong
        {
            if ((this.Page as FruitPage<Fruit>).MyFruit.ID <= 0) //This too
            { 
                /*
                    I want to get here (this.Page being an ApplePage or BananaPage).  

                    Basically...  if ID<=0 then it is a new (unsaved) "fruit", 
                        and I need to change some MasterPage GUI accordingly. 
                */
            }
        }
    }
}

Thank you!

"Any problem in computer science can be solved with another level of indirection."

public class FruitPage : System.Web.UI.Page {
   public Fruit MyInnerFruit { get; protected set; }
}

public abstract class FruitPage<T> : FruitPage where T : Fruit
{
   public T MyFruit { 
     get { return (T)MyInnerFruit; } 
     set { MyInnerFruit = value; } 
   }
}

public partial class FoodMaster : System.Web.UI.MasterPage {
    protected override void OnLoad(EventArgs e) {
       base.OnLoad(e);

       var fruitPage = this.Page as FruitPage;
       if (fruitPage != null && fruitPage.MyInnerFruit.ID <= 0) {
          ...
       }
    }
}

You could also shadow MyInnerFruit / MyFruit - but it's easier to understand without.

If you're using .NET 4, you can also use a covariant interface to basically allow casts from FruitPage<Apple> to FruitPage<Fruit> :

public interface IFruitPage<out T> where T : Fruit {
    public T MyFruit { get; }
}

public class FruitPage<T> : Page, IFruitPage<T> where T : Fruit {
    public T MyFruit { get; set; }
}

public class FoodMaster : MasterPage {
    protected override void OnLoad(EventArgs e) {
       base.OnLoad(e);

       var fruitPage = this.Page as IFruitPage<Fruit>;
       if (fruitPage != null && fruitPage.MyFruit.ID <= 0) {
          ...
       }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM