2014-03-24 74 views
1

请原谅我对此问题缺乏培训/理解。嵌套类无法访问“父”变量

我有一个复杂的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作为数量,因为它是一个移动商店,它们比原始商店中的向上/向下箭头更容易。这一切都非常复杂 - 一个商业商店包和两个不同的承包商已经将它与其他预订系统联系起来,我必须理解这一切并使其工作。希望我更了解.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; 
+4

你不需要创建一个* new *实例 - 你大概已经*有*一些实例。目前还不清楚究竟发生了什么或者你想要实现什么,但是我可能会从删除嵌套开始 - 这可能会导致更多的混乱,而不是价值。 –

+0

你可以创建它自己的属性_EventSelected用于嵌套类并将其设置在外部_EventSelected属性的setter中? – lavrik

+0

是的,这是一个涉及到的系统,我在.NET上是一个新手,我甚至很难解释。我会尽力将其分解出来,看看我能得到什么。谢谢。 – Deverill

回答

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 
     } 
    } 
} 
+0

我可以看到现在开展这项工作的路径。谢谢!这只是一个思维问题,而不是我习惯的线性C编程。 – Deverill

1

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

说一种不同的方式:尽可能地尝试并依赖于dependency inversion principle。避免在你正在工作的课程之外引用某些东西。