嵌套类无法访问“父”变量

时间:2014-03-24 16:01:30

标签: c# asp.net inheritance

请原谅我在这个问题上缺乏培训/理解。

我有一个复杂的asp.net / c#包,它是一个高度定制的电子商务商店。为了便于理解,我会尝试简化我的情况。

我有一个自定义控件,并且该控件的定义如下:

public partial class ConLib_Custom_ProductDialog : System.Web.UI.UserControl

并且在该课程中是这样的:

private class QtyBoxTemplate : System.Web.UI.ITemplate

在该类中,我使用:

解决bool _EventSelected的值
  if (_EventSelected)

在外部类中定义为:

public static bool _EventSelected;

我不想要静电,因为它可能导致"碰撞"网站用户之间,因为静态变量是应用程序的全局变量。我们之前遇到过这个问题,我可以直接取消静态关键字,但它确实有效。

在这种情况下,如果我删除静态,我会得到一个我有点理解的错误:

  

无法通过嵌套类型ConLib_Custom_ProductDialog.QtyBoxTemplate

访问外部类型ConLib_Custom_ProductDialog的非静态成员

似乎自QtyBoxTemplate嵌套后,它无法访问父类中的bool变量。

我发现了另一个类似的问题here,该问题尽可能多,并且有三种解决方案:

1. Make the (method) variable static.
2. Use inheritance instead of nested classes.
3. Create an instance of the outer class.

第一个是问题,因为它是变量而不是原始帖子中的方法,但它是我迄今为止工作的方式并没有意识到。

至于第二种,我不认为继承是一种选择,因为QtyBoxTemplate已经继承了System ITemplate。

最后,创建一个外部类的实例只是为了访问一个变量并且我缺乏经验我甚至不知道它是如何工作的 - 我什么时候才能创建实例,我是否必须通过它因为它是一个自定义控件,我甚至不知道是否可以这样做,因为它还没有被它所在的父页面实例化?

再次,对于向大多数人提出可能是基本问题的问题表示道歉,但这是我无法得到的一部分。我意识到代码有点复杂,希望我能够很好地理解它的本质。非常感谢帮助。

更新:尝试添加更多信息。我有一个数据网格,每行都是一个产品。在该网格行中,我有一个他们想要购买的数量的下拉列表,从1到10.但是,如果他们在旅行中选择了座位并且已经选择了一个日期/时间,他们就无法改变数量或它会搞乱预订系统所以我检查_EventSelected以禁用数量DDL,如果是这种情况。

我们使用DDL作为数量,因为它是一个移动商店,它们比原始商店中的向上/向下箭头更容易。这一切都非常复杂 - 商业商店套餐和2个不同的承包商已经开展工作,将其与另一个预订系统联系起来,我必须全面了解并使其发挥作用。希望我知道更多的.NET / C#!感谢您通过这种解释来试图提供帮助。

这是我的QtyBoxTemplate课程:

 private class QtyBoxTemplate : System.Web.UI.ITemplate
    {            
        private DataControlRowType templateType;
        private string columnName;

        public QtyBoxTemplate(DataControlRowType type, string colname)
        {
            templateType = type;
            columnName = colname;
        }

        public void InstantiateIn(System.Web.UI.Control container)
        {
            Literal lc = new Literal();

            switch (templateType)
            {
                case DataControlRowType.Header:
                    // build the header for this column
                    //lc.Text = "<b>" + BreakCamelCase(columnName) + "</b>";
                    lc.Text = "<b>" + columnName + "</b>";
                    container.Controls.Add(lc);
                    break;
                case DataControlRowType.DataRow:
                    //--plugables: Now we need a drop down list instead of a quantity box
                    DropDownList ddList = new DropDownList();
                    ddList.Items.Add(new ListItem("0", "0"));
                    ddList.Items.Add(new ListItem("1", "1"));
                    ddList.Items.Add(new ListItem("2", "2"));
                    ddList.Items.Add(new ListItem("3", "3"));
                    ddList.Items.Add(new ListItem("4", "4"));
                    ddList.Items.Add(new ListItem("5", "5"));
                    ddList.Items.Add(new ListItem("6", "6"));
                    ddList.Items.Add(new ListItem("7", "7"));
                    ddList.Items.Add(new ListItem("8", "8"));
                    ddList.Items.Add(new ListItem("9", "9"));
                    ddList.Items.Add(new ListItem("10", "10"));
                    ddList.Items.Add(new ListItem("20", "20"));
                    ddList.Items.Add(new ListItem("40", "40"));
                    ddList.ID = "Quantity";
                    ddList.Font.Size = FontUnit.Parse("18px");
                    if (_EventSelected)
                        ddList.Enabled = false;
                    container.Controls.Add(ddList);
                    break;
                default:
                    break;
            }
        }
    }

它生活在一个有几十种方法,类等的类中...太多了,不能在这里发布(2500多行),但它开始像:

public partial class ConLib_Custom_BuyTourProductDialogGalaxy : System.Web.UI.UserControl
{ 
    #region class variables

    int _ProductId = 0;
    Product _Product = null;
    List<int> _SelectedKitProducts = null;
    ProductVariantManager _VariantManager;
    PersistentCollection<ProductVariant> _AvailableVariants;
    DataTable _DataTable;
    ProductOptionCollection _ProdOptions;

    private bool _ShowAvailableSeats = true;
    public DateTime _SelectedDate;
    public int _EventTypeId;
    public bool _CollectRosterData;
    public Envelope _Inventory;
    private string _DTFormat = "yyyy-MM-dd HH:mm:ss";

    public bool _EventSelected;

2 个答案:

答案 0 :(得分:1)

您无法从嵌套类中访问类的实例成员。这没有任何意义,因为嵌套类没有对外部类的特定实例的引用,除非您将其传递给它。您可以在构造嵌套类的实例时传递外部类的实例,但是如果没有更多代码,我很难知道此解决方案是否适合您。

用不同的方式说:尽可能地尝试并依赖dependency inversion principle。避免引用您正在处理的课程之外的事情。

答案 1 :(得分:1)

由于QtyBoxTemplate是私有的,因此只能在ConLib_Custom_ProductDialog类内创建 我建议你将ConLib_Custom_ProductDialog作为参数添加到QtyBoxTemplate构造函数中,并将其设置为局部变量。然后,您可以使用该引用访问_EventSelected

public partial class ConLib_Custom_ProductDialog : System.Web.UI.UserControl
{
    public bool _EventSelected;

    public void SomeFunctionThatCreatesQtyBoxTemplate()
    {
        var q = new QtyBoxTemplate(this); //Include reference to itself
        q.SetEventSelected();
    }

    private class QtyBoxTemplate : System.Web.UI.ITemplate
    {
        private ConLib_Custom_ProductDialog _ccp;

        public QtyBoxTemplate(ConLib_Custom_ProductDialog ccp)
        {
            _ccp = ccp;
        }

        public void SetEventSelected()
        {
            _ccp._EventSelected = true; //Access to "parent" EventSelected 
        }
    }
}